create vendor folder & add freeRTOS 7.3 from lpcopen
This commit is contained in:
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
This includes un-modified version 7.3.0 of the core FreeRTOS files, with the
|
||||||
|
demos removed from the source tree to save space.
|
||||||
|
|
||||||
|
The original files can be downloaded at:
|
||||||
|
http://www.freertos.org
|
||||||
|
|
||||||
|
Information on FreeRTOS licensing is located in the freertos/license.txt file
|
||||||
|
or go to the website.
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
The following files have been modified to add support for a custom tick. This is
|
||||||
|
needed for the dual-core M0 FreeRTOS tick function (no sysTick on the LPC4350 M0
|
||||||
|
core).
|
||||||
|
software\freertos\freertos\Source\portable\GCC\ARM_CM0\port.c
|
||||||
|
software\freertos\freertos\Source\portable\IAR\ARM_CM0\port.c
|
||||||
|
software\freertos\freertos\Source\portable\RVDS\ARM_CM0\port_m0.c
|
||||||
|
software\freertos\freertos\Source\portable\RVDS\ARM_CM0\portmacro.h
|
||||||
+440
@@ -0,0 +1,440 @@
|
|||||||
|
The FreeRTOS.org source code is licensed by the *modified* GNU General Public
|
||||||
|
License (GPL), text provided below. A special exception to the GPL is
|
||||||
|
included to allow you to distribute a combined work that includes FreeRTOS
|
||||||
|
without being obliged to provide the source code for any proprietary
|
||||||
|
components. See the licensing section of http://www.FreeRTOS.org for full
|
||||||
|
details. The exception text is also included at the bottom of this file.
|
||||||
|
|
||||||
|
The FreeRTOS download also includes demo application source code, some of
|
||||||
|
which is provided by third parties AND IS LICENSED SEPARATELY FROM FREERTOS.
|
||||||
|
|
||||||
|
For the avoidance of any doubt refer to the comment included at the top
|
||||||
|
of each source and header file for license and copyright information.
|
||||||
|
|
||||||
|
This is a list of files for which Real Time Engineers Ltd are not the
|
||||||
|
copyright owner and are NOT COVERED BY THE GPL.
|
||||||
|
|
||||||
|
|
||||||
|
1) Various header files provided by silicon manufacturers and tool vendors
|
||||||
|
that define processor specific memory addresses and utility macros.
|
||||||
|
Permission has been granted by the various copyright holders for these
|
||||||
|
files to be included in the FreeRTOS download. Users must ensure license
|
||||||
|
conditions are adhered to for any use other than compilation of the
|
||||||
|
FreeRTOS demo applications.
|
||||||
|
|
||||||
|
2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
|
||||||
|
Users must ensure the open source license conditions stated at the top
|
||||||
|
of each uIP source file is understood and adhered to.
|
||||||
|
|
||||||
|
3) The lwIP TCP/IP stack the copyright of which is held by the Swedish
|
||||||
|
Institute of Computer Science. Users must ensure the open source license
|
||||||
|
conditions stated at the top of each lwIP source file is understood and
|
||||||
|
adhered to.
|
||||||
|
|
||||||
|
4) Various peripheral driver source files and binaries provided by silicon
|
||||||
|
manufacturers and tool vendors. Permission has been granted by the
|
||||||
|
various copyright holders for these files to be included in the FreeRTOS
|
||||||
|
download. Users must ensure license conditions are adhered to for any
|
||||||
|
use other than compilation of the FreeRTOS demo applications.
|
||||||
|
|
||||||
|
5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code,
|
||||||
|
which are slightly modified versions of code provided by and copyright to
|
||||||
|
Tern Inc.
|
||||||
|
|
||||||
|
Errors and omissions should be reported to Richard Barry, contact details for
|
||||||
|
whom can be obtained from http://www.FreeRTOS.org.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The GPL license text follows.
|
||||||
|
|
||||||
|
A special exception to the GPL is included to allow you to distribute a
|
||||||
|
combined work that includes FreeRTOS without being obliged to provide
|
||||||
|
the source code for any proprietary components. See the licensing section
|
||||||
|
of http://www.FreeRTOS.org for full details. The exception text is also
|
||||||
|
included at the bottom of this file.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License** as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The FreeRTOS GPL Exception Text:
|
||||||
|
|
||||||
|
Any FreeRTOS source code, whether modified or in it's original release form,
|
||||||
|
or whether in whole or in part, can only be distributed by you under the terms
|
||||||
|
of the GNU General Public License plus this exception. An independent module is
|
||||||
|
a module which is not derived from or based on FreeRTOS.
|
||||||
|
|
||||||
|
Clause 1:
|
||||||
|
|
||||||
|
Linking FreeRTOS statically or dynamically with other modules is making a
|
||||||
|
combined work based on FreeRTOS. Thus, the terms and conditions of the GNU
|
||||||
|
General Public License cover the whole combination.
|
||||||
|
|
||||||
|
As a special exception, the copyright holder of FreeRTOS gives you permission
|
||||||
|
to link FreeRTOS with independent modules that communicate with FreeRTOS
|
||||||
|
solely through the FreeRTOS API interface, regardless of the license terms of
|
||||||
|
these independent modules, and to copy and distribute the resulting combined
|
||||||
|
work under terms of your choice, provided that
|
||||||
|
|
||||||
|
+ Every copy of the combined work is accompanied by a written statement that
|
||||||
|
details to the recipient the version of FreeRTOS used and an offer by yourself
|
||||||
|
to provide the FreeRTOS source code (including any modifications you may have
|
||||||
|
made) should the recipient request it.
|
||||||
|
|
||||||
|
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
|
||||||
|
|
||||||
|
+ The independent modules add significant and primary functionality to FreeRTOS
|
||||||
|
and do not merely extend the existing functionality already present in FreeRTOS.
|
||||||
|
|
||||||
|
Clause 2:
|
||||||
|
|
||||||
|
FreeRTOS may not be used for any competitive or comparative purpose, including the
|
||||||
|
publication of any form of run time or compile time metric, without the express
|
||||||
|
permission of Real Time Engineers Ltd. (this is the norm within the industry and
|
||||||
|
is intended to ensure information accuracy).
|
||||||
+389
@@ -0,0 +1,389 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "croutine.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
|
* than file scope.
|
||||||
|
*/
|
||||||
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
|
#define static
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
|
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
|
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
|
static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
|
static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
||||||
|
static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
|
static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
|
/* Other file private variables. --------------------------------*/
|
||||||
|
corCRCB * pxCurrentCoRoutine = NULL;
|
||||||
|
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
|
||||||
|
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
|
/* The initial state of the co-routine when it is created. */
|
||||||
|
#define corINITIAL_STATE ( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
|
* for the priority. It is inserted at the end of the list.
|
||||||
|
*
|
||||||
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
|
* used from within an ISR.
|
||||||
|
*/
|
||||||
|
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||||
|
{ \
|
||||||
|
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||||
|
{ \
|
||||||
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
|
} \
|
||||||
|
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
|
* automatically upon the creation of the first co-routine.
|
||||||
|
*/
|
||||||
|
static void prvInitialiseCoRoutineLists( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
|
* the ready lists (there is no mutual exclusion). Instead they are placed in
|
||||||
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
|
* list by the co-routine scheduler.
|
||||||
|
*/
|
||||||
|
static void prvCheckPendingReadyList( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
|
* see if any require waking.
|
||||||
|
*
|
||||||
|
* Co-routines are stored in the queue in the order of their wake time -
|
||||||
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
|
* we need not look any further down the list.
|
||||||
|
*/
|
||||||
|
static void prvCheckDelayedList( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
signed portBASE_TYPE xReturn;
|
||||||
|
corCRCB *pxCoRoutine;
|
||||||
|
|
||||||
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
|
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
|
||||||
|
if( pxCoRoutine )
|
||||||
|
{
|
||||||
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
|
be created and the co-routine data structures need initialising. */
|
||||||
|
if( pxCurrentCoRoutine == NULL )
|
||||||
|
{
|
||||||
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
|
prvInitialiseCoRoutineLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the priority is within limits. */
|
||||||
|
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
|
||||||
|
{
|
||||||
|
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the co-routine control block from the function parameters. */
|
||||||
|
pxCoRoutine->uxState = corINITIAL_STATE;
|
||||||
|
pxCoRoutine->uxPriority = uxPriority;
|
||||||
|
pxCoRoutine->uxIndex = uxIndex;
|
||||||
|
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
||||||
|
|
||||||
|
/* Initialise all the other co-routine control block parameters. */
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
|
/* Set the co-routine control block as a link back from the xListItem.
|
||||||
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
|
in a list. */
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
|
/* Event lists are always in priority order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
|
||||||
|
|
||||||
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
|
list at the correct priority. */
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
|
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
|
||||||
|
{
|
||||||
|
portTickType xTimeToWake;
|
||||||
|
|
||||||
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
|
not a problem. */
|
||||||
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
|
/* We must remove ourselves from the ready list before adding
|
||||||
|
ourselves to the blocked list as the same list item is used for
|
||||||
|
both lists. */
|
||||||
|
uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* The list item will be inserted in wake time order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||||
|
|
||||||
|
if( xTimeToWake < xCoRoutineTickCount )
|
||||||
|
{
|
||||||
|
/* Wake time has overflowed. Place this item in the
|
||||||
|
overflow list. */
|
||||||
|
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The wake time has not overflowed, so we can use the
|
||||||
|
current block list. */
|
||||||
|
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pxEventList )
|
||||||
|
{
|
||||||
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
|
function must be called with interrupts disabled. */
|
||||||
|
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckPendingReadyList( void )
|
||||||
|
{
|
||||||
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
|
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
|
the ready lists itself. */
|
||||||
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
corCRCB *pxUnblockedCRCB;
|
||||||
|
|
||||||
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
||||||
|
uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckDelayedList( void )
|
||||||
|
{
|
||||||
|
corCRCB *pxCRCB;
|
||||||
|
|
||||||
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
|
while( xPassedTicks )
|
||||||
|
{
|
||||||
|
xCoRoutineTickCount++;
|
||||||
|
xPassedTicks--;
|
||||||
|
|
||||||
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
|
if( xCoRoutineTickCount == 0 )
|
||||||
|
{
|
||||||
|
xList * pxTemp;
|
||||||
|
|
||||||
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if this tick has made a timeout expire. */
|
||||||
|
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||||
|
|
||||||
|
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||||
|
{
|
||||||
|
/* Timeout not yet expired. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* The event could have occurred just before this critical
|
||||||
|
section. If this is the case then the generic list item will
|
||||||
|
have been moved to the pending ready list and the following
|
||||||
|
line is still valid. Also the pvContainer parameter will have
|
||||||
|
been set to NULL so the following lines are also valid. */
|
||||||
|
uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* Is the co-routine waiting on an event also? */
|
||||||
|
if( pxCRCB->xEventListItem.pvContainer )
|
||||||
|
{
|
||||||
|
uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineSchedule( void )
|
||||||
|
{
|
||||||
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
|
prvCheckPendingReadyList();
|
||||||
|
|
||||||
|
/* See if any delayed co-routines have timed out. */
|
||||||
|
prvCheckDelayedList();
|
||||||
|
|
||||||
|
/* Find the highest priority queue that contains ready co-routines. */
|
||||||
|
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
|
||||||
|
{
|
||||||
|
if( uxTopCoRoutineReadyPriority == 0 )
|
||||||
|
{
|
||||||
|
/* No more co-routines to check. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--uxTopCoRoutineReadyPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
|
of the same priority get an equal share of the processor time. */
|
||||||
|
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||||
|
|
||||||
|
/* Call the co-routine. */
|
||||||
|
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE uxPriority;
|
||||||
|
|
||||||
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
|
{
|
||||||
|
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
|
||||||
|
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
|
||||||
|
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
|
||||||
|
{
|
||||||
|
corCRCB *pxUnblockedCRCB;
|
||||||
|
signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
/* This function is called from within an interrupt. It can only access
|
||||||
|
event lists and the pending ready list. This function assumes that a
|
||||||
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
|
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
|
uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
||||||
|
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
+546
@@ -0,0 +1,546 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#define INC_FREERTOS_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include the generic headers required for the FreeRTOS port being used.
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Basic FreeRTOS definitions. */
|
||||||
|
#include "projdefs.h"
|
||||||
|
|
||||||
|
/* Application specific configuration options. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* configUSE_PORT_OPTIMISED_TASK_SELECTION must be defined before portable.h
|
||||||
|
is included as it is used by the port layer. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Definitions specific to the port being used. */
|
||||||
|
#include "portable.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines the prototype to which the application task hook function must
|
||||||
|
conform. */
|
||||||
|
typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all the required application specific macros have been defined.
|
||||||
|
* These macros are application specific and (as downloaded) are defined
|
||||||
|
* within FreeRTOSConfig.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configUSE_PREEMPTION
|
||||||
|
#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_IDLE_HOOK
|
||||||
|
#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TICK_HOOK
|
||||||
|
#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_CO_ROUTINES
|
||||||
|
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskPrioritySet
|
||||||
|
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_uxTaskPriorityGet
|
||||||
|
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelete
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskSuspend
|
||||||
|
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelayUntil
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelay
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_16_BIT_TICKS
|
||||||
|
#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xQueueGetMutexHolder
|
||||||
|
#define INCLUDE_xQueueGetMutexHolder 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_pcTaskGetTaskName
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_APPLICATION_TASK_TAG
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_eTaskStateGet
|
||||||
|
#define INCLUDE_eTaskStateGet 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_MUTEXES
|
||||||
|
#define configUSE_MUTEXES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TIMERS
|
||||||
|
#define configUSE_TIMERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_COUNTING_SEMAPHORES
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_ALTERNATIVE_API
|
||||||
|
#define configUSE_ALTERNATIVE_API 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCRITICAL_NESTING_IN_TCB
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMAX_TASK_NAME_LEN
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configIDLE_SHOULD_YIELD
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configMAX_TASK_NAME_LEN < 1
|
||||||
|
#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskResumeFromISR
|
||||||
|
#define INCLUDE_xTaskResumeFromISR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configASSERT
|
||||||
|
#define configASSERT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portALIGNMENT_ASSERT_pxCurrentTCB
|
||||||
|
#define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The timers module relies on xTaskGetSchedulerState(). */
|
||||||
|
#if configUSE_TIMERS == 1
|
||||||
|
|
||||||
|
#ifndef configTIMER_TASK_PRIORITY
|
||||||
|
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
|
||||||
|
#endif /* configTIMER_TASK_PRIORITY */
|
||||||
|
|
||||||
|
#ifndef configTIMER_QUEUE_LENGTH
|
||||||
|
#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
|
||||||
|
#endif /* configTIMER_QUEUE_LENGTH */
|
||||||
|
|
||||||
|
#ifndef configTIMER_TASK_STACK_DEPTH
|
||||||
|
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
|
||||||
|
#endif /* configTIMER_TASK_STACK_DEPTH */
|
||||||
|
|
||||||
|
#endif /* configUSE_TIMERS */
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetSchedulerState
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCLEAN_UP_TCB
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portSETUP_TCB
|
||||||
|
#define portSETUP_TCB( pxTCB ) ( void ) pxTCB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configQUEUE_REGISTRY_SIZE
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 0U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configQUEUE_REGISTRY_SIZE < 1 )
|
||||||
|
#define vQueueAddToRegistry( xQueue, pcName )
|
||||||
|
#define vQueueUnregisterQueue( xQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portPOINTER_SIZE_TYPE
|
||||||
|
#define portPOINTER_SIZE_TYPE unsigned long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove any unused trace macros. */
|
||||||
|
#ifndef traceSTART
|
||||||
|
/* Used to perform any necessary initialisation - for example, open a file
|
||||||
|
into which trace is to be written. */
|
||||||
|
#define traceSTART()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEND
|
||||||
|
/* Use to close a trace, for example close a file into which trace has been
|
||||||
|
written. */
|
||||||
|
#define traceEND()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SWITCHED_IN
|
||||||
|
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
|
||||||
|
to the task control block of the selected task. */
|
||||||
|
#define traceTASK_SWITCHED_IN()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SWITCHED_OUT
|
||||||
|
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
|
||||||
|
to the task control block of the task being switched out. */
|
||||||
|
#define traceTASK_SWITCHED_OUT()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_INHERIT
|
||||||
|
/* Called when a task attempts to take a mutex that is already held by a
|
||||||
|
lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
|
||||||
|
that holds the mutex. uxInheritedPriority is the priority the mutex holder
|
||||||
|
will inherit (the priority of the task that is attempting to obtain the
|
||||||
|
muted. */
|
||||||
|
#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_DISINHERIT
|
||||||
|
/* Called when a task releases a mutex, the holding of which had resulted in
|
||||||
|
the task inheriting the priority of a higher priority task.
|
||||||
|
pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
|
||||||
|
mutex. uxOriginalPriority is the task's configured (base) priority. */
|
||||||
|
#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
|
||||||
|
/* Task is about to block because it cannot read from a
|
||||||
|
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||||
|
upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||||
|
task that attempted the read. */
|
||||||
|
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceBLOCKING_ON_QUEUE_SEND
|
||||||
|
/* Task is about to block because it cannot write to a
|
||||||
|
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||||
|
upon which the write was attempted. pxCurrentTCB points to the TCB of the
|
||||||
|
task that attempted the write. */
|
||||||
|
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configCHECK_FOR_STACK_OVERFLOW
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following event macros are embedded in the kernel API calls. */
|
||||||
|
|
||||||
|
#ifndef traceMOVED_TASK_TO_READY_STATE
|
||||||
|
#define traceMOVED_TASK_TO_READY_STATE( pxTCB )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_CREATE
|
||||||
|
#define traceQUEUE_CREATE( pxNewQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_CREATE_FAILED
|
||||||
|
#define traceQUEUE_CREATE_FAILED( ucQueueType )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_MUTEX
|
||||||
|
#define traceCREATE_MUTEX( pxNewQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_MUTEX_FAILED
|
||||||
|
#define traceCREATE_MUTEX_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceGIVE_MUTEX_RECURSIVE
|
||||||
|
#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
|
||||||
|
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTAKE_MUTEX_RECURSIVE
|
||||||
|
#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED
|
||||||
|
#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_COUNTING_SEMAPHORE
|
||||||
|
#define traceCREATE_COUNTING_SEMAPHORE()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
|
||||||
|
#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND
|
||||||
|
#define traceQUEUE_SEND( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FAILED
|
||||||
|
#define traceQUEUE_SEND_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE
|
||||||
|
#define traceQUEUE_RECEIVE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_PEEK
|
||||||
|
#define traceQUEUE_PEEK( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FAILED
|
||||||
|
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FROM_ISR
|
||||||
|
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
|
||||||
|
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FROM_ISR
|
||||||
|
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
|
||||||
|
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_DELETE
|
||||||
|
#define traceQUEUE_DELETE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_CREATE
|
||||||
|
#define traceTASK_CREATE( pxNewTCB )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_CREATE_FAILED
|
||||||
|
#define traceTASK_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELETE
|
||||||
|
#define traceTASK_DELETE( pxTaskToDelete )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELAY_UNTIL
|
||||||
|
#define traceTASK_DELAY_UNTIL()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELAY
|
||||||
|
#define traceTASK_DELAY()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_SET
|
||||||
|
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SUSPEND
|
||||||
|
#define traceTASK_SUSPEND( pxTaskToSuspend )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_RESUME
|
||||||
|
#define traceTASK_RESUME( pxTaskToResume )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_RESUME_FROM_ISR
|
||||||
|
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_INCREMENT_TICK
|
||||||
|
#define traceTASK_INCREMENT_TICK( xTickCount )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_CREATE
|
||||||
|
#define traceTIMER_CREATE( pxNewTimer )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_CREATE_FAILED
|
||||||
|
#define traceTIMER_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_COMMAND_SEND
|
||||||
|
#define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_EXPIRED
|
||||||
|
#define traceTIMER_EXPIRED( pxTimer )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_COMMAND_RECEIVED
|
||||||
|
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configGENERATE_RUN_TIME_STATS
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
|
||||||
|
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
|
||||||
|
#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
|
||||||
|
#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
|
||||||
|
|
||||||
|
#ifndef portGET_RUN_TIME_COUNTER_VALUE
|
||||||
|
#ifndef portALT_GET_RUN_TIME_COUNTER_VALUE
|
||||||
|
#error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information.
|
||||||
|
#endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */
|
||||||
|
#endif /* portGET_RUN_TIME_COUNTER_VALUE */
|
||||||
|
|
||||||
|
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||||
|
|
||||||
|
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
|
||||||
|
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_MALLOC_FAILED_HOOK
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portPRIVILEGE_BIT
|
||||||
|
#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portYIELD_WITHIN_API
|
||||||
|
#define portYIELD_WITHIN_API portYIELD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pvPortMallocAligned
|
||||||
|
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef vPortFreeAligned
|
||||||
|
#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configPRE_SLEEP_PROCESSING
|
||||||
|
#define configPRE_SLEEP_PROCESSING( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configPOST_SLEEP_PROCESSING
|
||||||
|
#define configPOST_SLEEP_PROCESSING( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INC_FREERTOS_H */
|
||||||
|
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STACK_MACROS_H
|
||||||
|
#define STACK_MACROS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the stack overflow hook function if the stack of the task being swapped
|
||||||
|
* out is currently overflowed, or looks like it might have overflowed in the
|
||||||
|
* past.
|
||||||
|
*
|
||||||
|
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
||||||
|
* the current stack state only - comparing the current top of stack value to
|
||||||
|
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
||||||
|
* will also cause the last few stack bytes to be checked to ensure the value
|
||||||
|
* to which the bytes were set when the task was created have not been
|
||||||
|
* overwritten. Note this second test does not guarantee that an overflowed
|
||||||
|
* stack will always be recognised.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
|
||||||
|
|
||||||
|
/* FreeRTOSConfig.h is not set to check for stack overflows. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
|
||||||
|
|
||||||
|
/* FreeRTOSConfig.h is only set to use the first method of
|
||||||
|
overflow checking. */
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
|
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
|
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||||
|
\
|
||||||
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
|
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
||||||
+761
@@ -0,0 +1,761 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CO_ROUTINE_H
|
||||||
|
#define CO_ROUTINE_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Used to hide the implementation of the co-routine control block. The
|
||||||
|
control block structure however has to be included in the header due to
|
||||||
|
the macro implementation of the co-routine functionality. */
|
||||||
|
typedef void * xCoRoutineHandle;
|
||||||
|
|
||||||
|
/* Defines the prototype to which co-routine functions must conform. */
|
||||||
|
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
|
||||||
|
|
||||||
|
typedef struct corCoRoutineControlBlock
|
||||||
|
{
|
||||||
|
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||||
|
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||||
|
xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||||
|
unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||||
|
unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||||
|
unsigned short uxState; /*< Used internally by the co-routine implementation. */
|
||||||
|
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
portBASE_TYPE xCoRoutineCreate(
|
||||||
|
crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
|
unsigned portBASE_TYPE uxPriority,
|
||||||
|
unsigned portBASE_TYPE uxIndex
|
||||||
|
);</pre>
|
||||||
|
*
|
||||||
|
* Create a new co-routine and add it to the list of co-routines that are
|
||||||
|
* ready to run.
|
||||||
|
*
|
||||||
|
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
|
||||||
|
* functions require special syntax - see the co-routine section of the WEB
|
||||||
|
* documentation for more information.
|
||||||
|
*
|
||||||
|
* @param uxPriority The priority with respect to other co-routines at which
|
||||||
|
* the co-routine will run.
|
||||||
|
*
|
||||||
|
* @param uxIndex Used to distinguish between different co-routines that
|
||||||
|
* execute the same function. See the example below and the co-routine section
|
||||||
|
* of the WEB documentation for further information.
|
||||||
|
*
|
||||||
|
* @return pdPASS if the co-routine was successfully created and added to a ready
|
||||||
|
* list, otherwise an error code defined with ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
// This may not be necessary for const variables.
|
||||||
|
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||||
|
static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// This co-routine just delays for a fixed period, then toggles
|
||||||
|
// an LED. Two co-routines are created using this function, so
|
||||||
|
// the uxIndex parameter is used to tell the co-routine which
|
||||||
|
// LED to flash and how long to delay. This assumes xQueue has
|
||||||
|
// already been created.
|
||||||
|
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||||
|
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function that creates two co-routines.
|
||||||
|
void vOtherFunction( void )
|
||||||
|
{
|
||||||
|
unsigned char ucParameterToPass;
|
||||||
|
xTaskHandle xHandle;
|
||||||
|
|
||||||
|
// Create two co-routines at priority 0. The first is given index 0
|
||||||
|
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||||
|
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||||
|
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||||
|
{
|
||||||
|
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
void vCoRoutineSchedule( void );</pre>
|
||||||
|
*
|
||||||
|
* Run a co-routine.
|
||||||
|
*
|
||||||
|
* vCoRoutineSchedule() executes the highest priority co-routine that is able
|
||||||
|
* to run. The co-routine will execute until it either blocks, yields or is
|
||||||
|
* preempted by a task. Co-routines execute cooperatively so one
|
||||||
|
* co-routine cannot be preempted by another, but can be preempted by a task.
|
||||||
|
*
|
||||||
|
* If an application comprises of both tasks and co-routines then
|
||||||
|
* vCoRoutineSchedule should be called from the idle task (in an idle task
|
||||||
|
* hook).
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// This idle task hook will schedule a co-routine each time it is called.
|
||||||
|
// The rest of the idle task will execute between co-routine calls.
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
vCoRoutineSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternatively, if you do not require any other part of the idle task to
|
||||||
|
// execute, the idle task hook can call vCoRoutineScheduler() within an
|
||||||
|
// infinite loop.
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
vCoRoutineSchedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
void vCoRoutineSchedule( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crSTART( xCoRoutineHandle xHandle );</pre>
|
||||||
|
*
|
||||||
|
* This macro MUST always be called at the start of a co-routine function.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static long ulAVariable;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Co-routine functionality goes here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crSTART crSTART
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crEND();</pre>
|
||||||
|
*
|
||||||
|
* This macro MUST always be called at the end of a co-routine function.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static long ulAVariable;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Co-routine functionality goes here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crSTART crSTART
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crEND() }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
|
* only. The macros should not be used directly by application writers.
|
||||||
|
*/
|
||||||
|
#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||||
|
#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
|
||||||
|
*
|
||||||
|
* Delay a co-routine for a fixed period of time.
|
||||||
|
*
|
||||||
|
* crDELAY can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the co-routine to delay. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||||
|
* for. The actual amount of time this equates to is defined by
|
||||||
|
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
|
||||||
|
* can be used to convert ticks to milliseconds.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
// This may not be necessary for const variables.
|
||||||
|
// We are to delay for 200ms.
|
||||||
|
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Delay for 200ms.
|
||||||
|
crDELAY( xHandle, xDelayTime );
|
||||||
|
|
||||||
|
// Do something here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crDELAY crDELAY
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||||
|
if( ( xTicksToDelay ) > 0 ) \
|
||||||
|
{ \
|
||||||
|
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
||||||
|
} \
|
||||||
|
crSET_STATE0( ( xHandle ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND(
|
||||||
|
xCoRoutineHandle xHandle,
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvItemToQueue,
|
||||||
|
portTickType xTicksToWait,
|
||||||
|
portBASE_TYPE *pxResult
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||||
|
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param pxQueue The handle of the queue on which the data will be posted.
|
||||||
|
* The handle is obtained as the return value when the queue is created using
|
||||||
|
* the xQueueCreate() API function.
|
||||||
|
*
|
||||||
|
* @param pvItemToQueue A pointer to the data being posted onto the queue.
|
||||||
|
* The number of bytes of each queued item is specified when the queue is
|
||||||
|
* created. This number of bytes is copied from pvItemToQueue into the queue
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||||
|
* to wait for space to become available on the queue, should space not be
|
||||||
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
|
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
|
||||||
|
* below).
|
||||||
|
*
|
||||||
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
|
* data was successfully posted onto the queue, otherwise it will be set to an
|
||||||
|
* error defined within ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||||
|
// a queue.
|
||||||
|
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static portBASE_TYPE xNumberToPost = 0;
|
||||||
|
static portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// Co-routines must begin with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// This assumes the queue has already been created.
|
||||||
|
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
// The message was not posted!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the number to be posted onto the queue.
|
||||||
|
xNumberToPost++;
|
||||||
|
|
||||||
|
// Delay for 100 ticks.
|
||||||
|
crDELAY( xHandle, 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||||
|
{ \
|
||||||
|
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \
|
||||||
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
|
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
|
||||||
|
} \
|
||||||
|
if( *pxResult == errQUEUE_YIELD ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
|
*pxResult = pdPASS; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_RECEIVE(
|
||||||
|
xCoRoutineHandle xHandle,
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvBuffer,
|
||||||
|
portTickType xTicksToWait,
|
||||||
|
portBASE_TYPE *pxResult
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||||
|
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param pxQueue The handle of the queue from which the data will be received.
|
||||||
|
* The handle is obtained as the return value when the queue is created using
|
||||||
|
* the xQueueCreate() API function.
|
||||||
|
*
|
||||||
|
* @param pvBuffer The buffer into which the received item is to be copied.
|
||||||
|
* The number of bytes of each queued item is specified when the queue is
|
||||||
|
* created. This number of bytes is copied into pvBuffer.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||||
|
* to wait for data to become available from the queue, should data not be
|
||||||
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
|
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
|
||||||
|
* crQUEUE_SEND example).
|
||||||
|
*
|
||||||
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
|
* data was successfully retrieved from the queue, otherwise it will be set to
|
||||||
|
* an error code as defined within ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine receives the number of an LED to flash from a queue. It
|
||||||
|
// blocks on the queue until the number is received.
|
||||||
|
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static portBASE_TYPE xResult;
|
||||||
|
static unsigned portBASE_TYPE uxLEDToFlash;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Wait for data to become available on the queue.
|
||||||
|
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// We received the LED to flash - flash it!
|
||||||
|
vParTestToggleLED( uxLEDToFlash );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||||
|
{ \
|
||||||
|
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \
|
||||||
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
|
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \
|
||||||
|
} \
|
||||||
|
if( *( pxResult ) == errQUEUE_YIELD ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
|
*( pxResult ) = pdPASS; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND_FROM_ISR(
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvItemToQueue,
|
||||||
|
portBASE_TYPE xCoRoutinePreviouslyWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
* functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||||
|
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||||
|
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||||
|
* ISR.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
|
||||||
|
* that is being used from within a co-routine.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||||
|
*
|
||||||
|
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||||
|
* queue. The size of the items the queue will hold was defined when the
|
||||||
|
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||||
|
* into the queue storage area.
|
||||||
|
*
|
||||||
|
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
|
||||||
|
* the same queue multiple times from a single interrupt. The first call
|
||||||
|
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||||
|
* the value returned from the previous call.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
|
||||||
|
* used by the ISR to determine if a context switch may be required following
|
||||||
|
* the ISR.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||||
|
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
char cRxedChar;
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Wait for data to become available on the queue. This assumes the
|
||||||
|
// queue xCommsRxQueue has already been created!
|
||||||
|
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
// Was a character received?
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// Process the character here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ISR that uses a queue to send characters received on a serial port to
|
||||||
|
// a co-routine.
|
||||||
|
void vUART_ISR( void )
|
||||||
|
{
|
||||||
|
char cRxedChar;
|
||||||
|
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
|
// We loop around reading characters until there are none left in the UART.
|
||||||
|
while( UART_RX_REG_NOT_EMPTY() )
|
||||||
|
{
|
||||||
|
// Obtain the character from the UART.
|
||||||
|
cRxedChar = UART_RX_REG;
|
||||||
|
|
||||||
|
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||||
|
// the first time around the loop. If the post causes a co-routine
|
||||||
|
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||||
|
// In this manner we can ensure that if more than one co-routine is
|
||||||
|
// blocked on the queue only one is woken by this ISR no matter how
|
||||||
|
// many characters are posted to the queue.
|
||||||
|
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||||
|
}
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND_FROM_ISR(
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvBuffer,
|
||||||
|
portBASE_TYPE * pxCoRoutineWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
* functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||||
|
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||||
|
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||||
|
* ISR.
|
||||||
|
*
|
||||||
|
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
|
||||||
|
* from a queue that is being used from within a co-routine (a co-routine
|
||||||
|
* posted to the queue).
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||||
|
*
|
||||||
|
* @param pvBuffer A pointer to a buffer into which the received item will be
|
||||||
|
* placed. The size of the items the queue will hold was defined when the
|
||||||
|
* queue was created, so this many bytes will be copied from the queue into
|
||||||
|
* pvBuffer.
|
||||||
|
*
|
||||||
|
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
|
||||||
|
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
|
||||||
|
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
|
||||||
|
* *pxCoRoutineWoken will remain unchanged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE an item was successfully received from the queue, otherwise
|
||||||
|
* pdFALSE.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||||
|
// period. The character is incremented each time.
|
||||||
|
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// cChar holds its value while this co-routine is blocked and must therefore
|
||||||
|
// be declared static.
|
||||||
|
static char cCharToTx = 'a';
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Send the next character to the queue.
|
||||||
|
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// The character was successfully posted to the queue.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Could not post the character to the queue.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the UART Tx interrupt to cause an interrupt in this
|
||||||
|
// hypothetical UART. The interrupt will obtain the character
|
||||||
|
// from the queue and send it.
|
||||||
|
ENABLE_RX_INTERRUPT();
|
||||||
|
|
||||||
|
// Increment to the next character then block for a fixed period.
|
||||||
|
// cCharToTx will maintain its value across the delay as it is
|
||||||
|
// declared static.
|
||||||
|
cCharToTx++;
|
||||||
|
if( cCharToTx > 'x' )
|
||||||
|
{
|
||||||
|
cCharToTx = 'a';
|
||||||
|
}
|
||||||
|
crDELAY( 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// All co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ISR that uses a queue to receive characters to send on a UART.
|
||||||
|
void vUART_ISR( void )
|
||||||
|
{
|
||||||
|
char cCharToTx;
|
||||||
|
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
|
while( UART_TX_REG_EMPTY() )
|
||||||
|
{
|
||||||
|
// Are there any characters in the queue waiting to be sent?
|
||||||
|
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||||
|
// is woken by the post - ensuring that only a single co-routine is
|
||||||
|
// woken no matter how many times we go around this loop.
|
||||||
|
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||||
|
{
|
||||||
|
SEND_CHARACTER( cCharToTx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended for internal use by the co-routine macros only.
|
||||||
|
* The macro nature of the co-routine implementation requires that the
|
||||||
|
* prototype appears here. The function should not be used by application
|
||||||
|
* writers.
|
||||||
|
*
|
||||||
|
* Removes the current co-routine from its ready list and places it in the
|
||||||
|
* appropriate delayed list.
|
||||||
|
*/
|
||||||
|
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended for internal use by the queue implementation only.
|
||||||
|
* The function should not be used by application writers.
|
||||||
|
*
|
||||||
|
* Removes the highest priority co-routine from the event list and places it in
|
||||||
|
* the pending ready list.
|
||||||
|
*/
|
||||||
|
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CO_ROUTINE_H */
|
||||||
+350
@@ -0,0 +1,350 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the list implementation used by the scheduler. While it is tailored
|
||||||
|
* heavily for the schedulers needs, it is also available for use by
|
||||||
|
* application code.
|
||||||
|
*
|
||||||
|
* xLists can only store pointers to xListItems. Each xListItem contains a
|
||||||
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
|
* descending item value order.
|
||||||
|
*
|
||||||
|
* Lists are created already containing one list item. The value of this
|
||||||
|
* item is the maximum possible that can be stored, it is therefore always at
|
||||||
|
* the end of the list and acts as a marker. The list member pxHead always
|
||||||
|
* points to this marker - even though it is at the tail of the list. This
|
||||||
|
* is because the tail contains a wrap back pointer to the true head of
|
||||||
|
* the list.
|
||||||
|
*
|
||||||
|
* In addition to it's value, each list item contains a pointer to the next
|
||||||
|
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
|
||||||
|
* and a pointer to back to the object that contains it. These later two
|
||||||
|
* pointers are included for efficiency of list manipulation. There is
|
||||||
|
* effectively a two way link between the object containing the list item and
|
||||||
|
* the list item itself.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \page ListIntroduction List Implementation
|
||||||
|
* \ingroup FreeRTOSIntro
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIST_H
|
||||||
|
#define LIST_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Definition of the only type of object that a list can contain.
|
||||||
|
*/
|
||||||
|
struct xLIST_ITEM
|
||||||
|
{
|
||||||
|
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
|
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
|
||||||
|
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
||||||
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
|
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
|
};
|
||||||
|
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
|
struct xMINI_LIST_ITEM
|
||||||
|
{
|
||||||
|
portTickType xItemValue;
|
||||||
|
volatile struct xLIST_ITEM *pxNext;
|
||||||
|
volatile struct xLIST_ITEM *pxPrevious;
|
||||||
|
};
|
||||||
|
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition of the type of queue used by the scheduler.
|
||||||
|
*/
|
||||||
|
typedef struct xLIST
|
||||||
|
{
|
||||||
|
volatile unsigned portBASE_TYPE uxNumberOfItems;
|
||||||
|
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
||||||
|
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
|
} xList;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to set the owner of a list item. The owner of a list item
|
||||||
|
* is the object (usually a TCB) that contains the list item.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) ( pxOwner )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to get the owner of a list item. The owner of a list item
|
||||||
|
* is the object (usually a TCB) that contains the list item.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( pxListItem )->pvOwner
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
|
* used to sort the list in descending order.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to retrieve the value of the list item. The value can
|
||||||
|
* represent anything - for example a the priority of a task, or the time at
|
||||||
|
* which a task should be unblocked.
|
||||||
|
*
|
||||||
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro the retrieve the value of the list item at the head of a given
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to determine if a list contains any items. The macro will
|
||||||
|
* only have the value true if the list is empty.
|
||||||
|
*
|
||||||
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to return the number of items in the list.
|
||||||
|
*/
|
||||||
|
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access function to obtain the owner of the next entry in a list.
|
||||||
|
*
|
||||||
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||||
|
* and returns that entries pxOwner parameter. Using multiple calls to this
|
||||||
|
* function it is therefore possible to move through every item contained in
|
||||||
|
* a list.
|
||||||
|
*
|
||||||
|
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||||
|
* the list item. In the scheduler this is normally a task control block.
|
||||||
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
|
* item and its owner.
|
||||||
|
*
|
||||||
|
* @param pxList The list from which the next item owner is to be returned.
|
||||||
|
*
|
||||||
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
|
{ \
|
||||||
|
xList * const pxConstList = ( pxList ); \
|
||||||
|
/* Increment the index to the next item and return the item, ensuring */ \
|
||||||
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
|
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
|
||||||
|
{ \
|
||||||
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
|
} \
|
||||||
|
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access function to obtain the owner of the first entry in a list. Lists
|
||||||
|
* are normally sorted in ascending item value order.
|
||||||
|
*
|
||||||
|
* This function returns the pxOwner member of the first item in the list.
|
||||||
|
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||||
|
* the list item. In the scheduler this is normally a task control block.
|
||||||
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
|
* item and its owner.
|
||||||
|
*
|
||||||
|
* @param pxList The list from which the owner of the head item is to be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if a list item is within a list. The list item maintains a
|
||||||
|
* "container" pointer that points to the list it is in. All this macro does
|
||||||
|
* is check to see if the container and the list match.
|
||||||
|
*
|
||||||
|
* @param pxList The list we want to know if the list item is within.
|
||||||
|
* @param pxListItem The list item we want to know if is in the list.
|
||||||
|
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
|
||||||
|
* pointer against
|
||||||
|
*/
|
||||||
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list a list item is contained within (referenced from).
|
||||||
|
*
|
||||||
|
* @param pxListItem The list item being queried.
|
||||||
|
* @return A pointer to the xList object that references the pxListItem
|
||||||
|
*/
|
||||||
|
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This provides a crude means of knowing if a list has been initialised, as
|
||||||
|
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called before a list is used! This initialises all the members
|
||||||
|
* of the list structure and inserts the xListEnd item into the list as a
|
||||||
|
* marker to the back of the list.
|
||||||
|
*
|
||||||
|
* @param pxList Pointer to the list being initialised.
|
||||||
|
*
|
||||||
|
* \page vListInitialise vListInitialise
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInitialise( xList *pxList );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called before a list item is used. This sets the list container to
|
||||||
|
* null so the item does not think that it is already contained in a list.
|
||||||
|
*
|
||||||
|
* @param pxItem Pointer to the list item being initialised.
|
||||||
|
*
|
||||||
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInitialiseItem( xListItem *pxItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
|
* a position determined by its item value (descending item value order).
|
||||||
|
*
|
||||||
|
* @param pxList The list into which the item is to be inserted.
|
||||||
|
*
|
||||||
|
* @param pxNewListItem The item to that is to be placed in the list.
|
||||||
|
*
|
||||||
|
* \page vListInsert vListInsert
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
|
* such that it will be the last item within the list returned by multiple
|
||||||
|
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||||
|
*
|
||||||
|
* The list member pvIndex is used to walk through a list. Calling
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
|
||||||
|
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||||
|
* in the list position pointed to by pvIndex. This means that every other
|
||||||
|
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||||
|
* the pvIndex parameter again points to the item being inserted.
|
||||||
|
*
|
||||||
|
* @param pxList The list into which the item is to be inserted.
|
||||||
|
*
|
||||||
|
* @param pxNewListItem The list item to be inserted into the list.
|
||||||
|
*
|
||||||
|
* \page vListInsertEnd vListInsertEnd
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
* it is in, so only the list item need be passed into the function.
|
||||||
|
*
|
||||||
|
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||||
|
* the list pointed to by it's pxContainer parameter.
|
||||||
|
*
|
||||||
|
* @return The number of items that remain in the list after the list item has
|
||||||
|
* been removed.
|
||||||
|
*
|
||||||
|
* \page uxListRemove uxListRemove
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPU_WRAPPERS_H
|
||||||
|
#define MPU_WRAPPERS_H
|
||||||
|
|
||||||
|
/* This file redefines API functions to be called through a wrapper macro, but
|
||||||
|
only for ports that are using the MPU. */
|
||||||
|
#ifdef portUSING_MPU_WRAPPERS
|
||||||
|
|
||||||
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||||
|
included from queue.c or task.c to prevent it from having an effect within
|
||||||
|
those files. */
|
||||||
|
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#define xTaskGenericCreate MPU_xTaskGenericCreate
|
||||||
|
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||||
|
#define vTaskDelete MPU_vTaskDelete
|
||||||
|
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||||
|
#define vTaskDelay MPU_vTaskDelay
|
||||||
|
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||||
|
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||||
|
#define eTaskStateGet MPU_eTaskStateGet
|
||||||
|
#define vTaskSuspend MPU_vTaskSuspend
|
||||||
|
#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended
|
||||||
|
#define vTaskResume MPU_vTaskResume
|
||||||
|
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||||
|
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||||
|
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||||
|
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||||
|
#define vTaskList MPU_vTaskList
|
||||||
|
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||||
|
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||||
|
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||||
|
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||||
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
|
||||||
|
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||||
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
|
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||||
|
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||||
|
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||||
|
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||||
|
#define xQueueAltGenericSend MPU_xQueueAltGenericSend
|
||||||
|
#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
|
||||||
|
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||||
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
|
||||||
|
#define pvPortMalloc MPU_pvPortMalloc
|
||||||
|
#define vPortFree MPU_vPortFree
|
||||||
|
#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize
|
||||||
|
#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks
|
||||||
|
|
||||||
|
#if configQUEUE_REGISTRY_SIZE > 0
|
||||||
|
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||||
|
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove the privileged function macro. */
|
||||||
|
#define PRIVILEGED_FUNCTION
|
||||||
|
|
||||||
|
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
/* Ensure API functions go in the privileged execution section. */
|
||||||
|
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||||
|
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||||
|
//#define PRIVILEGED_DATA
|
||||||
|
|
||||||
|
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
#else /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
#define PRIVILEGED_FUNCTION
|
||||||
|
#define PRIVILEGED_DATA
|
||||||
|
#define portUSING_MPU_WRAPPERS 0
|
||||||
|
|
||||||
|
#endif /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MPU_WRAPPERS_H */
|
||||||
|
|
||||||
+405
@@ -0,0 +1,405 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Portable layer API. Each function must be defined for each port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PORTABLE_H
|
||||||
|
#define PORTABLE_H
|
||||||
|
|
||||||
|
/* Include the macro file relevant to the port being used. */
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MEGA_AVR
|
||||||
|
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MEGA_AVR
|
||||||
|
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC24_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_DSPIC_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC18F_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC32MX_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _FEDPICC
|
||||||
|
#include "libFreeRTOS/Include/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDCC_CYGNAL
|
||||||
|
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7_ECLIPSE
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_LPC23xx
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MSP430
|
||||||
|
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MSP430
|
||||||
|
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_MSP430
|
||||||
|
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||||
|
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_GCC
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM9XE_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LPC2000_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR71X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_GCC
|
||||||
|
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR91X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_H8S
|
||||||
|
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_AT91FR40008
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RVDS_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARM_CM3
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARMCM3_LM
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HCS12_CODE_WARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROBLAZE_GCC
|
||||||
|
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TERN_EE
|
||||||
|
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_HCS12
|
||||||
|
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MCF5235
|
||||||
|
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_GCC
|
||||||
|
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC405
|
||||||
|
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC440
|
||||||
|
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _16FX_SOFTUNE
|
||||||
|
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_FLASH_LITE_186_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifdef __AVR32_AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ICCAVR32__
|
||||||
|
#ifdef __CORE__
|
||||||
|
#if __CORE__ == __AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __91467D
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __96340
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Fx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3_L__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Hx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3L__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
||||||
|
have the path as part of the project options, rather than as relative from
|
||||||
|
the project location. If portENTER_CRITICAL() has not been defined then
|
||||||
|
portmacro.h has not yet been included - as every portmacro.h provides a
|
||||||
|
portENTER_CRITICAL() definition. Check the demo application for your demo
|
||||||
|
to find the path to the correct portmacro.h file. */
|
||||||
|
#ifndef portENTER_CRITICAL
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 8
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 4
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 2
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 1
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portBYTE_ALIGNMENT_MASK
|
||||||
|
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the stack of a new task so it is ready to be placed under the
|
||||||
|
* scheduler control. The registers have to be placed on the stack in
|
||||||
|
* the order that the port expects to find them.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map to the memory management routines required for the port.
|
||||||
|
*/
|
||||||
|
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||||
|
* the hardware is left in its original condition after the scheduler stops
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The structures and methods of manipulating the MPU are contained within the
|
||||||
|
* port layer.
|
||||||
|
*
|
||||||
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
|
* contained in xRegions.
|
||||||
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
struct xMEMORY_REGION;
|
||||||
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTABLE_H */
|
||||||
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROJDEFS_H
|
||||||
|
#define PROJDEFS_H
|
||||||
|
|
||||||
|
/* Defines the prototype to which task functions must conform. */
|
||||||
|
typedef void (*pdTASK_CODE)( void * );
|
||||||
|
|
||||||
|
#define pdTRUE ( 1 )
|
||||||
|
#define pdFALSE ( 0 )
|
||||||
|
|
||||||
|
#define pdPASS ( 1 )
|
||||||
|
#define pdFAIL ( 0 )
|
||||||
|
#define errQUEUE_EMPTY ( 0 )
|
||||||
|
#define errQUEUE_FULL ( 0 )
|
||||||
|
|
||||||
|
/* Error definitions. */
|
||||||
|
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||||
|
#define errNO_TASK_TO_RUN ( -2 )
|
||||||
|
#define errQUEUE_BLOCKED ( -4 )
|
||||||
|
#define errQUEUE_YIELD ( -5 )
|
||||||
|
|
||||||
|
#endif /* PROJDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+1302
File diff suppressed because it is too large
Load Diff
+789
@@ -0,0 +1,789 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMAPHORE_H
|
||||||
|
#define SEMAPHORE_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h" must appear in source files before "include semphr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
typedef xQueueHandle xSemaphoreHandle;
|
||||||
|
|
||||||
|
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )
|
||||||
|
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )
|
||||||
|
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
|
||||||
|
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
||||||
|
* as we don't want to actually store any data - we just want to know if the
|
||||||
|
* queue is empty or full.
|
||||||
|
*
|
||||||
|
* This type of semaphore can be used for pure synchronisation between tasks or
|
||||||
|
* between an interrupt and a task. The semaphore need not be given back once
|
||||||
|
* obtained, so one task/interrupt can continuously 'give' the semaphore while
|
||||||
|
* another continuously 'takes' the semaphore. For this reason this type of
|
||||||
|
* semaphore does not use a priority inheritance mechanism. For an alternative
|
||||||
|
* that does use priority inheritance see xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define vSemaphoreCreateBinary( xSemaphore ) \
|
||||||
|
{ \
|
||||||
|
( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
||||||
|
if( ( xSemaphore ) != NULL ) \
|
||||||
|
{ \
|
||||||
|
xSemaphoreGive( ( xSemaphore ) ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreTake(
|
||||||
|
* xSemaphoreHandle xSemaphore,
|
||||||
|
* portTickType xBlockTime
|
||||||
|
* )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
||||||
|
* xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being taken - obtained when
|
||||||
|
* the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
|
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the semaphore. A block
|
||||||
|
* time of portMAX_DELAY can be used to block indefinitely (provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was obtained. pdFALSE
|
||||||
|
* if xBlockTime expired without the semaphore becoming available.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// A task that creates a semaphore.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the semaphore to guard a shared resource.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the semaphore.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the semaphore. If the semaphore is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the semaphore and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished accessing the shared resource. Release the
|
||||||
|
// semaphore.
|
||||||
|
xSemaphoreGive( xSemaphore );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the semaphore and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* xSemaphoreTakeRecursive(
|
||||||
|
* xSemaphoreHandle xMutex,
|
||||||
|
* portTickType xBlockTime
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
|
||||||
|
* The mutex must have previously been created using a call to
|
||||||
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
|
* macro to be available.
|
||||||
|
*
|
||||||
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* @param xMutex A handle to the mutex being obtained. This is the
|
||||||
|
* handle returned by xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
|
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the semaphore. If
|
||||||
|
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
|
||||||
|
* return immediately no matter what the value of xBlockTime.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
|
||||||
|
* expired without the semaphore becoming available.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xMutex = NULL;
|
||||||
|
|
||||||
|
// A task that creates a mutex.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the mutex to guard a shared resource.
|
||||||
|
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the mutex.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the mutex and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
// For some reason due to the nature of the code further calls to
|
||||||
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
|
// code these would not be just sequential calls as this would make
|
||||||
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
|
// a more complex call structure.
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
|
||||||
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
|
// available to another task until it has also been given back
|
||||||
|
// three times. Again it is unlikely that real code would have
|
||||||
|
// these calls sequentially, but instead buried in a more complex
|
||||||
|
// call structure. This is just for illustrative purposes.
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
|
||||||
|
// Now the mutex can be taken by other tasks.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the mutex and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
|
||||||
|
*
|
||||||
|
* The source code that implements the alternative (Alt) API is much
|
||||||
|
* simpler because it executes everything from within a critical section.
|
||||||
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
|
* preferred fully featured API too. The fully featured API has more
|
||||||
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
||||||
|
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
|
||||||
|
*
|
||||||
|
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
|
||||||
|
* an alternative which can be used from an ISR.
|
||||||
|
*
|
||||||
|
* This macro must also not be used on semaphores created using
|
||||||
|
* xSemaphoreCreateRecursiveMutex().
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
|
||||||
|
* Semaphores are implemented using queues. An error can occur if there is
|
||||||
|
* no space on the queue to post a message - indicating that the
|
||||||
|
* semaphore was not first obtained correctly.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the semaphore to guard a shared resource.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
|
{
|
||||||
|
// We would expect this call to fail because we cannot give
|
||||||
|
// a semaphore without first "taking" it!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain the semaphore - don't block if the semaphore is not
|
||||||
|
// immediately available.
|
||||||
|
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
|
||||||
|
{
|
||||||
|
// We now have the semaphore and can access the shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished accessing the shared resource so can free the
|
||||||
|
// semaphore.
|
||||||
|
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
|
{
|
||||||
|
// We would not expect this call to fail because we must have
|
||||||
|
// obtained the semaphore to get here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
|
||||||
|
* The mutex must have previously been created using a call to
|
||||||
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
|
* macro to be available.
|
||||||
|
*
|
||||||
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* @param xMutex A handle to the mutex being released, or 'given'. This is the
|
||||||
|
* handle returned by xSemaphoreCreateMutex();
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was given.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xMutex = NULL;
|
||||||
|
|
||||||
|
// A task that creates a mutex.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the mutex to guard a shared resource.
|
||||||
|
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the mutex.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the mutex and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
// For some reason due to the nature of the code further calls to
|
||||||
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
|
// code these would not be just sequential calls as this would make
|
||||||
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
|
// a more complex call structure.
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
|
||||||
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
|
// available to another task until it has also been given back
|
||||||
|
// three times. Again it is unlikely that real code would have
|
||||||
|
// these calls sequentially, it would be more likely that the calls
|
||||||
|
// to xSemaphoreGiveRecursive() would be called as a call stack
|
||||||
|
// unwound. This is just for demonstrative purposes.
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
|
||||||
|
// Now the mutex can be taken by other tasks.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the mutex and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
|
||||||
|
*
|
||||||
|
* The source code that implements the alternative (Alt) API is much
|
||||||
|
* simpler because it executes everything from within a critical section.
|
||||||
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
|
* preferred fully featured API too. The fully featured API has more
|
||||||
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>
|
||||||
|
xSemaphoreGiveFromISR(
|
||||||
|
xSemaphoreHandle xSemaphore,
|
||||||
|
signed portBASE_TYPE *pxHigherPriorityTaskWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
|
||||||
|
* must not be used with this macro.
|
||||||
|
*
|
||||||
|
* This macro can be used from an ISR.
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
|
||||||
|
* to unblock, and the unblocked task has a priority higher than the currently
|
||||||
|
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
|
||||||
|
* a context switch should be requested before the interrupt is exited.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
\#define LONG_TIME 0xffff
|
||||||
|
\#define TICKS_TO_WAIT 10
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// Repetitive task.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// We want this task to run every 10 ticks of a timer. The semaphore
|
||||||
|
// was created before this task was started.
|
||||||
|
|
||||||
|
// Block waiting for the semaphore to become available.
|
||||||
|
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// It is time to execute.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished our task. Return to the top of the loop where
|
||||||
|
// we will block on the semaphore until it is time to execute
|
||||||
|
// again. Note when using the semaphore for synchronisation with an
|
||||||
|
// ISR in this manner there is no need to 'give' the semaphore back.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer ISR
|
||||||
|
void vTimerISR( void * pvParameters )
|
||||||
|
{
|
||||||
|
static unsigned char ucLocalTickCount = 0;
|
||||||
|
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
|
// A timer tick has occurred.
|
||||||
|
|
||||||
|
// ... Do other time functions.
|
||||||
|
|
||||||
|
// Is it time for vATask () to run?
|
||||||
|
xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
ucLocalTickCount++;
|
||||||
|
if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||||
|
{
|
||||||
|
// Unblock the task by releasing the semaphore.
|
||||||
|
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
// Reset the count so we release the semaphore again in 10 ticks time.
|
||||||
|
ucLocalTickCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
{
|
||||||
|
// We can force a context switch here. Context switching from an
|
||||||
|
// ISR uses port specific syntax. Check the demo task for your port
|
||||||
|
// to find the syntax required.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>
|
||||||
|
xSemaphoreTakeFromISR(
|
||||||
|
xSemaphoreHandle xSemaphore,
|
||||||
|
signed portBASE_TYPE *pxHigherPriorityTaskWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
|
||||||
|
* previously been created with a call to vSemaphoreCreateBinary() or
|
||||||
|
* xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
|
||||||
|
* must not be used with this macro.
|
||||||
|
*
|
||||||
|
* This macro can be used from an ISR, however taking a semaphore from an ISR
|
||||||
|
* is not a common operation. It is likely to only be useful when taking a
|
||||||
|
* counting semaphore when an interrupt is obtaining an object from a resource
|
||||||
|
* pool (when the semaphore count indicates the number of resources available).
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being taken. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
|
||||||
|
* to unblock, and the unblocked task has a priority higher than the currently
|
||||||
|
* running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then
|
||||||
|
* a context switch should be requested before the interrupt is exited.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was successfully taken, otherwise
|
||||||
|
* pdFALSE
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
|
||||||
|
* mechanism.
|
||||||
|
*
|
||||||
|
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
|
||||||
|
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
|
||||||
|
* xSemaphoreGiveRecursive() macros should not be used.
|
||||||
|
*
|
||||||
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
|
*
|
||||||
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
|
*
|
||||||
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
|
* service routines.
|
||||||
|
*
|
||||||
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
|
* xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
xSemaphore = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a recursive mutex by using the existing queue
|
||||||
|
* mechanism.
|
||||||
|
*
|
||||||
|
* Mutexes created using this macro can be accessed using the
|
||||||
|
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
|
||||||
|
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
|
*
|
||||||
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
|
*
|
||||||
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
|
* service routines.
|
||||||
|
*
|
||||||
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
|
* xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
xSemaphore = xSemaphoreCreateRecursiveMutex();
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that creates a counting semaphore by using the existing
|
||||||
|
* queue mechanism.
|
||||||
|
*
|
||||||
|
* Counting semaphores are typically used for two things:
|
||||||
|
*
|
||||||
|
* 1) Counting events.
|
||||||
|
*
|
||||||
|
* In this usage scenario an event handler will 'give' a semaphore each time
|
||||||
|
* an event occurs (incrementing the semaphore count value), and a handler
|
||||||
|
* task will 'take' a semaphore each time it processes an event
|
||||||
|
* (decrementing the semaphore count value). The count value is therefore
|
||||||
|
* the difference between the number of events that have occurred and the
|
||||||
|
* number that have been processed. In this case it is desirable for the
|
||||||
|
* initial count value to be zero.
|
||||||
|
*
|
||||||
|
* 2) Resource management.
|
||||||
|
*
|
||||||
|
* In this usage scenario the count value indicates the number of resources
|
||||||
|
* available. To obtain control of a resource a task must first obtain a
|
||||||
|
* semaphore - decrementing the semaphore count value. When the count value
|
||||||
|
* reaches zero there are no free resources. When a task finishes with the
|
||||||
|
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
||||||
|
* value. In this case it is desirable for the initial count value to be
|
||||||
|
* equal to the maximum count value, indicating that all resources are free.
|
||||||
|
*
|
||||||
|
* @param uxMaxCount The maximum count value that can be reached. When the
|
||||||
|
* semaphore reaches this value it can no longer be 'given'.
|
||||||
|
*
|
||||||
|
* @param uxInitialCount The count value assigned to the semaphore when it is
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* @return Handle to the created semaphore. Null if the semaphore could not be
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||||
|
// The max value to which the semaphore can count should be 10, and the
|
||||||
|
// initial value assigned to the count should be 0.
|
||||||
|
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>
|
||||||
|
*
|
||||||
|
* Delete a semaphore. This function must be used with care. For example,
|
||||||
|
* do not delete a mutex type semaphore if the mutex is held by a task.
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore to be deleted.
|
||||||
|
*
|
||||||
|
* \page vSemaphoreDelete vSemaphoreDelete
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr.h
|
||||||
|
* <pre>xTaskHandle xSemaphoreGetMutexHolder( xSemaphoreHandle xMutex );</pre>
|
||||||
|
*
|
||||||
|
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
|
||||||
|
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
|
||||||
|
* by a task), return NULL.
|
||||||
|
*
|
||||||
|
* Note: This Is is a good way of determining if the calling task is the mutex
|
||||||
|
* holder, but not a good way of determining the identity of the mutex holder as
|
||||||
|
* the holder may change between the function exiting and the returned value
|
||||||
|
* being tested.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
|
||||||
|
|
||||||
|
#endif /* SEMAPHORE_H */
|
||||||
|
|
||||||
|
|
||||||
+1338
File diff suppressed because it is too large
Load Diff
+954
@@ -0,0 +1,954 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TIMERS_H
|
||||||
|
#define TIMERS_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "portable.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||||
|
be used solely through the macros that make up the public software timer API,
|
||||||
|
as defined below. */
|
||||||
|
#define tmrCOMMAND_START 0
|
||||||
|
#define tmrCOMMAND_STOP 1
|
||||||
|
#define tmrCOMMAND_CHANGE_PERIOD 2
|
||||||
|
#define tmrCOMMAND_DELETE 3
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* MACROS AND DEFINITIONS
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type by which software timers are referenced. For example, a call to
|
||||||
|
* xTimerCreate() returns an xTimerHandle variable that can then be used to
|
||||||
|
* reference the subject timer in calls to other software timer API functions
|
||||||
|
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||||
|
*/
|
||||||
|
typedef void * xTimerHandle;
|
||||||
|
|
||||||
|
/* Define the prototype to which timer callback functions must conform. */
|
||||||
|
typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xTimerHandle xTimerCreate( const signed char *pcTimerName,
|
||||||
|
* portTickType xTimerPeriodInTicks,
|
||||||
|
* unsigned portBASE_TYPE uxAutoReload,
|
||||||
|
* void * pvTimerID,
|
||||||
|
* tmrTIMER_CALLBACK pxCallbackFunction );
|
||||||
|
*
|
||||||
|
* Creates a new software timer instance. This allocates the storage required
|
||||||
|
* by the new timer, initialises the new timers internal state, and returns a
|
||||||
|
* handle by which the new timer can be referenced.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
|
||||||
|
* active state.
|
||||||
|
*
|
||||||
|
* @param pcTimerName A text name that is assigned to the timer. This is done
|
||||||
|
* purely to assist debugging. The kernel itself only ever references a timer by
|
||||||
|
* its handle, and never by its name.
|
||||||
|
*
|
||||||
|
* @param xTimerPeriodInTicks The timer period. The time is defined in tick periods so
|
||||||
|
* the constant portTICK_RATE_MS can be used to convert a time that has been
|
||||||
|
* specified in milliseconds. For example, if the timer must expire after 100
|
||||||
|
* ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer
|
||||||
|
* must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )
|
||||||
|
* provided configTICK_RATE_HZ is less than or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
||||||
|
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If
|
||||||
|
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
|
* enter the dormant state after it expires.
|
||||||
|
*
|
||||||
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
|
* Typically this would be used in the timer callback function to identify which
|
||||||
|
* timer expired when the same callback function is assigned to more than one
|
||||||
|
* timer.
|
||||||
|
*
|
||||||
|
* @param pxCallbackFunction The function to call when the timer expires.
|
||||||
|
* Callback functions must have the prototype defined by tmrTIMER_CALLBACK,
|
||||||
|
* which is "void vCallbackFunction( xTimerHandle xTimer );".
|
||||||
|
*
|
||||||
|
* @return If the timer is successfully create then a handle to the newly
|
||||||
|
* created timer is returned. If the timer cannot be created (because either
|
||||||
|
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
||||||
|
* structures, or the timer period was set to 0) then 0 is returned.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* #define NUM_TIMERS 5
|
||||||
|
*
|
||||||
|
* // An array to hold handles to the created timers.
|
||||||
|
* xTimerHandle xTimers[ NUM_TIMERS ];
|
||||||
|
*
|
||||||
|
* // An array to hold a count of the number of times each timer expires.
|
||||||
|
* long lExpireCounters[ NUM_TIMERS ] = { 0 };
|
||||||
|
*
|
||||||
|
* // Define a callback function that will be used by multiple timer instances.
|
||||||
|
* // The callback function does nothing but count the number of times the
|
||||||
|
* // associated timer expires, and stop the timer once the timer has expired
|
||||||
|
* // 10 times.
|
||||||
|
* void vTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* long lArrayIndex;
|
||||||
|
* const long xMaxExpiryCountBeforeStopping = 10;
|
||||||
|
*
|
||||||
|
* // Optionally do something if the pxTimer parameter is NULL.
|
||||||
|
* configASSERT( pxTimer );
|
||||||
|
*
|
||||||
|
* // Which timer expired?
|
||||||
|
* lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );
|
||||||
|
*
|
||||||
|
* // Increment the number of times that pxTimer has expired.
|
||||||
|
* lExpireCounters[ lArrayIndex ] += 1;
|
||||||
|
*
|
||||||
|
* // If the timer has expired 10 times then stop it from running.
|
||||||
|
* if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )
|
||||||
|
* {
|
||||||
|
* // Do not use a block time if calling a timer API function from a
|
||||||
|
* // timer callback function, as doing so could cause a deadlock!
|
||||||
|
* xTimerStop( pxTimer, 0 );
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* long x;
|
||||||
|
*
|
||||||
|
* // Create then start some timers. Starting the timers before the scheduler
|
||||||
|
* // has been started means the timers will start running immediately that
|
||||||
|
* // the scheduler starts.
|
||||||
|
* for( x = 0; x < NUM_TIMERS; x++ )
|
||||||
|
* {
|
||||||
|
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
||||||
|
* ( 100 * x ), // The timer period in ticks.
|
||||||
|
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
||||||
|
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
||||||
|
* vTimerCallback // Each timer calls the same callback when it expires.
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* if( xTimers[ x ] == NULL )
|
||||||
|
* {
|
||||||
|
* // The timer was not created.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // Start the timer. No block time is specified, and even if one was
|
||||||
|
* // it would be ignored because the scheduler has not yet been
|
||||||
|
* // started.
|
||||||
|
* if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The timer could not be set into the Active state.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timers running as they have already
|
||||||
|
* // been set into the active state.
|
||||||
|
* xTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* void *pvTimerGetTimerID( xTimerHandle xTimer );
|
||||||
|
*
|
||||||
|
* Returns the ID assigned to the timer.
|
||||||
|
*
|
||||||
|
* IDs are assigned to timers using the pvTimerID parameter of the call to
|
||||||
|
* xTimerCreated() that was used to create the timer.
|
||||||
|
*
|
||||||
|
* If the same callback function is assigned to multiple timers then the timer
|
||||||
|
* ID can be used within the callback function to identify which timer actually
|
||||||
|
* expired.
|
||||||
|
*
|
||||||
|
* @param xTimer The timer being queried.
|
||||||
|
*
|
||||||
|
* @return The ID assigned to the timer being queried.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*/
|
||||||
|
void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );
|
||||||
|
*
|
||||||
|
* Queries a timer to see if it is active or dormant.
|
||||||
|
*
|
||||||
|
* A timer will be dormant if:
|
||||||
|
* 1) It has been created but not started, or
|
||||||
|
* 2) It is an expired on-shot timer that has not been restarted.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
|
||||||
|
* active state.
|
||||||
|
*
|
||||||
|
* @param xTimer The timer being queried.
|
||||||
|
*
|
||||||
|
* @return pdFALSE will be returned if the timer is dormant. A value other than
|
||||||
|
* pdFALSE will be returned if the timer is active.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This function assumes xTimer has already been created.
|
||||||
|
* void vAFunction( xTimerHandle xTimer )
|
||||||
|
* {
|
||||||
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
|
* {
|
||||||
|
* // xTimer is active, do something.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // xTimer is not active, do something else.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xTimerGetTimerDaemonTaskHandle() is only available if
|
||||||
|
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* Simply returns the handle of the timer service/daemon task. It it not valid
|
||||||
|
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
||||||
|
*/
|
||||||
|
xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerStart() starts a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function. If the timer had already been started and was
|
||||||
|
* already in the active state, then xTimerStart() has equivalent functionality
|
||||||
|
* to the xTimerReset() API function.
|
||||||
|
*
|
||||||
|
* Starting a timer ensures the timer is in the active state. If the timer
|
||||||
|
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||||
|
* associated with the timer will get called 'n' ticks after xTimerStart() was
|
||||||
|
* called, where 'n' is the timers defined period.
|
||||||
|
*
|
||||||
|
* It is valid to call xTimerStart() before the scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the scheduler is
|
||||||
|
* started, and the timers expiry time will be relative to when the scheduler is
|
||||||
|
* started, not relative to when xTimerStart() was called.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being started/restarted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the start command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the start command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
|
* timers expiry time is relative to when xTimerStart() is actually called. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerStop() stops a timer that was previously started using either of the
|
||||||
|
* The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),
|
||||||
|
* xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.
|
||||||
|
*
|
||||||
|
* Stopping a timer ensures the timer is not in the active state.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being stopped.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the stop command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the stop command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
|
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,
|
||||||
|
* portTickType xNewPeriod,
|
||||||
|
* portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerChangePeriod() changes the period of a timer that was previously
|
||||||
|
* created using the xTimerCreate() API function.
|
||||||
|
*
|
||||||
|
* xTimerChangePeriod() can be called to change the period of an active or
|
||||||
|
* dormant state timer.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for
|
||||||
|
* xTimerChangePeriod() to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
|
*
|
||||||
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
||||||
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
|
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
||||||
|
* or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the change period command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when xTimerChangePeriod() was called. xBlockTime is ignored if
|
||||||
|
* xTimerChangePeriod() is called before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the change period command could not be
|
||||||
|
* sent to the timer command queue even after xBlockTime ticks had passed.
|
||||||
|
* pdPASS will be returned if the command was successfully sent to the timer
|
||||||
|
* command queue. When the command is actually processed will depend on the
|
||||||
|
* priority of the timer service/daemon task relative to other tasks in the
|
||||||
|
* system. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This function assumes xTimer has already been created. If the timer
|
||||||
|
* // referenced by xTimer is already active when it is called, then the timer
|
||||||
|
* // is deleted. If the timer referenced by xTimer is not active when it is
|
||||||
|
* // called, then the period of the timer is set to 500ms and the timer is
|
||||||
|
* // started.
|
||||||
|
* void vAFunction( xTimerHandle xTimer )
|
||||||
|
* {
|
||||||
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
|
* {
|
||||||
|
* // xTimer is already active - delete it.
|
||||||
|
* xTimerDelete( xTimer );
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // xTimer is not active, change its period to 500ms. This will also
|
||||||
|
* // cause the timer to start. Block for a maximum of 100 ticks if the
|
||||||
|
* // change period command cannot immediately be sent to the timer
|
||||||
|
* // command queue.
|
||||||
|
* if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )
|
||||||
|
* {
|
||||||
|
* // The command was successfully sent.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // The command could not be sent, even after waiting for 100 ticks
|
||||||
|
* // to pass. Take appropriate action here.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerDelete() deletes a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for
|
||||||
|
* xTimerDelete() to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being deleted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the delete command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()
|
||||||
|
* is called before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the delete command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
|
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerChangePeriod() API function example usage scenario.
|
||||||
|
*/
|
||||||
|
#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerReset() re-starts a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function. If the timer had already been started and was
|
||||||
|
* already in the active state, then xTimerReset() will cause the timer to
|
||||||
|
* re-evaluate its expiry time so that it is relative to when xTimerReset() was
|
||||||
|
* called. If the timer was in the dormant state then xTimerReset() has
|
||||||
|
* equivalent functionality to the xTimerStart() API function.
|
||||||
|
*
|
||||||
|
* Resetting a timer ensures the timer is in the active state. If the timer
|
||||||
|
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||||
|
* associated with the timer will get called 'n' ticks after xTimerReset() was
|
||||||
|
* called, where 'n' is the timers defined period.
|
||||||
|
*
|
||||||
|
* It is valid to call xTimerReset() before the scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the scheduler is
|
||||||
|
* started, and the timers expiry time will be relative to when the scheduler is
|
||||||
|
* started, not relative to when xTimerReset() was called.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being reset/started/restarted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the reset command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the reset command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
|
* timers expiry time is relative to when xTimerStart() is actually called. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer.
|
||||||
|
*
|
||||||
|
* xTimerHandle xBacklightTimer = NULL;
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press event handler.
|
||||||
|
* void vKeyPressEventHandler( char cKey )
|
||||||
|
* {
|
||||||
|
* // Ensure the LCD back-light is on, then reset the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. Wait 10 ticks for the command to be successfully sent
|
||||||
|
* // if it cannot be sent immediately.
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
* if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The reset command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* long x;
|
||||||
|
*
|
||||||
|
* // Create then start the one-shot timer that is responsible for turning
|
||||||
|
* // the back-light off if no keys are pressed within a 5 second period.
|
||||||
|
* xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.
|
||||||
|
* ( 5000 / portTICK_RATE_MS), // The timer period in ticks.
|
||||||
|
* pdFALSE, // The timer is a one-shot timer.
|
||||||
|
* 0, // The id is not used by the callback so can take any value.
|
||||||
|
* vBacklightTimerCallback // The callback function that switches the LCD back-light off.
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* if( xBacklightTimer == NULL )
|
||||||
|
* {
|
||||||
|
* // The timer was not created.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // Start the timer. No block time is specified, and even if one was
|
||||||
|
* // it would be ignored because the scheduler has not yet been
|
||||||
|
* // started.
|
||||||
|
* if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The timer could not be set into the Active state.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timer running as it has already
|
||||||
|
* // been set into the active state.
|
||||||
|
* xTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerStart() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being started/restarted.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerStartFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerStartFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerStartFromISR() function. If
|
||||||
|
* xTimerStartFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the start command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system, although the timers expiry time is
|
||||||
|
* relative to when xTimerStartFromISR() is actually called. The timer service/daemon
|
||||||
|
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer, and unlike the example given for
|
||||||
|
* // the xTimerReset() function, the key press event handler is an interrupt
|
||||||
|
* // service routine.
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press interrupt service routine.
|
||||||
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // Ensure the LCD back-light is on, then restart the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. This is an interrupt service routine so can only
|
||||||
|
* // call FreeRTOS API functions that end in "FromISR".
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
*
|
||||||
|
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
|
||||||
|
* // as both cause the timer to re-calculate its expiry time.
|
||||||
|
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
|
||||||
|
* // declared (in this function).
|
||||||
|
* if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The start command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerStop() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being stopped.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerStopFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerStopFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerStopFromISR() function. If
|
||||||
|
* xTimerStopFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the stop command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system. The timer service/daemon task
|
||||||
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
|
* // an interrupt occurs, the timer should be simply stopped.
|
||||||
|
*
|
||||||
|
* // The interrupt service routine that stops the timer.
|
||||||
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // The interrupt has occurred - simply stop the timer.
|
||||||
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
|
* // (within this function). As this is an interrupt service routine, only
|
||||||
|
* // FreeRTOS API functions that end in "FromISR" can be used.
|
||||||
|
* if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The stop command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,
|
||||||
|
* portTickType xNewPeriod,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerChangePeriod() that can be called from an interrupt
|
||||||
|
* service routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
|
*
|
||||||
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
||||||
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
|
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
||||||
|
* or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerChangePeriodFromISR() writes a message to the
|
||||||
|
* timer command queue, so has the potential to transition the timer service/
|
||||||
|
* daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()
|
||||||
|
* causes the timer service/daemon task to leave the Blocked state, and the
|
||||||
|
* timer service/daemon task has a priority equal to or greater than the
|
||||||
|
* currently executing task (the task that was interrupted), then
|
||||||
|
* *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the
|
||||||
|
* xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets
|
||||||
|
* this value to pdTRUE then a context switch should be performed before the
|
||||||
|
* interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the command to change the timers period
|
||||||
|
* could not be sent to the timer command queue. pdPASS will be returned if the
|
||||||
|
* command was successfully sent to the timer command queue. When the command
|
||||||
|
* is actually processed will depend on the priority of the timer service/daemon
|
||||||
|
* task relative to other tasks in the system. The timer service/daemon task
|
||||||
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
|
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
|
||||||
|
*
|
||||||
|
* // The interrupt service routine that changes the period of xTimer.
|
||||||
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // The interrupt has occurred - change the period of xTimer to 500ms.
|
||||||
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
|
* // (within this function). As this is an interrupt service routine, only
|
||||||
|
* // FreeRTOS API functions that end in "FromISR" can be used.
|
||||||
|
* if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The command to change the timers period was not executed
|
||||||
|
* // successfully. Take appropriate action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerReset() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is to be started, reset, or
|
||||||
|
* restarted.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerResetFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerResetFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerResetFromISR() function. If
|
||||||
|
* xTimerResetFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the reset command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system, although the timers expiry time is
|
||||||
|
* relative to when xTimerResetFromISR() is actually called. The timer service/daemon
|
||||||
|
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer, and unlike the example given for
|
||||||
|
* // the xTimerReset() function, the key press event handler is an interrupt
|
||||||
|
* // service routine.
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press interrupt service routine.
|
||||||
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // Ensure the LCD back-light is on, then reset the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. This is an interrupt service routine so can only
|
||||||
|
* // call FreeRTOS API functions that end in "FromISR".
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
*
|
||||||
|
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
|
||||||
|
* // as both cause the timer to re-calculate its expiry time.
|
||||||
|
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
|
||||||
|
* // declared (in this function).
|
||||||
|
* if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The reset command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions beyond this part are not part of the public API and are intended
|
||||||
|
* for use by the kernel only.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
|
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* TIMERS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+208
@@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* PUBLIC LIST API documented in list.h
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInitialise( xList *pxList )
|
||||||
|
{
|
||||||
|
/* The list structure contains a list item which is used to mark the
|
||||||
|
end of the list. To initialise the list the list end is inserted
|
||||||
|
as the only list entry. */
|
||||||
|
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
/* The list end value is the highest possible value in the list to
|
||||||
|
ensure it remains at the end of the list. */
|
||||||
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
|
||||||
|
/* The list end next and previous pointers point to itself so we know
|
||||||
|
when the list is empty. */
|
||||||
|
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInitialiseItem( xListItem *pxItem )
|
||||||
|
{
|
||||||
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
|
pxItem->pvContainer = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
|
||||||
|
{
|
||||||
|
volatile xListItem * pxIndex;
|
||||||
|
|
||||||
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
|
makes the new list item the last item to be removed by a call to
|
||||||
|
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
|
||||||
|
the pxIndex member. */
|
||||||
|
pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
|
pxNewListItem->pxNext = pxIndex->pxNext;
|
||||||
|
pxNewListItem->pxPrevious = pxList->pxIndex;
|
||||||
|
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
|
||||||
|
/* Remember which list the item is in. */
|
||||||
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
|
|
||||||
|
( pxList->uxNumberOfItems )++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInsert( xList *pxList, xListItem *pxNewListItem )
|
||||||
|
{
|
||||||
|
volatile xListItem *pxIterator;
|
||||||
|
portTickType xValueOfInsertion;
|
||||||
|
|
||||||
|
/* Insert the new list item into the list, sorted in ulListItem order. */
|
||||||
|
xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
|
/* If the list already contains a list item with the same item value then
|
||||||
|
the new list item should be placed after it. This ensures that TCB's which
|
||||||
|
are stored in ready lists (all of which have the same ulListItem value)
|
||||||
|
get an equal share of the CPU. However, if the xItemValue is the same as
|
||||||
|
the back marker the iteration loop below will not end. This means we need
|
||||||
|
to guard against this by checking the value first and modifying the
|
||||||
|
algorithm slightly if necessary. */
|
||||||
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
|
{
|
||||||
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* *** NOTE ***********************************************************
|
||||||
|
If you find your application is crashing here then likely causes are:
|
||||||
|
1) Stack overflow -
|
||||||
|
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
|
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
||||||
|
parts where numerically high priority values denote low actual
|
||||||
|
interrupt priories, which can seem counter intuitive. See
|
||||||
|
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||||
|
3) Calling an API function from within a critical section or when
|
||||||
|
the scheduler is suspended.
|
||||||
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
|
before the scheduler has been started (are interrupts firing
|
||||||
|
before vTaskStartScheduler() has been called?).
|
||||||
|
See http://www.freertos.org/FAQHelp.html for more tips.
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
|
||||||
|
{
|
||||||
|
/* There is nothing to do here, we are just iterating to the
|
||||||
|
wanted insertion position. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
|
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxNewListItem->pxPrevious = pxIterator;
|
||||||
|
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
|
||||||
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
|
item later. */
|
||||||
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
|
|
||||||
|
( pxList->uxNumberOfItems )++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove )
|
||||||
|
{
|
||||||
|
xList * pxList;
|
||||||
|
|
||||||
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
||||||
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
|
item. */
|
||||||
|
pxList = ( xList * ) pxItemToRemove->pvContainer;
|
||||||
|
|
||||||
|
/* Make sure the index is left pointing to a valid item. */
|
||||||
|
if( pxList->pxIndex == pxItemToRemove )
|
||||||
|
{
|
||||||
|
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxItemToRemove->pvContainer = NULL;
|
||||||
|
( pxList->uxNumberOfItems )--;
|
||||||
|
|
||||||
|
return pxList->uxNumberOfItems;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.00:
|
||||||
|
|
||||||
|
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||||
|
efficient portSWITCH_CONTEXT().
|
||||||
|
+ ISR function definitions renamed to include the prv prefix.
|
||||||
|
|
||||||
|
Changes from V2.6.1
|
||||||
|
|
||||||
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
|
macro to be consistent with the later ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||||
|
* port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "portasm.h"
|
||||||
|
|
||||||
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
|
#define portTIMER_EOI_TYPE ( 8 )
|
||||||
|
#define portRESET_PIC() portOUTPUT_WORD( ( unsigned short ) 0xff22, portTIMER_EOI_TYPE )
|
||||||
|
#define portTIMER_INT_NUMBER 0x12
|
||||||
|
|
||||||
|
#define portTIMER_1_CONTROL_REGISTER ( ( unsigned short ) 0xff5e )
|
||||||
|
#define portTIMER_0_CONTROL_REGISTER ( ( unsigned short ) 0xff56 )
|
||||||
|
#define portTIMER_INTERRUPT_ENABLE ( ( unsigned short ) 0x2000 )
|
||||||
|
|
||||||
|
/* Setup the hardware to generate the required tick frequency. */
|
||||||
|
static void prvSetTickFrequency( unsigned long ulTickRateHz );
|
||||||
|
|
||||||
|
/* Set the hardware back to the state as per before the scheduler started. */
|
||||||
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
|
is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
being used. */
|
||||||
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
|
#else
|
||||||
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
being used. */
|
||||||
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Trap routine used by taskYIELD() to manually cause a context switch. */
|
||||||
|
static void __interrupt __far prvYieldProcessor( void );
|
||||||
|
|
||||||
|
/*lint -e956 File scopes necessary here. */
|
||||||
|
|
||||||
|
/* Set true when the vectors are set so the scheduler will service the tick. */
|
||||||
|
static portBASE_TYPE xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
|
/* Points to the original routine installed on the vector we use for manual
|
||||||
|
context switches. This is then used to restore the original routine during
|
||||||
|
prvExitFunction(). */
|
||||||
|
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||||
|
|
||||||
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
|
static jmp_buf xJumpBuf;
|
||||||
|
|
||||||
|
/*lint +e956 */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
|
/* Remember what was on the interrupts we are going to use
|
||||||
|
so we can put them back later if required. */
|
||||||
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
|
|
||||||
|
/* Put our manual switch (yield) function on a known
|
||||||
|
vector. */
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
{
|
||||||
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* We want the timer interrupt to just increment the tick count. */
|
||||||
|
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||||
|
|
||||||
|
/* Clean up function if we want to return to DOS. */
|
||||||
|
if( setjmp( xJumpBuf ) != 0 )
|
||||||
|
{
|
||||||
|
prvExitFunction();
|
||||||
|
xSchedulerRunning = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xSchedulerRunning = pdTRUE;
|
||||||
|
|
||||||
|
/* Kick off the scheduler by setting up the context of the first task. */
|
||||||
|
portFIRST_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSchedulerRunning;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
|
is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Switch in the context of the next task to be run. */
|
||||||
|
portSWITCH_CONTEXT();
|
||||||
|
|
||||||
|
/* Reset the PIC ready for the next time. */
|
||||||
|
portRESET_PIC();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
|
so we don't have to switch in the context of the next task. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
portRESET_PIC();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Switch in the context of the next task to be run. */
|
||||||
|
portSWITCH_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Jump back to the processor state prior to starting the
|
||||||
|
scheduler. This means we are not going to be using a
|
||||||
|
task stack frame so the task can be deleted. */
|
||||||
|
longjmp( xJumpBuf, 1 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvExitFunction( void )
|
||||||
|
{
|
||||||
|
const unsigned short usTimerDisable = 0x0000;
|
||||||
|
unsigned short usTimer0Control;
|
||||||
|
|
||||||
|
/* Interrupts should be disabled here anyway - but no
|
||||||
|
harm in making sure. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
if( xSchedulerRunning == pdTRUE )
|
||||||
|
{
|
||||||
|
/* Put back the switch interrupt routines that was in place
|
||||||
|
before the scheduler started. */
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the timer used for the tick to ensure the scheduler is
|
||||||
|
not called before restoring interrupts. There was previously nothing
|
||||||
|
on this timer so there is no old ISR to restore. */
|
||||||
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||||
|
|
||||||
|
/* Restart the DOS tick. */
|
||||||
|
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
|
||||||
|
usTimer0Control |= portTIMER_INTERRUPT_ENABLE;
|
||||||
|
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
|
||||||
|
|
||||||
|
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetTickFrequency( unsigned long ulTickRateHz )
|
||||||
|
{
|
||||||
|
const unsigned short usMaxCountRegister = 0xff5a;
|
||||||
|
const unsigned short usTimerPriorityRegister = 0xff32;
|
||||||
|
const unsigned short usTimerEnable = 0xC000;
|
||||||
|
const unsigned short usRetrigger = 0x0001;
|
||||||
|
const unsigned short usTimerHighPriority = 0x0000;
|
||||||
|
unsigned short usTimer0Control;
|
||||||
|
|
||||||
|
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||||
|
|
||||||
|
const unsigned long ulClockFrequency = ( unsigned long ) 0x7f31a0UL;
|
||||||
|
|
||||||
|
unsigned long ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||||
|
|
||||||
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||||
|
portOUTPUT_WORD( usMaxCountRegister, ( unsigned short ) ulTimerCount );
|
||||||
|
portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority );
|
||||||
|
|
||||||
|
/* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */
|
||||||
|
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
|
||||||
|
usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE;
|
||||||
|
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*lint +e950 */
|
||||||
|
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE long
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT int
|
||||||
|
#define portSTACK_TYPE unsigned portSHORT
|
||||||
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||||
|
__asm{ cli } \
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portNOP() __asm{ nop }
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portSWITCH_INT_NUMBER 0x80
|
||||||
|
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 2
|
||||||
|
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Compiler specifics. */
|
||||||
|
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||||
|
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||||
|
#define portINPUT_WORD( xAddr ) inpw( xAddr )
|
||||||
|
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.6.1
|
||||||
|
|
||||||
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
|
macro to be consistent with the later ports.
|
||||||
|
|
||||||
|
Changes from V4.0.1
|
||||||
|
|
||||||
|
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||||
|
its proper value when the scheduler exits.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "portasm.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the industrial
|
||||||
|
* PC port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
|
#define portTIMER_INT_NUMBER 0x08
|
||||||
|
|
||||||
|
/* Setup hardware for required tick interrupt rate. */
|
||||||
|
static void prvSetTickFrequency( unsigned long ulTickRateHz );
|
||||||
|
|
||||||
|
/* Restore hardware to as it was prior to starting the scheduler. */
|
||||||
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
|
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
||||||
|
directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||||
|
tick rate. */
|
||||||
|
static void prvPortResetPIC( void );
|
||||||
|
|
||||||
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
being used. */
|
||||||
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
|
#else
|
||||||
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
being used. */
|
||||||
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Trap routine used by taskYIELD() to manually cause a context switch. */
|
||||||
|
static void __interrupt __far prvYieldProcessor( void );
|
||||||
|
|
||||||
|
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||||
|
scheduler exits. */
|
||||||
|
static void prvSetTickFrequencyDefault( void );
|
||||||
|
|
||||||
|
/*lint -e956 File scopes necessary here. */
|
||||||
|
|
||||||
|
/* Used to signal when to chain to the DOS tick, and when to just clear the PIC ourselves. */
|
||||||
|
static short sDOSTickCounter;
|
||||||
|
|
||||||
|
/* Set true when the vectors are set so the scheduler will service the tick. */
|
||||||
|
static portBASE_TYPE xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
|
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
|
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||||
|
|
||||||
|
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
|
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
||||||
|
|
||||||
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
|
static jmp_buf xJumpBuf;
|
||||||
|
|
||||||
|
/*lint +e956 */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
pxISR pxOriginalTickISR;
|
||||||
|
|
||||||
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
|
/* Remember what was on the interrupts we are going to use
|
||||||
|
so we can put them back later if required. */
|
||||||
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
|
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||||
|
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||||
|
|
||||||
|
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||||
|
|
||||||
|
/* Put our manual switch (yield) function on a known
|
||||||
|
vector. */
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
|
/* Put the old tick on a different interrupt number so we can
|
||||||
|
call it when we want. */
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||||
|
|
||||||
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
{
|
||||||
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* We want the timer interrupt to just increment the tick count. */
|
||||||
|
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup a counter that is used to call the DOS interrupt as close
|
||||||
|
to it's original frequency as can be achieved given our chosen tick
|
||||||
|
frequency. */
|
||||||
|
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||||
|
|
||||||
|
/* Clean up function if we want to return to DOS. */
|
||||||
|
if( setjmp( xJumpBuf ) != 0 )
|
||||||
|
{
|
||||||
|
prvExitFunction();
|
||||||
|
xSchedulerRunning = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xSchedulerRunning = pdTRUE;
|
||||||
|
|
||||||
|
/* Kick off the scheduler by setting up the context of the first task. */
|
||||||
|
portFIRST_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSchedulerRunning;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Switch in the context of the next task to be run. */
|
||||||
|
portSWITCH_CONTEXT();
|
||||||
|
|
||||||
|
/* Reset the PIC ready for the next time. */
|
||||||
|
prvPortResetPIC();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
|
so we don't have to switch in the context of the next task. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
prvPortResetPIC();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Switch in the context of the next task to be run. */
|
||||||
|
portSWITCH_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvPortResetPIC( void )
|
||||||
|
{
|
||||||
|
/* We are going to call the DOS tick interrupt at as close a
|
||||||
|
frequency to the normal DOS tick as possible. */
|
||||||
|
|
||||||
|
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||||
|
--sDOSTickCounter;
|
||||||
|
if( sDOSTickCounter <= 0 )
|
||||||
|
{
|
||||||
|
sDOSTickCounter = ( short ) portTICKS_PER_DOS_TICK;
|
||||||
|
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset the PIC as the DOS tick is not being called to
|
||||||
|
do it. */
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
mov al, 20H
|
||||||
|
out 20H, al
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Jump back to the processor state prior to starting the
|
||||||
|
scheduler. This means we are not going to be using a
|
||||||
|
task stack frame so the task can be deleted. */
|
||||||
|
longjmp( xJumpBuf, 1 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvExitFunction( void )
|
||||||
|
{
|
||||||
|
void ( __interrupt __far *pxOriginalTickISR )();
|
||||||
|
|
||||||
|
/* Interrupts should be disabled here anyway - but no
|
||||||
|
harm in making sure. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
if( xSchedulerRunning == pdTRUE )
|
||||||
|
{
|
||||||
|
/* Set the DOS tick back onto the timer ticker. */
|
||||||
|
pxOriginalTickISR = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||||
|
_dos_setvect( portTIMER_INT_NUMBER, pxOriginalTickISR );
|
||||||
|
prvSetTickFrequencyDefault();
|
||||||
|
|
||||||
|
/* Put back the switch interrupt routines that was in place
|
||||||
|
before the scheduler started. */
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||||
|
}
|
||||||
|
/* The tick timer is back how DOS wants it. We can re-enable
|
||||||
|
interrupts without the scheduler being called. */
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetTickFrequency( unsigned long ulTickRateHz )
|
||||||
|
{
|
||||||
|
const unsigned short usPIT_MODE = ( unsigned short ) 0x43;
|
||||||
|
const unsigned short usPIT0 = ( unsigned short ) 0x40;
|
||||||
|
const unsigned long ulPIT_CONST = ( unsigned long ) 1193180UL;
|
||||||
|
const unsigned short us8254_CTR0_MODE3 = ( unsigned short ) 0x36;
|
||||||
|
unsigned long ulOutput;
|
||||||
|
|
||||||
|
/* Setup the 8245 to tick at the wanted frequency. */
|
||||||
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
|
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||||
|
portOUTPUT_BYTE( usPIT0, ( unsigned short )( ulOutput & ( unsigned long ) 0xff ) );
|
||||||
|
ulOutput >>= 8;
|
||||||
|
portOUTPUT_BYTE( usPIT0, ( unsigned short ) ( ulOutput & ( unsigned long ) 0xff ) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetTickFrequencyDefault( void )
|
||||||
|
{
|
||||||
|
const unsigned short usPIT_MODE = ( unsigned short ) 0x43;
|
||||||
|
const unsigned short usPIT0 = ( unsigned short ) 0x40;
|
||||||
|
const unsigned short us8254_CTR0_MODE3 = ( unsigned short ) 0x36;
|
||||||
|
|
||||||
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
|
portOUTPUT_BYTE( usPIT0,0 );
|
||||||
|
portOUTPUT_BYTE( usPIT0,0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*lint +e950 */
|
||||||
|
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT long
|
||||||
|
#define portDOUBLE long
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT int
|
||||||
|
#define portSTACK_TYPE unsigned portSHORT
|
||||||
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||||
|
__asm{ cli } \
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portNOP() __asm{ nop }
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portSWITCH_INT_NUMBER 0x80
|
||||||
|
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||||
|
#define portDOS_TICK_RATE ( 18.20648 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portTICKS_PER_DOS_TICK ( ( unsigned portSHORT ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
|
||||||
|
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||||
|
#define portBYTE_ALIGNMENT ( 2 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Compiler specifics. */
|
||||||
|
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||||
|
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORT_ASM_H
|
||||||
|
#define PORT_ASM_H
|
||||||
|
|
||||||
|
typedef void tskTCB;
|
||||||
|
extern volatile tskTCB * volatile pxCurrentTCB;
|
||||||
|
extern void vTaskSwitchContext( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Saves the stack pointer for one task into its TCB, calls
|
||||||
|
* vTaskSwitchContext() to update the TCB being used, then restores the stack
|
||||||
|
* from the new TCB read to run the task.
|
||||||
|
*/
|
||||||
|
void portSWITCH_CONTEXT( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the stack pointer from the TCB of the task which is going to be first
|
||||||
|
* to execute. Then force an IRET so the registers and IP are popped off the
|
||||||
|
* stack.
|
||||||
|
*/
|
||||||
|
void portFIRST_CONTEXT( void );
|
||||||
|
|
||||||
|
/* There are slightly different versions depending on whether you are building
|
||||||
|
to include debugger information. If debugger information is used then there
|
||||||
|
are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||||
|
debugger). The true stack pointer is then stored in the bp register. We add
|
||||||
|
2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||||
|
|
||||||
|
#define portSWITCH_CONTEXT() \
|
||||||
|
asm { mov ax, seg pxCurrentTCB } \
|
||||||
|
asm { mov ds, ax } \
|
||||||
|
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||||
|
asm { mov es:0x2[ bx ], ss } \
|
||||||
|
asm { mov es:[ bx ], sp } \
|
||||||
|
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||||
|
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||||
|
asm { mov ds, ax } \
|
||||||
|
asm { les bx, dword ptr pxCurrentTCB } \
|
||||||
|
asm { mov ss, es:[ bx + 2 ] } \
|
||||||
|
asm { mov sp, es:[ bx ] }
|
||||||
|
|
||||||
|
#define portFIRST_CONTEXT() \
|
||||||
|
__asm { mov ax, seg pxCurrentTCB } \
|
||||||
|
__asm { mov ds, ax } \
|
||||||
|
__asm { les bx, dword ptr pxCurrentTCB } \
|
||||||
|
__asm { mov ss, es:[ bx + 2 ] } \
|
||||||
|
__asm { mov sp, es:[ bx ] } \
|
||||||
|
__asm { pop bp } \
|
||||||
|
__asm { pop di } \
|
||||||
|
__asm { pop si } \
|
||||||
|
__asm { pop ds } \
|
||||||
|
__asm { pop es } \
|
||||||
|
__asm { pop dx } \
|
||||||
|
__asm { pop cx } \
|
||||||
|
__asm { pop bx } \
|
||||||
|
__asm { pop ax } \
|
||||||
|
__asm { iret }
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.00:
|
||||||
|
|
||||||
|
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||||
|
same format used by the compiler. This allows the compiler generated
|
||||||
|
interrupt mechanism to be used for context switches.
|
||||||
|
|
||||||
|
Changes from V2.6.1
|
||||||
|
|
||||||
|
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* See header file for description. */
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE DS_Reg = 0;
|
||||||
|
|
||||||
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is just useful for debugging. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x1111;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x2222;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x3333;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x4444;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x5555;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
||||||
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
|
/* We are going to start the scheduler using a return from interrupt
|
||||||
|
instruction to load the program counter, so first there would be the
|
||||||
|
function call with parameters preamble. */
|
||||||
|
|
||||||
|
*pxTopOfStack = FP_SEG( pvParameters );
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = FP_OFF( pvParameters );
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = FP_SEG( pxCode );
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = FP_OFF( pxCode );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Next the status register and interrupt return address. */
|
||||||
|
*pxTopOfStack = portINITIAL_SW;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = FP_SEG( pxCode );
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = FP_OFF( pxCode );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The remaining registers would be pushed on the stack by our context
|
||||||
|
switch function. These are loaded with values simply to make debugging
|
||||||
|
easier. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xAAAA; /* AX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xBBBB; /* BX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xCCCC; /* CX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xDDDD; /* DX */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xEEEE; /* ES */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* We need the true data segment. */
|
||||||
|
__asm{ MOV DS_Reg, DS };
|
||||||
|
|
||||||
|
*pxTopOfStack = DS_Reg; /* DS */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0123; /* SI */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xDDDD; /* DI */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xBBBB; /* BP */
|
||||||
|
|
||||||
|
/*lint +e950 +e611 +e923 */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Count of the critical section nesting depth. */
|
||||||
|
unsigned portLONG ulCriticalNesting = 9999;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Registers required to configure the RTI. */
|
||||||
|
#define portRTI_GCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC00 ) )
|
||||||
|
#define portRTI_TBCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC04 ) )
|
||||||
|
#define portRTI_COMPCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC0C ) )
|
||||||
|
#define portRTI_CNT0_FRC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC10 ) )
|
||||||
|
#define portRTI_CNT0_UC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC14 ) )
|
||||||
|
#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC18 ) )
|
||||||
|
#define portRTI_CNT0_COMP0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC50 ) )
|
||||||
|
#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC54 ) )
|
||||||
|
#define portRTI_SETINTENA_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC80 ) )
|
||||||
|
#define portRTI_CLEARINTENA_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC84 ) )
|
||||||
|
#define portRTI_INTFLAG_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC88 ) )
|
||||||
|
|
||||||
|
|
||||||
|
/* Constants required to set up the initial stack of each task. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1F )
|
||||||
|
#define portINITIAL_FPSCR ( ( portSTACK_TYPE ) 0x00 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0x04 )
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
|
||||||
|
/* The number of words on the stack frame between the saved Top Of Stack and
|
||||||
|
R0 (in which the parameters are passed. */
|
||||||
|
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* vPortStartFirstSTask() is defined in portASM.asm */
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||||
|
require an FPU context. */
|
||||||
|
unsigned long ulTaskHasFPUContext = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
#if __TI_VFP_SUPPORT__
|
||||||
|
{
|
||||||
|
/* Ensure the stack is correctly aligned on exit. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which is the start of the as
|
||||||
|
the task has not executed yet. The offset is added to make the return
|
||||||
|
address appear as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
#ifdef portPRELOAD_TASK_REGISTERS
|
||||||
|
{
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function parameters are passed in R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Set the status register for system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR );
|
||||||
|
|
||||||
|
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* The task will start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __TI_VFP_SUPPORT__
|
||||||
|
{
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
||||||
|
default is set to indicate that the stack frame does not include FPU
|
||||||
|
registers. */
|
||||||
|
*pxTopOfStack = pdFALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt(void)
|
||||||
|
{
|
||||||
|
/* Disable timer 0. */
|
||||||
|
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
||||||
|
|
||||||
|
/* Use the internal counter. */
|
||||||
|
portRTI_TBCTRL_REG = 0x00000000U;
|
||||||
|
|
||||||
|
/* COMPSEL0 will use the RTIFRC0 counter. */
|
||||||
|
portRTI_COMPCTRL_REG = 0x00000000U;
|
||||||
|
|
||||||
|
/* Initialise the counter and the prescale counter registers. */
|
||||||
|
portRTI_CNT0_UC0_REG = 0x00000000U;
|
||||||
|
portRTI_CNT0_FRC0_REG = 0x00000000U;
|
||||||
|
|
||||||
|
/* Set Prescalar for RTI clock. */
|
||||||
|
portRTI_CNT0_CPUC0_REG = 0x00000001U;
|
||||||
|
portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
||||||
|
portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* Clear interrupts. */
|
||||||
|
portRTI_INTFLAG_REG = 0x0007000FU;
|
||||||
|
portRTI_CLEARINTENA_REG = 0x00070F0FU;
|
||||||
|
|
||||||
|
/* Enable the compare 0 interrupt. */
|
||||||
|
portRTI_SETINTENA_REG = 0x00000001U;
|
||||||
|
portRTI_GCTRL_REG |= 0x00000001U;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler(void)
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Reset the critical section nesting count read to execute the first task. */
|
||||||
|
ulCriticalNesting = 0;
|
||||||
|
|
||||||
|
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||||
|
used. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return pdFAIL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
void vPortEndScheduler(void)
|
||||||
|
{
|
||||||
|
/* It is unlikely that the port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
* simply increment the system tick. */
|
||||||
|
__interrupt void vPortNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* clear clock interrupt flag */
|
||||||
|
RTI->INTFLAG = 0x00000001;
|
||||||
|
|
||||||
|
/* Increment the tick count - this may make a delaying task ready
|
||||||
|
to run - but a context switch is not performed. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
**************************************************************************
|
||||||
|
* The preemptive scheduler ISR is written in assembler and can be found
|
||||||
|
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
||||||
|
* is set to 1 in portmacro.h
|
||||||
|
**************************************************************************
|
||||||
|
*/
|
||||||
|
void vPortPreemptiveTick( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable interrupts, and keep a count of the nesting depth.
|
||||||
|
*/
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the critical nesting count, and if it has reached zero, re-enable
|
||||||
|
* interrupts.
|
||||||
|
*/
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > 0 )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if __TI_VFP_SUPPORT__
|
||||||
|
|
||||||
|
void vPortTaskUsesFPU( void )
|
||||||
|
{
|
||||||
|
extern void vPortInitialiseFPSCR( void );
|
||||||
|
|
||||||
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
|
FPU flag (saved as part of the task context. */
|
||||||
|
ulTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
|
/* Initialise the floating point status register. */
|
||||||
|
vPortInitialiseFPSCR();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __TI_VFP_SUPPORT__ */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
;/*
|
||||||
|
; FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ***************************************************************************
|
||||||
|
; * *
|
||||||
|
; * FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
; * Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
; * available. *
|
||||||
|
; * *
|
||||||
|
; * Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
; * ensuring you get running as quickly as possible and with an *
|
||||||
|
; * in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
; * the FreeRTOS project to continue with its mission of providing *
|
||||||
|
; * professional grade, cross platform, de facto standard solutions *
|
||||||
|
; * for microcontrollers - completely free of charge! *
|
||||||
|
; * *
|
||||||
|
; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
; * *
|
||||||
|
; * Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
; * *
|
||||||
|
; ***************************************************************************
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; This file is part of the FreeRTOS distribution.
|
||||||
|
;
|
||||||
|
; FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
; the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
; Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
; >>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
; distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
; provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
; kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
; more details. You should have received a copy of the GNU General Public
|
||||||
|
; License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
; can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
; by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
; FreeRTOS WEB site.
|
||||||
|
;
|
||||||
|
; 1 tab == 4 spaces!
|
||||||
|
;
|
||||||
|
; http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
; contact details.
|
||||||
|
;
|
||||||
|
; http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
; critical systems.
|
||||||
|
;
|
||||||
|
; http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
; licensing and training services.
|
||||||
|
;*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.arm
|
||||||
|
.ref vTaskSwitchContext
|
||||||
|
.ref vTaskIncrementTick
|
||||||
|
.ref ulTaskHasFPUContext
|
||||||
|
.ref pxCurrentTCB
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
;
|
||||||
|
; Save Task Context
|
||||||
|
;
|
||||||
|
portSAVE_CONTEXT .macro
|
||||||
|
DSB
|
||||||
|
|
||||||
|
; Push R0 as we are going to use it
|
||||||
|
STMDB SP!, {R0}
|
||||||
|
|
||||||
|
; Set R0 to point to the task stack pointer.
|
||||||
|
STMDB SP,{SP}^
|
||||||
|
SUB SP, SP, #4
|
||||||
|
LDMIA SP!,{R0}
|
||||||
|
|
||||||
|
; Push the return address onto the stack.
|
||||||
|
STMDB R0!, {LR}
|
||||||
|
|
||||||
|
; Now LR has been saved, it can be used instead of R0.
|
||||||
|
MOV LR, R0
|
||||||
|
|
||||||
|
; Pop R0 so it can be saved onto the task stack.
|
||||||
|
LDMIA SP!, {R0}
|
||||||
|
|
||||||
|
; Push all the system mode registers onto the task stack.
|
||||||
|
STMDB LR,{R0-LR}^
|
||||||
|
SUB LR, LR, #60
|
||||||
|
|
||||||
|
; Push the SPSR onto the task stack.
|
||||||
|
MRS R0, SPSR
|
||||||
|
STMDB LR!, {R0}
|
||||||
|
|
||||||
|
.if (__TI_VFP_SUPPORT__)
|
||||||
|
;Determine if the task maintains an FPU context.
|
||||||
|
LDR R0, ulFPUContextConst
|
||||||
|
LDR R0, [R0]
|
||||||
|
|
||||||
|
; Test the flag
|
||||||
|
CMP R0, #0
|
||||||
|
|
||||||
|
; If the task is not using a floating point context then skip the
|
||||||
|
; saving of the FPU registers.
|
||||||
|
BEQ PC+3
|
||||||
|
FSTMDBD LR!, {D0-D15}
|
||||||
|
FMRX R1, FPSCR
|
||||||
|
STMFD LR!, {R1}
|
||||||
|
|
||||||
|
; Save the flag
|
||||||
|
STMDB LR!, {R0}
|
||||||
|
.endif
|
||||||
|
|
||||||
|
; Store the new top of stack for the task.
|
||||||
|
LDR R0, pxCurrentTCBConst
|
||||||
|
LDR R0, [R0]
|
||||||
|
STR LR, [R0]
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
;
|
||||||
|
; Restore Task Context
|
||||||
|
;
|
||||||
|
portRESTORE_CONTEXT .macro
|
||||||
|
LDR R0, pxCurrentTCBConst
|
||||||
|
LDR R0, [R0]
|
||||||
|
LDR LR, [R0]
|
||||||
|
|
||||||
|
.if (__TI_VFP_SUPPORT__)
|
||||||
|
; The floating point context flag is the first thing on the stack.
|
||||||
|
LDR R0, ulFPUContextConst
|
||||||
|
LDMFD LR!, {R1}
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
; Test the flag
|
||||||
|
CMP R1, #0
|
||||||
|
|
||||||
|
; If the task is not using a floating point context then skip the
|
||||||
|
; VFP register loads.
|
||||||
|
BEQ PC+3
|
||||||
|
|
||||||
|
; Restore the floating point context.
|
||||||
|
LDMFD LR!, {R0}
|
||||||
|
FLDMIAD LR!, {D0-D15}
|
||||||
|
FMXR FPSCR, R0
|
||||||
|
.endif
|
||||||
|
|
||||||
|
; Get the SPSR from the stack.
|
||||||
|
LDMFD LR!, {R0}
|
||||||
|
MSR SPSR_CSXF, R0
|
||||||
|
|
||||||
|
; Restore all system mode registers for the task.
|
||||||
|
LDMFD LR, {R0-R14}^
|
||||||
|
|
||||||
|
; Restore the return address.
|
||||||
|
LDR LR, [LR, #+60]
|
||||||
|
|
||||||
|
; And return - correcting the offset in the LR to obtain the
|
||||||
|
; correct address.
|
||||||
|
SUBS PC, LR, #4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
; Start the first task by restoring its context.
|
||||||
|
|
||||||
|
.def vPortStartFirstTask
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
; Yield to another task.
|
||||||
|
|
||||||
|
.def vPortYieldProcessor
|
||||||
|
|
||||||
|
vPortYieldProcessor:
|
||||||
|
; Within an IRQ ISR the link register has an offset from the true return
|
||||||
|
; address. SWI doesn't do this. Add the offset manually so the ISR
|
||||||
|
; return code can be used.
|
||||||
|
ADD LR, LR, #4
|
||||||
|
|
||||||
|
; First save the context of the current task.
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
; Select the next task to execute. */
|
||||||
|
BL vTaskSwitchContext
|
||||||
|
|
||||||
|
; Restore the context of the task selected to execute.
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
; Yield to another task from within the FreeRTOS API
|
||||||
|
|
||||||
|
.def vPortYeildWithinAPI
|
||||||
|
|
||||||
|
vPortYeildWithinAPI:
|
||||||
|
; Save the context of the current task.
|
||||||
|
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
; Clear SSI flag.
|
||||||
|
MOVW R0, #0xFFF4
|
||||||
|
MOVT R0, #0xFFFF
|
||||||
|
LDR R0, [R0]
|
||||||
|
|
||||||
|
; Select the next task to execute. */
|
||||||
|
BL vTaskSwitchContext
|
||||||
|
|
||||||
|
; Restore the context of the task selected to execute.
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
;/*-----------------------------------------------------------*/
|
||||||
|
; Preemptive Tick
|
||||||
|
|
||||||
|
.def vPortPreemptiveTick
|
||||||
|
|
||||||
|
vPortPreemptiveTick:
|
||||||
|
|
||||||
|
; Save the context of the current task.
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
; Clear interrupt flag
|
||||||
|
MOVW R0, #0xFC88
|
||||||
|
MOVT R0, #0xFFFF
|
||||||
|
MOV R1, #1
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
; Increment the tick count, making any adjustments to the blocked lists
|
||||||
|
; that may be necessary.
|
||||||
|
BL vTaskIncrementTick
|
||||||
|
|
||||||
|
; Select the next task to execute.
|
||||||
|
BL vTaskSwitchContext
|
||||||
|
|
||||||
|
; Restore the context of the task selected to execute.
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.def ulPortCountLeadingZeros
|
||||||
|
|
||||||
|
ulPortCountLeadingZeros:
|
||||||
|
|
||||||
|
CLZ R0, R0
|
||||||
|
BX LR
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.if (__TI_VFP_SUPPORT__)
|
||||||
|
|
||||||
|
.def vPortInitialiseFPSCR
|
||||||
|
|
||||||
|
vPortInitialiseFPSCR:
|
||||||
|
|
||||||
|
MOV R0, #0
|
||||||
|
FMXR FPSCR, R0
|
||||||
|
BX LR
|
||||||
|
|
||||||
|
.endif ;__TI_VFP_SUPPORT__
|
||||||
|
|
||||||
|
|
||||||
|
pxCurrentTCBConst .word pxCurrentTCB
|
||||||
|
ulFPUContextConst .word ulTaskHasFPUContext
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PORTMACRO_H__
|
||||||
|
#define __PORTMACRO_H__
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if (configUSE_16_BIT_TICKS == 1)
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY (portTickType) 0xFFFF
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY (portTickType) 0xFFFFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH (-1)
|
||||||
|
#define portTICK_RATE_MS ((portTickType) 1000 / configTICK_RATE_HZ)
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
extern void vPortEnterCritical(void);
|
||||||
|
extern void vPortExitCritical(void);
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
#define portDISABLE_INTERRUPTS() asm( " CPSID I" )
|
||||||
|
#define portENABLE_INTERRUPTS() asm( " CPSIE I" )
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
#pragma SWI_ALIAS( vPortYield, 0 )
|
||||||
|
extern void vPortYield( void );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portSYS_SSIR1_REG ( * ( ( volatile unsigned long * ) 0xFFFFFFB0 ) )
|
||||||
|
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
||||||
|
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
||||||
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ){ portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
||||||
|
|
||||||
|
/* Architecture specific optimisations. */
|
||||||
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Generic helper function. */
|
||||||
|
unsigned long ulPortCountLeadingZeros( unsigned long ulBitmap );
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||||
|
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||||
|
|
||||||
|
#endif /* __PORTMACRO_H__ */
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
;/*
|
||||||
|
; FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ***************************************************************************
|
||||||
|
; * *
|
||||||
|
; * FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
; * Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
; * available. *
|
||||||
|
; * *
|
||||||
|
; * Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
; * ensuring you get running as quickly as possible and with an *
|
||||||
|
; * in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
; * the FreeRTOS project to continue with its mission of providing *
|
||||||
|
; * professional grade, cross platform, de facto standard solutions *
|
||||||
|
; * for microcontrollers - completely free of charge! *
|
||||||
|
; * *
|
||||||
|
; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
; * *
|
||||||
|
; * Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
; * *
|
||||||
|
; ***************************************************************************
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; This file is part of the FreeRTOS distribution.
|
||||||
|
;
|
||||||
|
; FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
; the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
; Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
; >>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
; distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
; provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
; kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
; more details. You should have received a copy of the GNU General Public
|
||||||
|
; License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
; can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
; by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
; FreeRTOS WEB site.
|
||||||
|
;
|
||||||
|
; 1 tab == 4 spaces!
|
||||||
|
;
|
||||||
|
; http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
; contact details.
|
||||||
|
;
|
||||||
|
; http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
; critical systems.
|
||||||
|
;
|
||||||
|
; http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
; licensing and training services.
|
||||||
|
;*/
|
||||||
|
|
||||||
|
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||||
|
.define "pushm.a", pushm_x
|
||||||
|
.define "popm.a", popm_x
|
||||||
|
.define "push.a", push_x
|
||||||
|
.define "pop.a", pop_x
|
||||||
|
.define "mov.a", mov_x
|
||||||
|
.else
|
||||||
|
.define "pushm.w", pushm_x
|
||||||
|
.define "popm.w", popm_x
|
||||||
|
.define "push.w", push_x
|
||||||
|
.define "pop.w", pop_x
|
||||||
|
.define "mov.w", mov_x
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.if $DEFINED( __LARGE_CODE_MODEL__ )
|
||||||
|
.define "calla", call_x
|
||||||
|
.define "reta", ret_x
|
||||||
|
.else
|
||||||
|
.define "call", call_x
|
||||||
|
.define "ret", ret_x
|
||||||
|
.endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the MSP430X port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
|
not the MCLK. */
|
||||||
|
#define portACLK_FREQUENCY_HZ ( ( portTickType ) 32768 )
|
||||||
|
#define portINITIAL_CRITICAL_NESTING ( ( unsigned short ) 10 )
|
||||||
|
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x08 )
|
||||||
|
|
||||||
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
|
any details of its type. */
|
||||||
|
typedef void tskTCB;
|
||||||
|
extern volatile tskTCB * volatile pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Each task maintains a count of the critical section nesting depth. Each
|
||||||
|
time a critical section is entered the count is incremented. Each time a
|
||||||
|
critical section is exited the count is decremented - with interrupts only
|
||||||
|
being re-enabled if the count is zero.
|
||||||
|
|
||||||
|
usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
|
not be initialised to zero as this will cause problems during the startup
|
||||||
|
sequence. */
|
||||||
|
volatile unsigned short usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
|
||||||
|
* could have alternatively used the watchdog timer or timer 1.
|
||||||
|
*/
|
||||||
|
void vPortSetupTimerInterrupt( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See the header file portable.h.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short *pusTopOfStack;
|
||||||
|
unsigned long *pulTopOfStack, ulTemp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is just useful for debugging and can be included if required.
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x3333;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||||
|
and code model used. */
|
||||||
|
if( sizeof( pxCode ) == sizeof( unsigned short ) )
|
||||||
|
{
|
||||||
|
pusTopOfStack = ( unsigned short * ) pxTopOfStack;
|
||||||
|
ulTemp = ( unsigned long ) pxCode;
|
||||||
|
*pusTopOfStack = ( unsigned short ) ulTemp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Make room for a 20 bit value stored as a 32 bit value. */
|
||||||
|
pusTopOfStack = ( unsigned short * ) pxTopOfStack;
|
||||||
|
pusTopOfStack--;
|
||||||
|
pulTopOfStack = ( unsigned long * ) pusTopOfStack;
|
||||||
|
*pulTopOfStack = ( unsigned long ) pxCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
pusTopOfStack--;
|
||||||
|
*pusTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
|
pusTopOfStack -= ( sizeof( portSTACK_TYPE ) / 2 );
|
||||||
|
|
||||||
|
/* From here on the size of stacked items depends on the memory model. */
|
||||||
|
pxTopOfStack = ( portSTACK_TYPE * ) pusTopOfStack;
|
||||||
|
|
||||||
|
/* Next the general purpose registers. */
|
||||||
|
#ifdef PRELOAD_REGISTER_VALUES
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xffff;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xeeee;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xdddd;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xbbbb;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaa;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x9999;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x8888;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x5555;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x6666;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x5555;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x4444;
|
||||||
|
pxTopOfStack--;
|
||||||
|
#else
|
||||||
|
pxTopOfStack -= 3;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack -= 9;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A variable is used to keep track of the critical section nesting.
|
||||||
|
This variable has to be stored as part of the task context and is
|
||||||
|
initially set to zero. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
|
be stored in the task control block for the task. */
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
|
disable the tick interrupt here. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initialisation to generate the RTOS tick.
|
||||||
|
*/
|
||||||
|
void vPortSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
vApplicationSetupTimerInterrupt();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma vector=configTICK_VECTOR
|
||||||
|
interrupt void vTickISREntry( void )
|
||||||
|
{
|
||||||
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
|
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
extern void vPortPreemptiveTickISR( void );
|
||||||
|
vPortPreemptiveTickISR();
|
||||||
|
#else
|
||||||
|
extern void vPortCooperativeTickISR( void );
|
||||||
|
vPortCooperativeTickISR();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
;
|
||||||
|
;/*
|
||||||
|
; FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ***************************************************************************
|
||||||
|
; * *
|
||||||
|
; * FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
; * Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
; * available. *
|
||||||
|
; * *
|
||||||
|
; * Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
; * ensuring you get running as quickly as possible and with an *
|
||||||
|
; * in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
; * the FreeRTOS project to continue with its mission of providing *
|
||||||
|
; * professional grade, cross platform, de facto standard solutions *
|
||||||
|
; * for microcontrollers - completely free of charge! *
|
||||||
|
; * *
|
||||||
|
; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
; * *
|
||||||
|
; * Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
; * *
|
||||||
|
; ***************************************************************************
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; This file is part of the FreeRTOS distribution.
|
||||||
|
;
|
||||||
|
; FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
; the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
; Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
; >>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
; distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
; provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
; kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
; more details. You should have received a copy of the GNU General Public
|
||||||
|
; License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
; can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
; by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
; FreeRTOS WEB site.
|
||||||
|
;
|
||||||
|
; 1 tab == 4 spaces!
|
||||||
|
;
|
||||||
|
; http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
; contact details.
|
||||||
|
;
|
||||||
|
; http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
; critical systems.
|
||||||
|
;
|
||||||
|
; http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
; licensing and training services.
|
||||||
|
;*/
|
||||||
|
|
||||||
|
; * The definition of the "register test" tasks, as described at the top of
|
||||||
|
; * main.c
|
||||||
|
|
||||||
|
.include data_model.h
|
||||||
|
|
||||||
|
.global vTaskIncrementTick
|
||||||
|
.global vTaskSwitchContext
|
||||||
|
.global vPortSetupTimerInterrupt
|
||||||
|
.global pxCurrentTCB
|
||||||
|
.global usCriticalNesting
|
||||||
|
|
||||||
|
.def vPortPreemptiveTickISR
|
||||||
|
.def vPortCooperativeTickISR
|
||||||
|
.def vPortYield
|
||||||
|
.def xPortStartScheduler
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
portSAVE_CONTEXT .macro
|
||||||
|
|
||||||
|
;Save the remaining registers.
|
||||||
|
pushm_x #12, r15
|
||||||
|
mov.w &usCriticalNesting, r14
|
||||||
|
push_x r14
|
||||||
|
mov_x &pxCurrentTCB, r12
|
||||||
|
mov_x sp, 0( r12 )
|
||||||
|
.endm
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
portRESTORE_CONTEXT .macro
|
||||||
|
|
||||||
|
mov_x &pxCurrentTCB, r12
|
||||||
|
mov_x @r12, sp
|
||||||
|
pop_x r15
|
||||||
|
mov.w r15, &usCriticalNesting
|
||||||
|
popm_x #12, r15
|
||||||
|
pop.w sr
|
||||||
|
ret_x
|
||||||
|
.endm
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
;*
|
||||||
|
;* The RTOS tick ISR.
|
||||||
|
;*
|
||||||
|
;* If the cooperative scheduler is in use this simply increments the tick
|
||||||
|
;* count.
|
||||||
|
;*
|
||||||
|
;* If the preemptive scheduler is in use a context switch can also occur.
|
||||||
|
;*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
vPortPreemptiveTickISR: .asmfunc
|
||||||
|
|
||||||
|
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
|
||||||
|
;to save it manually before it gets modified (interrupts get disabled).
|
||||||
|
push.w sr
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
call_x #vTaskIncrementTick
|
||||||
|
call_x #vTaskSwitchContext
|
||||||
|
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
.endasmfunc
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
vPortCooperativeTickISR: .asmfunc
|
||||||
|
|
||||||
|
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
|
||||||
|
;to save it manually before it gets modified (interrupts get disabled).
|
||||||
|
push.w sr
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
call_x #vTaskIncrementTick
|
||||||
|
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
.endasmfunc
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
;
|
||||||
|
; Manual context switch called by the portYIELD() macro.
|
||||||
|
;
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
vPortYield: .asmfunc
|
||||||
|
|
||||||
|
; The sr needs saving before it is modified.
|
||||||
|
push.w sr
|
||||||
|
|
||||||
|
; Now the SR is stacked we can disable interrupts.
|
||||||
|
dint
|
||||||
|
nop
|
||||||
|
|
||||||
|
; Save the context of the current task.
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
; Select the next task to run.
|
||||||
|
call_x #vTaskSwitchContext
|
||||||
|
|
||||||
|
; Restore the context of the new task.
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
.endasmfunc
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Start off the scheduler by initialising the RTOS tick timer, then restoring
|
||||||
|
; the context of the first task.
|
||||||
|
;
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
xPortStartScheduler: .asmfunc
|
||||||
|
|
||||||
|
; Setup the hardware to generate the tick. Interrupts are disabled
|
||||||
|
; when this function is called.
|
||||||
|
call_x #vPortSetupTimerInterrupt
|
||||||
|
|
||||||
|
; Restore the context of the first task that is going to run.
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
.endasmfunc
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Hardware includes. */
|
||||||
|
#include "msp430.h"
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT int
|
||||||
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
|
/* The stack type changes depending on the data model. */
|
||||||
|
#ifdef __LARGE_DATA_MODEL__
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#else
|
||||||
|
#define portSTACK_TYPE unsigned short
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Interrupt control macros. */
|
||||||
|
#define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop()
|
||||||
|
#define portENABLE_INTERRUPTS() _enable_interrupt()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section control macros. */
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned portSHORT ) 0 )
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned short usCriticalNesting; \
|
||||||
|
\
|
||||||
|
portDISABLE_INTERRUPTS(); \
|
||||||
|
\
|
||||||
|
/* Now interrupts are disabled usCriticalNesting can be accessed */ \
|
||||||
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
|
usCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned short usCriticalNesting; \
|
||||||
|
\
|
||||||
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
|
{ \
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */ \
|
||||||
|
usCriticalNesting--; \
|
||||||
|
\
|
||||||
|
/* If the nesting level has reached zero then interrupts should be */ \
|
||||||
|
/* re-enabled. */ \
|
||||||
|
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
|
{ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch called by portYIELD or taskYIELD.
|
||||||
|
*/
|
||||||
|
extern void vPortYield( void );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 2
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() __no_operation()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
extern void vTaskSwitchContext( void );
|
||||||
|
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
||||||
|
|
||||||
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||||
|
run time stats information is to be displayed. */
|
||||||
|
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
|
||||||
|
|
||||||
|
/* Supervisor mode set. */
|
||||||
|
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
|
||||||
|
|
||||||
|
/* The clock prescale into the timer peripheral. */
|
||||||
|
#define portPRESCALE_VALUE ( ( unsigned char ) 10 )
|
||||||
|
|
||||||
|
/* The clock frequency into the RTC. */
|
||||||
|
#define portRTC_CLOCK_HZ ( ( unsigned long ) 1000 )
|
||||||
|
|
||||||
|
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
|
will be set to 0 prior to the first task being started. */
|
||||||
|
static unsigned long ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned long ulOriginalA5;
|
||||||
|
|
||||||
|
__asm{ MOVE.L A5, ulOriginalA5 };
|
||||||
|
|
||||||
|
|
||||||
|
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Exception stack frame starts with the return address. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
|
||||||
|
pxTopOfStack -= 14; /* A5 to D0. */
|
||||||
|
|
||||||
|
/* Parameter in A0. */
|
||||||
|
*( pxTopOfStack + 8 ) = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
|
||||||
|
/* A5 must be maintained as it is resurved by the compiler. */
|
||||||
|
*( pxTopOfStack + 13 ) = ulOriginalA5;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
/* Configure a timer to generate the tick interrupt. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task executing. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Prescale by 1 - ie no prescale. */
|
||||||
|
RTCSC |= 8;
|
||||||
|
|
||||||
|
/* Compare match value. */
|
||||||
|
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||||
|
when this code executes. */
|
||||||
|
RTCSC_RTIE = 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented as there is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting == 0UL )
|
||||||
|
{
|
||||||
|
/* Guard against context switches being pended simultaneously with a
|
||||||
|
critical section being entered. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
if( INTC_FRC == 0UL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
} while( 1 );
|
||||||
|
}
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
ulCriticalNesting--;
|
||||||
|
if( ulCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldHandler( void )
|
||||||
|
{
|
||||||
|
unsigned long ulSavedInterruptMask;
|
||||||
|
|
||||||
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
INTC_CFRC = 0x3E;
|
||||||
|
vTaskSwitchContext();
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||||
|
{
|
||||||
|
unsigned long ulSavedInterruptMask;
|
||||||
|
|
||||||
|
/* Clear the interrupt. */
|
||||||
|
RTCSC |= RTCSC_RTIF_MASK;
|
||||||
|
|
||||||
|
/* Increment the RTOS tick. */
|
||||||
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
|
|
||||||
|
/* If we are using the pre-emptive scheduler then also request a
|
||||||
|
context switch as incrementing the tick could have unblocked a task. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Purpose: Lowest level routines for all ColdFire processors.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
|
||||||
|
* supplied source files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global ulPortSetIPL
|
||||||
|
.global _ulPortSetIPL
|
||||||
|
.global mcf5xxx_wr_cacrx
|
||||||
|
.global _mcf5xxx_wr_cacrx
|
||||||
|
.global vPortYieldISR
|
||||||
|
.global _vPortYieldISR
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global _vPortStartFirstTask
|
||||||
|
.extern _pxCurrentTCB
|
||||||
|
.extern _vPortYieldHandler
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.macro portSAVE_CONTEXT
|
||||||
|
|
||||||
|
lea.l (-60, sp), sp
|
||||||
|
movem.l d0-a6, (sp)
|
||||||
|
move.l _pxCurrentTCB, a0
|
||||||
|
move.l sp, (a0)
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
move.l _pxCurrentTCB, a0
|
||||||
|
move.l (a0), sp
|
||||||
|
movem.l (sp), d0-a6
|
||||||
|
lea.l (60, sp), sp
|
||||||
|
rte
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* This routines changes the IPL to the value passed into the routine.
|
||||||
|
* It also returns the old IPL value back.
|
||||||
|
* Calling convention from C:
|
||||||
|
* old_ipl = asm_set_ipl(new_ipl);
|
||||||
|
* For the Diab Data C compiler, it passes return value thru D0.
|
||||||
|
* Note that only the least significant three bits of the passed
|
||||||
|
* value are used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ulPortSetIPL:
|
||||||
|
_ulPortSetIPL:
|
||||||
|
link A6,#-8
|
||||||
|
movem.l D6-D7,(SP)
|
||||||
|
|
||||||
|
move.w SR,D7 /* current sr */
|
||||||
|
|
||||||
|
move.l D7,D6 /* prepare return value */
|
||||||
|
andi.l #0x0700,D6 /* mask out IPL */
|
||||||
|
lsr.l #8,D6 /* IPL */
|
||||||
|
|
||||||
|
andi.l #0x07,D0 /* least significant three bits */
|
||||||
|
lsl.l #8,D0 /* move over to make mask */
|
||||||
|
|
||||||
|
andi.l #0x0000F8FF,D7 /* zero out current IPL */
|
||||||
|
or.l D0,D7 /* place new IPL in sr */
|
||||||
|
move.w D7,SR
|
||||||
|
|
||||||
|
move.l D6, D0 /* Return value in D0. */
|
||||||
|
movem.l (SP),D6-D7
|
||||||
|
lea 8(SP),SP
|
||||||
|
unlk A6
|
||||||
|
rts
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
mcf5xxx_wr_cacrx:
|
||||||
|
_mcf5xxx_wr_cacrx:
|
||||||
|
move.l 4(sp),d0
|
||||||
|
.long 0x4e7b0002 /* movec d0,cacr */
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* Yield interrupt. */
|
||||||
|
_vPortYieldISR:
|
||||||
|
vPortYieldISR:
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
jsr _vPortYieldHandler
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
_vPortStartFirstTask:
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portSTACK_GROWTH -1
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned portLONG ulPortSetIPL( unsigned portLONG );
|
||||||
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
|
||||||
|
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
|
/* Context switches are requested using the force register. */
|
||||||
|
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
|
{ \
|
||||||
|
portYIELD(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
|
||||||
|
|
||||||
|
/* Supervisor mode set. */
|
||||||
|
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
|
||||||
|
|
||||||
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
|
will be set to 0 prior to the first task being started. */
|
||||||
|
static unsigned long ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
lea.l (-60, %sp), %sp; \
|
||||||
|
movem.l %d0-%fp, (%sp); \
|
||||||
|
move.l pxCurrentTCB, %a0; \
|
||||||
|
move.l %sp, (%a0);
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
move.l pxCurrentTCB, %a0; \
|
||||||
|
move.l (%a0), %sp; \
|
||||||
|
movem.l (%sp), %d0-%fp; \
|
||||||
|
lea.l %sp@(60), %sp; \
|
||||||
|
rte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Exception stack frame starts with the return address. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
|
||||||
|
pxTopOfStack -= 14; /* A5 to D0. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
/* Configure the interrupts used by this port. */
|
||||||
|
vApplicationSetupInterrupts();
|
||||||
|
|
||||||
|
/* Start the first task executing. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented as there is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting == 0UL )
|
||||||
|
{
|
||||||
|
/* Guard against context switches being pended simultaneously with a
|
||||||
|
critical section being entered. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
if( MCF_INTC0_INTFRCH == 0UL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
} while( 1 );
|
||||||
|
}
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
ulCriticalNesting--;
|
||||||
|
if( ulCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldHandler( void )
|
||||||
|
{
|
||||||
|
unsigned long ulSavedInterruptMask;
|
||||||
|
|
||||||
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
MCF_INTC0_INTFRCL = 0;
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Purpose: Lowest level routines for all ColdFire processors.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
|
||||||
|
* supplied source files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global ulPortSetIPL
|
||||||
|
.global _ulPortSetIPL
|
||||||
|
.global mcf5xxx_wr_cacrx
|
||||||
|
.global _mcf5xxx_wr_cacrx
|
||||||
|
.global vPortYieldISR
|
||||||
|
.global _vPortYieldISR
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global _vPortStartFirstTask
|
||||||
|
.extern _pxCurrentTCB
|
||||||
|
.extern _vPortYieldHandler
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.macro portSAVE_CONTEXT
|
||||||
|
|
||||||
|
lea.l (-60, sp), sp
|
||||||
|
movem.l d0-a6, (sp)
|
||||||
|
move.l _pxCurrentTCB, a0
|
||||||
|
move.l sp, (a0)
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
move.l _pxCurrentTCB, a0
|
||||||
|
move.l (a0), sp
|
||||||
|
movem.l (sp), d0-a6
|
||||||
|
lea.l (60, sp), sp
|
||||||
|
rte
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* This routines changes the IPL to the value passed into the routine.
|
||||||
|
* It also returns the old IPL value back.
|
||||||
|
* Calling convention from C:
|
||||||
|
* old_ipl = asm_set_ipl(new_ipl);
|
||||||
|
* For the Diab Data C compiler, it passes return value thru D0.
|
||||||
|
* Note that only the least significant three bits of the passed
|
||||||
|
* value are used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ulPortSetIPL:
|
||||||
|
_ulPortSetIPL:
|
||||||
|
link A6,#-8
|
||||||
|
movem.l D6-D7,(SP)
|
||||||
|
|
||||||
|
move.w SR,D7 /* current sr */
|
||||||
|
|
||||||
|
move.l D7,D0 /* prepare return value */
|
||||||
|
andi.l #0x0700,D0 /* mask out IPL */
|
||||||
|
lsr.l #8,D0 /* IPL */
|
||||||
|
|
||||||
|
move.l 8(A6),D6 /* get argument */
|
||||||
|
andi.l #0x07,D6 /* least significant three bits */
|
||||||
|
lsl.l #8,D6 /* move over to make mask */
|
||||||
|
|
||||||
|
andi.l #0x0000F8FF,D7 /* zero out current IPL */
|
||||||
|
or.l D6,D7 /* place new IPL in sr */
|
||||||
|
move.w D7,SR
|
||||||
|
|
||||||
|
movem.l (SP),D6-D7
|
||||||
|
lea 8(SP),SP
|
||||||
|
unlk A6
|
||||||
|
rts
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
mcf5xxx_wr_cacrx:
|
||||||
|
_mcf5xxx_wr_cacrx:
|
||||||
|
move.l 4(sp),d0
|
||||||
|
.long 0x4e7b0002 /* movec d0,cacr */
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* Yield interrupt. */
|
||||||
|
_vPortYieldISR:
|
||||||
|
vPortYieldISR:
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
jsr _vPortYieldHandler
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
_vPortStartFirstTask:
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portSTACK_GROWTH -1
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
unsigned portLONG ulPortSetIPL( unsigned portLONG );
|
||||||
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
|
||||||
|
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
|
{ \
|
||||||
|
portYIELD(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure a timer to generate the RTOS tick at the frequency specified
|
||||||
|
* within FreeRTOSConfig.h.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||||
|
scheduler startup function. */
|
||||||
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||||
|
|
||||||
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
|
void interrupt vPortYield( void );
|
||||||
|
|
||||||
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
|
void interrupt vPortTickInterrupt( void );
|
||||||
|
|
||||||
|
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||||
|
start the scheduler directly because the header file containing the
|
||||||
|
xPortStartScheduler() prototype is part of the common kernel code, and
|
||||||
|
therefore cannot use the CODE_SEG pragma. */
|
||||||
|
static portBASE_TYPE xBankedStartScheduler( void );
|
||||||
|
|
||||||
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
|
critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
|
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
|
depth. Each task maintains it's own critical nesting depth variable so
|
||||||
|
uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
|
switch. */
|
||||||
|
volatile unsigned portBASE_TYPE uxCriticalNesting = 0xff;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This can be uncommented to provide useful stack markers when debugging.
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x22;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x33;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
|
expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
|
||||||
|
/* Y register */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xff;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xee;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* X register */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xdd;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xcc;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* A register contains parameter high byte. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* B register contains parameter low byte. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
|
"I" bit of CCR is cleared */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
#ifdef BANKED_MODEL
|
||||||
|
/* The page of the task. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ( int ) pxCode );
|
||||||
|
pxTopOfStack--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||||
|
a critical section). */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the HCS12 port will get stopped. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
TickTimer_SetFreqHz( configTICK_RATE_HZ );
|
||||||
|
TickTimer_Enable();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
|
the header file containing the xPortStartScheduler() prototype is part
|
||||||
|
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
|
Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||||
|
which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
|
return xBankedStartScheduler();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||||
|
|
||||||
|
static portBASE_TYPE xBankedStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
|
disabled when this function is called. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Restore the context of the first task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
/* Simulate the end of an interrupt to start the scheduler off. */
|
||||||
|
__asm( "rti" );
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context switch functions. These are both interrupt service routines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch forced by calling portYIELD(). This is the SWI
|
||||||
|
* handler.
|
||||||
|
*/
|
||||||
|
void interrupt vPortYield( void )
|
||||||
|
{
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTOS tick interrupt service routine. If the cooperative scheduler is
|
||||||
|
* being used then this simply increments the tick count. If the
|
||||||
|
* preemptive scheduler is being used a context switch can occur.
|
||||||
|
*/
|
||||||
|
void interrupt vPortTickInterrupt( void )
|
||||||
|
{
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
{
|
||||||
|
/* A context switch might happen so save the context. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the tick ... */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* ... then see if the new tick value has necessitated a
|
||||||
|
context switch. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
TFLG1 = 1;
|
||||||
|
|
||||||
|
/* Restore the context of a task - which may be a different task
|
||||||
|
to that interrupted. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
TFLG1 = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portCHAR
|
||||||
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 1
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portYIELD() __asm( "swi" );
|
||||||
|
#define portNOP() __asm( "nop" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable interrupts before incrementing the count of critical section nesting.
|
||||||
|
* The nesting count is maintained so we know when interrupts should be
|
||||||
|
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
||||||
|
* directly. Each task maintains its own nesting count.
|
||||||
|
*/
|
||||||
|
#define portENTER_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
portDISABLE_INTERRUPTS(); \
|
||||||
|
uxCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
|
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
||||||
|
* section and interrupts can be re-enabled.
|
||||||
|
*/
|
||||||
|
#define portEXIT_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
uxCriticalNesting--; \
|
||||||
|
if( uxCriticalNesting == 0 ) \
|
||||||
|
{ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are very simple as the processor automatically saves and
|
||||||
|
* restores its registers as interrupts are entered and exited. In
|
||||||
|
* addition to the (automatically stacked) registers we also stack the
|
||||||
|
* critical nesting count. Each task maintains its own critical nesting
|
||||||
|
* count as it is legitimate for a task to yield from within a critical
|
||||||
|
* section. If the banked memory model is being used then the PPAGE
|
||||||
|
* register is also stored as part of the tasks context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef BANKED_MODEL
|
||||||
|
/*
|
||||||
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
|
* count and PPAGE register from the stack. The remains of the
|
||||||
|
* context are restored by the RTI instruction.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
|
__asm( "lds 0, x" ); \
|
||||||
|
__asm( "pula" ); \
|
||||||
|
__asm( "staa uxCriticalNesting" ); \
|
||||||
|
__asm( "pula" ); \
|
||||||
|
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By the time this macro is called the processor has already stacked the
|
||||||
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
|
* the task stack pointer.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
|
__asm( "psha" ); \
|
||||||
|
__asm( "ldaa uxCriticalNesting" ); \
|
||||||
|
__asm( "psha" ); \
|
||||||
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
|
__asm( "sts 0, x" ); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
|
* and restoring the PPAGE register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
|
__asm( "lds 0, x" ); \
|
||||||
|
__asm( "pula" ); \
|
||||||
|
__asm( "staa uxCriticalNesting" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
__asm( "ldaa uxCriticalNesting" ); \
|
||||||
|
__asm( "psha" ); \
|
||||||
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
|
__asm( "sts 0, x" ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
* task switch from within a standard ISR. This macro can only be used if
|
||||||
|
* the ISR does not use any local (stack) variables. If the ISR uses stack
|
||||||
|
* variables portYIELD() should be used in it's place.
|
||||||
|
*/
|
||||||
|
#define portTASK_SWITCH_FROM_ISR() \
|
||||||
|
portSAVE_CONTEXT(); \
|
||||||
|
vTaskSwitchContext(); \
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||||
|
* port.
|
||||||
|
*
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode are contained in portISR.c.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Hardware specific definitions. */
|
||||||
|
#include "AT91R40008.h"
|
||||||
|
#include "pio.h"
|
||||||
|
#include "aic.h"
|
||||||
|
#include "tc.h"
|
||||||
|
|
||||||
|
/* Constants required to setup the task context. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
|
||||||
|
#define portTICK_PRIORITY_6 ( 6 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, so
|
||||||
|
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||||
|
*/
|
||||||
|
extern void vPortISRStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
|
is not really required. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which in this case is the
|
||||||
|
start of the task. The offset is added to make the return address appear
|
||||||
|
as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
|
system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
{
|
||||||
|
/* We want the task to start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
|
instead be stored in a variable, which is then saved as part of the
|
||||||
|
tasks context. */
|
||||||
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortISRStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the tick timer to generate the tick interrupts at the required frequency.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
volatile unsigned long ulDummy;
|
||||||
|
|
||||||
|
/* Enable clock to the tick timer... */
|
||||||
|
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||||
|
|
||||||
|
/* Stop the tick timer... */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_CCR = TC_CLKDIS;
|
||||||
|
|
||||||
|
/* Start with tick timer interrupts disabled... */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* Clear any pending tick timer interrupts... */
|
||||||
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
|
/* Store interrupt handler function address in tick timer vector register...
|
||||||
|
The ISR installed depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
{
|
||||||
|
extern void ( vPreemptiveTick )( void );
|
||||||
|
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( unsigned long ) vPreemptiveTick;
|
||||||
|
}
|
||||||
|
#else // else use cooperative scheduler
|
||||||
|
{
|
||||||
|
extern void ( vNonPreemptiveTick )( void );
|
||||||
|
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( unsigned long ) vNonPreemptiveTick;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Tick timer interrupt level-sensitive, priority 6... */
|
||||||
|
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||||
|
|
||||||
|
/* Enable the tick timer interrupt...
|
||||||
|
|
||||||
|
First at timer level */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||||
|
|
||||||
|
/* Then at the AIC level. */
|
||||||
|
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
||||||
|
|
||||||
|
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||||
|
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
||||||
|
{
|
||||||
|
/* The tick rate is fast enough for us to use the faster timer input
|
||||||
|
clock (main clock / 2). */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We must use a slower timer input clock (main clock / 8) because the
|
||||||
|
tick rate is too slow for the faster input clock. */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start tick timer... */
|
||||||
|
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode, are contained in this file.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to handle interrupts. */
|
||||||
|
#define portCLEAR_AIC_INTERRUPT ( ( unsigned long ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
* function here.
|
||||||
|
*/
|
||||||
|
void vPortISRStartFirstTask( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRStartFirstTask( void )
|
||||||
|
{
|
||||||
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
|
called from ARM mode. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
|
*
|
||||||
|
* When a context switch is performed from the task level the saved task
|
||||||
|
* context is made to look as if it occurred from within the tick ISR. This
|
||||||
|
* way the same restore context function can be used when restoring the context
|
||||||
|
* saved from the ISR or that saved from a call to vPortYieldProcessor.
|
||||||
|
*/
|
||||||
|
void vPortYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
|
ISR return code can be used in both cases. */
|
||||||
|
asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
simply increment the system tick. */
|
||||||
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
|
void vNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
static volatile unsigned long ulDummy;
|
||||||
|
|
||||||
|
/* Clear tick timer interrupt indication. */
|
||||||
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Acknowledge the interrupt at AIC level... */
|
||||||
|
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* else preemption is turned on */
|
||||||
|
|
||||||
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
|
saved on entry as part of the context switch. */
|
||||||
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
|
void vPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||||
|
if you must! */
|
||||||
|
static volatile unsigned long ulDummy;
|
||||||
|
|
||||||
|
/* Clear tick timer interrupt indication. */
|
||||||
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
|
task that is ready to run. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Acknowledge the interrupt at AIC level... */
|
||||||
|
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions here to
|
||||||
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
|
*/
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
|
in a variable, which is then saved as part of the stack context. */
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V3.2.3
|
||||||
|
|
||||||
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
|
replaced them with hard coded registers. This will ensure the
|
||||||
|
assembler does not select the link register as the temp register as
|
||||||
|
was occasionally happening previously.
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
|
||||||
|
Changes from V4.5.0
|
||||||
|
|
||||||
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
|
macros as per the V4.5.1 demo code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portYIELD() asm volatile ( "SWI 0" )
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These define the timer to use for generating the tick interrupt.
|
||||||
|
* They are put in this file so they can be shared between "port.c"
|
||||||
|
* and "portisr.c".
|
||||||
|
*/
|
||||||
|
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
||||||
|
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
||||||
|
#define portTIMER_AIC_CHANNEL ( ( unsigned portLONG ) 4 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||||
|
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||||
|
* are included here for efficiency. An attempt to call one from
|
||||||
|
* THUMB mode code will result in a compile time error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Set the LR to the task stack. */ \
|
||||||
|
asm volatile ( \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"LDR LR, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
|
"STR R1, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* Get the SPSR from the stack. */ \
|
||||||
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
|
"MSR SPSR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore all system mode registers for the task. */ \
|
||||||
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore the return address. */ \
|
||||||
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
|
\
|
||||||
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
|
/* correct address. */ \
|
||||||
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Push R0 as we are going to use the register. */ \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB SP, SP, #4 \n\t" \
|
||||||
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the return address onto the stack. */ \
|
||||||
|
"STMDB R0!, {LR} \n\t" \
|
||||||
|
\
|
||||||
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
|
"MOV LR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB LR, LR, #60 \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the SPSR onto the task stack. */ \
|
||||||
|
"MRS R0, SPSR \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Store the new top of stack for the task. */ \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STR LR, [R0] \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions in
|
||||||
|
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
|
||||||
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
+4698
File diff suppressed because it is too large
Load Diff
+51
@@ -0,0 +1,51 @@
|
|||||||
|
//* ----------------------------------------------------------------------------
|
||||||
|
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||||
|
//* ----------------------------------------------------------------------------
|
||||||
|
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//* ----------------------------------------------------------------------------
|
||||||
|
//* File Name : lib_AT91SAM7X256.h
|
||||||
|
//* Object : AT91SAM7X256 inlined functions
|
||||||
|
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
|
||||||
|
//*
|
||||||
|
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
|
||||||
|
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
|
||||||
|
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
|
||||||
|
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
|
||||||
|
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
|
||||||
|
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
|
||||||
|
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
|
||||||
|
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
|
||||||
|
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
|
||||||
|
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
|
||||||
|
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
|
||||||
|
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
|
||||||
|
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
|
||||||
|
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
|
||||||
|
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
|
||||||
|
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
|
||||||
|
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
|
||||||
|
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
|
||||||
|
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
|
||||||
|
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
|
||||||
|
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
|
||||||
|
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
||||||
|
//* ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
|
||||||
|
//*----------------------------------------------------------------------------
|
||||||
|
//* \fn AT91F_AIC_ConfigureIt
|
||||||
|
//* \brief Interrupt Handler Initialization
|
||||||
|
//*----------------------------------------------------------------------------
|
||||||
|
|
||||||
+4558
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
|
*
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode are contained in portISR.c.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Processor constants. */
|
||||||
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
/* Constants required to setup the task context. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to setup the tick ISR. */
|
||||||
|
#define portENABLE_TIMER ( ( unsigned char ) 0x01 )
|
||||||
|
#define portPRESCALE_VALUE 0x00
|
||||||
|
#define portINTERRUPT_ON_MATCH ( ( unsigned long ) 0x01 )
|
||||||
|
#define portRESET_COUNT_ON_MATCH ( ( unsigned long ) 0x02 )
|
||||||
|
|
||||||
|
/* Constants required to setup the PIT. */
|
||||||
|
#define portPIT_CLOCK_DIVISOR ( ( unsigned long ) 16 )
|
||||||
|
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
|
||||||
|
|
||||||
|
#define portINT_LEVEL_SENSITIVE 0
|
||||||
|
#define portPIT_ENABLE ( ( unsigned short ) 0x1 << 24 )
|
||||||
|
#define portPIT_INT_ENABLE ( ( unsigned short ) 0x1 << 25 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, so
|
||||||
|
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||||
|
*/
|
||||||
|
extern void vPortISRStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
|
is not really required. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which in this case is the
|
||||||
|
start of the task. The offset is added to make the return address appear
|
||||||
|
as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
|
system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
{
|
||||||
|
/* We want the task to start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
|
instead be stored in a variable, which is then saved as part of the
|
||||||
|
tasks context. */
|
||||||
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortISRStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||||
|
|
||||||
|
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||||
|
on whether the preemptive or cooperative scheduler is being used. */
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
extern void ( vNonPreemptiveTick ) ( void );
|
||||||
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern void ( vPreemptiveTick )( void );
|
||||||
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configure the PIT period. */
|
||||||
|
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||||
|
|
||||||
|
/* Enable the interrupt. Global interrupts are disables at this point so
|
||||||
|
this is safe. */
|
||||||
|
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode, are contained in this file.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
/* Constants required to handle interrupts. */
|
||||||
|
#define portTIMER_MATCH_ISR_BIT ( ( unsigned char ) 0x01 )
|
||||||
|
#define portCLEAR_VIC_INTERRUPT ( ( unsigned long ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
* function here.
|
||||||
|
*/
|
||||||
|
void vPortISRStartFirstTask( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRStartFirstTask( void )
|
||||||
|
{
|
||||||
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
|
called from ARM mode. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
|
*
|
||||||
|
* When a context switch is performed from the task level the saved task
|
||||||
|
* context is made to look as if it occurred from within the tick ISR. This
|
||||||
|
* way the same restore context function can be used when restoring the context
|
||||||
|
* saved from the ISR or that saved from a call to vPortYieldProcessor.
|
||||||
|
*/
|
||||||
|
void vPortYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
|
ISR return code can be used in both cases. */
|
||||||
|
asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
simply increment the system tick. */
|
||||||
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
|
void vNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
unsigned long ulDummy;
|
||||||
|
|
||||||
|
/* Increment the tick count - which may wake some tasks but as the
|
||||||
|
preemptive scheduler is not being used any woken task is not given
|
||||||
|
processor time no matter what its priority. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Clear the PIT interrupt. */
|
||||||
|
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
|
||||||
|
|
||||||
|
/* End the interrupt in the AIC. */
|
||||||
|
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
|
saved on entry as part of the context switch. */
|
||||||
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
|
void vPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the tick count - this may wake a task. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* End the interrupt in the AIC. */
|
||||||
|
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;
|
||||||
|
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions here to
|
||||||
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
|
*/
|
||||||
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
|
in a variable, which is then saved as part of the stack context. */
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V3.2.3
|
||||||
|
|
||||||
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
|
replaced them with hard coded registers. This will ensure the
|
||||||
|
assembler does not select the link register as the temp register as
|
||||||
|
was occasionally happening previously.
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
|
||||||
|
Changes from V4.5.0
|
||||||
|
|
||||||
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
|
macros as per the V4.5.1 demo code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP() asm volatile ( "NOP" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||||
|
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||||
|
* are included here for efficiency. An attempt to call one from
|
||||||
|
* THUMB mode code will result in a compile time error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Set the LR to the task stack. */ \
|
||||||
|
asm volatile ( \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"LDR LR, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
|
"STR R1, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* Get the SPSR from the stack. */ \
|
||||||
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
|
"MSR SPSR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore all system mode registers for the task. */ \
|
||||||
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore the return address. */ \
|
||||||
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
|
\
|
||||||
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
|
/* correct address. */ \
|
||||||
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Push R0 as we are going to use the register. */ \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB SP, SP, #4 \n\t" \
|
||||||
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the return address onto the stack. */ \
|
||||||
|
"STMDB R0!, {LR} \n\t" \
|
||||||
|
\
|
||||||
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
|
"MOV LR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB LR, LR, #60 \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the SPSR onto the task stack. */ \
|
||||||
|
"MRS R0, SPSR \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Store the new top of stack for the task. */ \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STR LR, [R0] \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
#define portYIELD() asm volatile ( "SWI 0" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions in
|
||||||
|
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
|
||||||
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
|
*
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode are contained in portISR.c.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to setup the task context. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to setup the tick ISR. */
|
||||||
|
#define portENABLE_TIMER ( ( unsigned char ) 0x01 )
|
||||||
|
#define portPRESCALE_VALUE 0x00
|
||||||
|
#define portINTERRUPT_ON_MATCH ( ( unsigned long ) 0x01 )
|
||||||
|
#define portRESET_COUNT_ON_MATCH ( ( unsigned long ) 0x02 )
|
||||||
|
|
||||||
|
/* Constants required to setup the VIC for the tick ISR. */
|
||||||
|
#define portTIMER_VIC_CHANNEL ( ( unsigned long ) 0x0004 )
|
||||||
|
#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned long ) 0x0010 )
|
||||||
|
#define portTIMER_VIC_ENABLE ( ( unsigned long ) 0x0020 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, so
|
||||||
|
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||||
|
*/
|
||||||
|
extern void vPortISRStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
|
is not really required. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which in this case is the
|
||||||
|
start of the task. The offset is added to make the return address appear
|
||||||
|
as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
|
system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||||
|
|
||||||
|
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* We want the task to start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
|
instead be stored in a variable, which is then saved as part of the
|
||||||
|
tasks context. */
|
||||||
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortISRStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
unsigned long ulCompareMatch;
|
||||||
|
extern void ( vTickISR )( void );
|
||||||
|
|
||||||
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
|
defaulted to zero but can be used if necessary. */
|
||||||
|
T0_PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
|
in a warning - hence the #if. */
|
||||||
|
#if portPRESCALE_VALUE != 0
|
||||||
|
{
|
||||||
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
T0_MR0 = ulCompareMatch;
|
||||||
|
|
||||||
|
/* Generate tick with timer 0 compare match. */
|
||||||
|
T0_MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
|
||||||
|
|
||||||
|
/* Setup the VIC for the timer. */
|
||||||
|
VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
|
||||||
|
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||||
|
|
||||||
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
|
||||||
|
VICVectAddr0 = ( long ) vTickISR;
|
||||||
|
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||||
|
|
||||||
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
|
so it is okay to do this here. */
|
||||||
|
T0_TCR = portENABLE_TIMER;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode, are contained in this file.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.5.2
|
||||||
|
|
||||||
|
+ The critical section management functions have been changed. These no
|
||||||
|
longer modify the stack and are safe to use at all optimisation levels.
|
||||||
|
The functions are now also the same for both ARM and THUMB modes.
|
||||||
|
|
||||||
|
Changes from V2.6.0
|
||||||
|
|
||||||
|
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||||
|
allow the demo to link when using the cooperative scheduler.
|
||||||
|
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* Constants required to handle interrupts. */
|
||||||
|
#define portTIMER_MATCH_ISR_BIT ( ( unsigned char ) 0x01 )
|
||||||
|
#define portCLEAR_VIC_INTERRUPT ( ( unsigned long ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
* function here.
|
||||||
|
*/
|
||||||
|
void vPortISRStartFirstTask( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRStartFirstTask( void )
|
||||||
|
{
|
||||||
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
|
called from ARM mode. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
|
*
|
||||||
|
* When a context switch is performed from the task level the saved task
|
||||||
|
* context is made to look as if it occurred from within the tick ISR. This
|
||||||
|
* way the same restore context function can be used when restoring the context
|
||||||
|
* saved from the ISR or that saved from a call to vPortYieldProcessor.
|
||||||
|
*/
|
||||||
|
void vPortYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
|
ISR return code can be used in both cases. */
|
||||||
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
__asm volatile ( "bl vTaskSwitchContext" );
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick.
|
||||||
|
*/
|
||||||
|
void vTickISR( void ) __attribute__((naked));
|
||||||
|
void vTickISR( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
|
task that is ready to run. */
|
||||||
|
__asm volatile( "bl vTaskIncrementTick" );
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
__asm volatile( "bl vTaskSwitchContext" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ready for the next interrupt. */
|
||||||
|
T0_IR = portTIMER_MATCH_ISR_BIT;
|
||||||
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions here to
|
||||||
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
|
*/
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
|
in a variable, which is then saved as part of the stack context. */
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||||
|
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||||
|
* are included here for efficiency. An attempt to call one from
|
||||||
|
* THUMB mode code will result in a compile time error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Set the LR to the task stack. */ \
|
||||||
|
__asm volatile ( \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"LDR LR, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
|
"STR R1, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* Get the SPSR from the stack. */ \
|
||||||
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
|
"MSR SPSR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore all system mode registers for the task. */ \
|
||||||
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore the return address. */ \
|
||||||
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
|
\
|
||||||
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
|
/* correct address. */ \
|
||||||
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Push R0 as we are going to use the register. */ \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB SP, SP, #4 \n\t" \
|
||||||
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the return address onto the stack. */ \
|
||||||
|
"STMDB R0!, {LR} \n\t" \
|
||||||
|
\
|
||||||
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
|
"MOV LR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB LR, LR, #60 \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the SPSR onto the task stack. */ \
|
||||||
|
"MRS R0, SPSR \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Store the new top of stack for the task. */ \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STR LR, [R0] \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void vTaskSwitchContext( void );
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions in
|
||||||
|
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
|
||||||
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
|
*
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode are contained in portISR.c.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to setup the task context. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to setup the tick ISR. */
|
||||||
|
#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
|
||||||
|
#define portPRESCALE_VALUE 0x00
|
||||||
|
#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
|
||||||
|
#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
|
||||||
|
|
||||||
|
/* Constants required to setup the VIC for the tick ISR. */
|
||||||
|
#define portTIMER_VIC_CHANNEL ( ( unsigned portLONG ) 0x0004 )
|
||||||
|
#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned portLONG ) 0x0010 )
|
||||||
|
#define portTIMER_VIC_ENABLE ( ( unsigned portLONG ) 0x0020 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, so
|
||||||
|
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||||
|
*/
|
||||||
|
extern void vPortISRStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
|
is not really required. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which in this case is the
|
||||||
|
start of the task. The offset is added to make the return address appear
|
||||||
|
as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
|
system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||||
|
|
||||||
|
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* We want the task to start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
|
instead be stored in a variable, which is then saved as part of the
|
||||||
|
tasks context. */
|
||||||
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortISRStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
unsigned portLONG ulCompareMatch;
|
||||||
|
|
||||||
|
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
||||||
|
T0TCR = 2; /* Stop and reset the timer */
|
||||||
|
T0CTCR = 0; /* Timer mode */
|
||||||
|
|
||||||
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
|
defaulted to zero but can be used if necessary. */
|
||||||
|
T0PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
|
in a warning - hence the #if. */
|
||||||
|
#if portPRESCALE_VALUE != 0
|
||||||
|
{
|
||||||
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
T0MR1 = ulCompareMatch;
|
||||||
|
|
||||||
|
/* Generate tick with timer 0 compare match. */
|
||||||
|
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
||||||
|
|
||||||
|
/* Setup the VIC for the timer. */
|
||||||
|
VICIntEnable = 0x00000010;
|
||||||
|
|
||||||
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
|
scheduler is being used. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
{
|
||||||
|
extern void ( vPreemptiveTick )( void );
|
||||||
|
VICVectAddr4 = ( portLONG ) vPreemptiveTick;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
extern void ( vNonPreemptiveTick )( void );
|
||||||
|
VICVectAddr4 = ( portLONG ) vNonPreemptiveTick;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VICVectCntl4 = 1;
|
||||||
|
|
||||||
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
|
so it is okay to do this here. */
|
||||||
|
T0TCR = portENABLE_TIMER;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode, are contained in this file.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to handle interrupts. */
|
||||||
|
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
|
||||||
|
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||||
|
volatile unsigned portLONG ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
* function here.
|
||||||
|
*/
|
||||||
|
void vPortISRStartFirstTask( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRStartFirstTask( void )
|
||||||
|
{
|
||||||
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
|
called from ARM mode. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
|
*
|
||||||
|
* When a context switch is performed from the task level the saved task
|
||||||
|
* context is made to look as if it occurred from within the tick ISR. This
|
||||||
|
* way the same restore context function can be used when restoring the context
|
||||||
|
* saved from the ISR or that saved from a call to vPortYieldProcessor.
|
||||||
|
*/
|
||||||
|
void vPortYieldProcessor( void )
|
||||||
|
{
|
||||||
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
|
ISR return code can be used in both cases. */
|
||||||
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
__asm volatile( "bl vTaskSwitchContext" );
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
simply increment the system tick. */
|
||||||
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
|
void vNonPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
T0IR = 2;
|
||||||
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
|
saved on entry as part of the context switch. */
|
||||||
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
|
void vPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
|
task that is ready to run. */
|
||||||
|
__asm volatile( "bl vTaskIncrementTick" );
|
||||||
|
__asm volatile( "bl vTaskSwitchContext" );
|
||||||
|
|
||||||
|
/* Ready for the next interrupt. */
|
||||||
|
T0IR = 2;
|
||||||
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions here to
|
||||||
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
|
*/
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
|
in a variable, which is then saved as part of the stack context. */
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
|
__asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V3.2.3
|
||||||
|
|
||||||
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
|
||||||
|
Changes from V3.2.4
|
||||||
|
|
||||||
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
|
replaced them with hard coded registers. This will ensure the
|
||||||
|
assembler does not select the link register as the temp register as
|
||||||
|
was occasionally happening previously.
|
||||||
|
|
||||||
|
+ The assembler statements are now included in a single asm block rather
|
||||||
|
than each line having its own asm block.
|
||||||
|
|
||||||
|
Changes from V4.5.0
|
||||||
|
|
||||||
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
|
macros as per the V4.5.1 demo code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||||
|
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||||
|
* are included here for efficiency. An attempt to call one from
|
||||||
|
* THUMB mode code will result in a compile time error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Set the LR to the task stack. */ \
|
||||||
|
__asm volatile ( \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"LDR LR, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
|
"STR R1, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* Get the SPSR from the stack. */ \
|
||||||
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
|
"MSR SPSR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore all system mode registers for the task. */ \
|
||||||
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore the return address. */ \
|
||||||
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
|
\
|
||||||
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
|
/* correct address. */ \
|
||||||
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
\
|
||||||
|
/* Push R0 as we are going to use the register. */ \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB SP, SP, #4 \n\t" \
|
||||||
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the return address onto the stack. */ \
|
||||||
|
"STMDB R0!, {LR} \n\t" \
|
||||||
|
\
|
||||||
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
|
"MOV LR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
"SUB LR, LR, #60 \n\t" \
|
||||||
|
\
|
||||||
|
/* Push the SPSR onto the task stack. */ \
|
||||||
|
"MRS R0, SPSR \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STMDB LR!, {R0} \n\t" \
|
||||||
|
\
|
||||||
|
/* Store the new top of stack for the task. */ \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"STR LR, [R0] \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) ulCriticalNesting; \
|
||||||
|
( void ) pxCurrentTCB; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions in
|
||||||
|
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
|
||||||
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( \
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to manipulate the NVIC. */
|
||||||
|
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
|
||||||
|
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
|
||||||
|
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
|
||||||
|
#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
|
||||||
|
#define portNVIC_SYSTICK_CLK 0x00000004
|
||||||
|
#define portNVIC_SYSTICK_INT 0x00000002
|
||||||
|
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
||||||
|
#define portNVIC_PENDSVSET 0x10000000
|
||||||
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
|
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||||
|
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||||
|
|
||||||
|
/* Constants required to set up the initial stack. */
|
||||||
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
|
#if configUSE_CUSTOM_TICK == 0
|
||||||
|
/*
|
||||||
|
* Setup the timer to generate the tick interrupts.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception handlers.
|
||||||
|
*/
|
||||||
|
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
||||||
|
void xPortSysTickHandler( void );
|
||||||
|
void vPortSVCHandler( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
|
*/
|
||||||
|
static void vPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
|
interrupt. */
|
||||||
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||||
|
pxTopOfStack -= 6; /* LR, R12, R3..R1 */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack -= 8; /* R11..R4. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSVCHandler( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||||
|
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" add r0, r0, #16 \n" /* Move to the high registers. */
|
||||||
|
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
||||||
|
" mov r8, r4 \n"
|
||||||
|
" mov r9, r5 \n"
|
||||||
|
" mov r10, r6 \n"
|
||||||
|
" mov r11, r7 \n"
|
||||||
|
" \n"
|
||||||
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
|
" \n"
|
||||||
|
" sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
||||||
|
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
||||||
|
" mov r1, r14 \n" /* OR R14 with 0x0d. */
|
||||||
|
" movs r0, #0x0d \n"
|
||||||
|
" orr r1, r0 \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortStartFirstTask( void )
|
||||||
|
{
|
||||||
|
__asm volatile(
|
||||||
|
" movs r0, #0x00 \n" /* Locate the top of stack. */
|
||||||
|
" ldr r0, [r0] \n"
|
||||||
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" svc 0 \n" /* System call to start first task. */
|
||||||
|
" nop \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
|
||||||
|
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
|
||||||
|
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
|
#if configUSE_CUSTOM_TICK == 0
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
uxCriticalNesting = 0;
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the CM0 port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldFromISR( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
uxCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
uxCriticalNesting--;
|
||||||
|
if( uxCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xPortPendSVHandler( void )
|
||||||
|
{
|
||||||
|
/* This is a naked function. */
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
|
" ldr r2, [r3] \n"
|
||||||
|
" \n"
|
||||||
|
" sub r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
||||||
|
" str r0, [r2] \n" /* Save the new top of stack. */
|
||||||
|
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
||||||
|
" mov r4, r8 \n" /* Store the high registers. */
|
||||||
|
" mov r5, r9 \n"
|
||||||
|
" mov r6, r10 \n"
|
||||||
|
" mov r7, r11 \n"
|
||||||
|
" stmia r0!, {r4-r7} \n"
|
||||||
|
" \n"
|
||||||
|
" push {r3, r14} \n"
|
||||||
|
" cpsid i \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" cpsie i \n"
|
||||||
|
" pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */
|
||||||
|
" \n"
|
||||||
|
" ldr r1, [r2] \n"
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" add r0, r0, #16 \n" /* Move to the high registers. */
|
||||||
|
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
||||||
|
" mov r8, r4 \n"
|
||||||
|
" mov r9, r5 \n"
|
||||||
|
" mov r10, r6 \n"
|
||||||
|
" mov r11, r7 \n"
|
||||||
|
" \n"
|
||||||
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
|
" \n"
|
||||||
|
" sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
||||||
|
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
||||||
|
" \n"
|
||||||
|
" bx r3 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst: .word pxCurrentTCB "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if configUSE_CUSTOM_TICK == 0
|
||||||
|
void xPortSysTickHandler( void )
|
||||||
|
{
|
||||||
|
unsigned long ulDummy;
|
||||||
|
|
||||||
|
/* If using preemption, also force a context switch. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
|
* frequency.
|
||||||
|
*/
|
||||||
|
void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
|
*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||||
|
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
extern void vPortYieldFromISR( void );
|
||||||
|
#define portYIELD() vPortYieldFromISR()
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )
|
||||||
|
#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
|
||||||
|
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
|
||||||
|
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,492 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
||||||
|
defined. The value should also ensure backward compatibility.
|
||||||
|
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||||
|
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
|
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
|
||||||
|
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
|
||||||
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
|
||||||
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
||||||
|
/* ...then bits in the registers. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||||
|
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||||
|
|
||||||
|
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
|
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
|
/* Constants required to set up the initial stack. */
|
||||||
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
|
/* The priority used by the kernel is assigned to a variable to make access
|
||||||
|
from inline assembler easier. */
|
||||||
|
const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||||
|
* file is weak to allow application writers to change the timer used to
|
||||||
|
* generate the tick interrupt.
|
||||||
|
*/
|
||||||
|
void vPortSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception handlers.
|
||||||
|
*/
|
||||||
|
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
||||||
|
void xPortSysTickHandler( void );
|
||||||
|
void vPortSVCHandler( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
|
*/
|
||||||
|
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The number of SysTick increments that make up one tick period.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long ulTimerReloadValueForOneTick = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
|
* 24 bit resolution of the SysTick timer.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
|
* power functionality only.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long ulStoppedTimerCompensation = 0;
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
|
interrupt. */
|
||||||
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0; /* LR */
|
||||||
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSVCHandler( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||||
|
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||||
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" orr r14, #0xd \n"
|
||||||
|
" bx r14 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvPortStartFirstTask( void )
|
||||||
|
{
|
||||||
|
__asm volatile(
|
||||||
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
|
" ldr r0, [r0] \n"
|
||||||
|
" ldr r0, [r0] \n"
|
||||||
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" svc 0 \n" /* System call to start first task. */
|
||||||
|
" nop \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||||
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
|
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
|
||||||
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
uxCriticalNesting = 0;
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
prvPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the CM3 port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldFromISR( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
uxCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
uxCriticalNesting--;
|
||||||
|
if( uxCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__(( naked )) unsigned long ulPortSetInterruptMask( void )
|
||||||
|
{
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" mrs r0, basepri \n" \
|
||||||
|
" mov r1, %0 \n" \
|
||||||
|
" msr basepri, r1 \n" \
|
||||||
|
" bx lr \n" \
|
||||||
|
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__(( naked )) void vPortClearInterruptMask( unsigned long ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" msr basepri, r0 \n" \
|
||||||
|
" bx lr \n" \
|
||||||
|
:::"r0" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Just to avoid compiler warnings. */
|
||||||
|
( void ) ulNewMaskValue;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xPortPendSVHandler( void )
|
||||||
|
{
|
||||||
|
/* This is a naked function. */
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
|
" ldr r2, [r3] \n"
|
||||||
|
" \n"
|
||||||
|
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
|
||||||
|
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||||
|
" \n"
|
||||||
|
" stmdb sp!, {r3, r14} \n"
|
||||||
|
" mov r0, %0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" ldmia sp!, {r3, r14} \n"
|
||||||
|
" \n" /* Restore the context, including the critical nesting count. */
|
||||||
|
" ldr r1, [r3] \n"
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||||
|
" msr psp, r0 \n"
|
||||||
|
" bx r14 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xPortSysTickHandler( void )
|
||||||
|
{
|
||||||
|
/* If using preemption, also force a context switch. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
|
||||||
|
1. If it is set to 0 tickless idle is not being used. If it is set to a
|
||||||
|
value other than 0 or 1 then a timer other than the SysTick is being used
|
||||||
|
to generate the tick interrupt. */
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
|
||||||
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
|
{
|
||||||
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements;
|
||||||
|
|
||||||
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||||
|
{
|
||||||
|
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
through one of the tick periods, and the fraction of a tick period is
|
||||||
|
accounted for later. */
|
||||||
|
ulReloadValue = ( ulTimerReloadValueForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
|
{
|
||||||
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||||
|
is accounted for as best it can be, but using the tickless mode will
|
||||||
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
|
kernel with respect to calendar time. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
||||||
|
|
||||||
|
/* If a context switch is pending then abandon the low power entry as
|
||||||
|
the context switch might have been pended by an external interrupt that
|
||||||
|
requires processing. */
|
||||||
|
if( ( portNVIC_INT_CTRL_REG & portNVIC_PENDSVSET_BIT ) != 0 )
|
||||||
|
{
|
||||||
|
/* Restart SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Adjust the reload value to take into account that the current
|
||||||
|
time slice is already partially complete. */
|
||||||
|
ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) );
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||||
|
|
||||||
|
/* Clear the SysTick count flag and set the count value back to
|
||||||
|
zero. */
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
|
/* Restart SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
|
/* Sleep until something happens. */
|
||||||
|
configPRE_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
if( xExpectedIdleTime > 0 )
|
||||||
|
{
|
||||||
|
__asm volatile( "wfi" );
|
||||||
|
}
|
||||||
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
|
/* Stop SysTick. Again, the time the SysTick is stopped for is
|
||||||
|
accounted for as best it can be, but using the tickless mode will
|
||||||
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
|
kernel with respect to calendar time. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
||||||
|
|
||||||
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
|
{
|
||||||
|
/* The tick interrupt has already executed, and the SysTick
|
||||||
|
count reloaded with the portNVIC_SYSTICK_LOAD_REG value.
|
||||||
|
Reset the portNVIC_SYSTICK_LOAD_REG with whatever remains of
|
||||||
|
this tick period. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
|
|
||||||
|
/* The tick interrupt handler will already have pended the tick
|
||||||
|
processing in the kernel. As the pending tick will be
|
||||||
|
processed as soon as this function exits, the tick value
|
||||||
|
maintained by the tick is stepped forward by one less than the
|
||||||
|
time spent waiting. */
|
||||||
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Something other than the tick interrupt ended the sleep.
|
||||||
|
Work out how long the sleep lasted. */
|
||||||
|
ulCompletedSysTickIncrements = ( xExpectedIdleTime * ulTimerReloadValueForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
|
/* How many complete tick periods passed while the processor
|
||||||
|
was waiting? */
|
||||||
|
ulCompleteTickPeriods = ulCompletedSysTickIncrements / ulTimerReloadValueForOneTick;
|
||||||
|
|
||||||
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
|
period remains. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerReloadValueForOneTick ) - ulCompletedSysTickIncrements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
|
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
|
value. */
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if configUSE_TICKLESS_IDLE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
|
* frequency.
|
||||||
|
*/
|
||||||
|
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
{
|
||||||
|
ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||||
|
xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
ulStoppedTimerCompensation = 45UL / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||||
|
}
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
extern void vPortYieldFromISR( void );
|
||||||
|
#define portYIELD() vPortYieldFromISR()
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
extern unsigned long ulPortSetInterruptMask( void );
|
||||||
|
extern void vPortClearInterruptMask( unsigned long ulNewMaskValue );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||||
|
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
|
not necessary for to use this port. They are defined so the common demo files
|
||||||
|
(which build with all the ports) will build. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Tickless idle/low power functionality. */
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specific optimisations. */
|
||||||
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Generic helper function. */
|
||||||
|
__attribute__( ( always_inline ) ) static inline unsigned char ucPortCountLeadingZeros( unsigned long ulBitmap )
|
||||||
|
{
|
||||||
|
unsigned char ucReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||||
|
return ucReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* portNOP() is not required by this port. */
|
||||||
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* MPU specific constants. */
|
||||||
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
|
||||||
|
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
||||||
|
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 2UL )
|
||||||
|
#define portGENERAL_PERIPHERALS_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" )
|
||||||
|
|
||||||
|
typedef struct MPU_REGION_REGISTERS
|
||||||
|
{
|
||||||
|
unsigned portLONG ulRegionBaseAddress;
|
||||||
|
unsigned portLONG ulRegionAttribute;
|
||||||
|
} xMPU_REGION_REGISTERS;
|
||||||
|
|
||||||
|
/* Plus 1 to create space for the stack region. */
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ];
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* SVC numbers for various services. */
|
||||||
|
#define portSVC_START_SCHEDULER 0
|
||||||
|
#define portSVC_YIELD 1
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 2
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
|
||||||
|
#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) )
|
||||||
|
#define portYIELD_WITHIN_API() *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL ( ( volatile unsigned portLONG *) 0xe000ed04 )
|
||||||
|
#define portNVIC_PENDSVSET 0x10000000
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
|
||||||
|
* registers. r0 is clobbered.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK() \
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" mov r0, %0 \n" \
|
||||||
|
" msr basepri, r0 \n" \
|
||||||
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set basepri back to 0 without effective other registers.
|
||||||
|
* r0 is clobbered. FAQ: Setting BASEPRI to 0 is not a bug. Please see
|
||||||
|
* http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html before disagreeing.
|
||||||
|
*/
|
||||||
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" mov r0, #0 \n" \
|
||||||
|
" msr basepri, r0 \n" \
|
||||||
|
:::"r0" \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* FAQ: Setting BASEPRI to 0 is not a bug. Please see
|
||||||
|
http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html before disagreeing. */
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
|
||||||
|
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
|
||||||
|
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#define portNOP()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,538 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#ifndef __VFP_FP__
|
||||||
|
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
|
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
|
||||||
|
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
|
||||||
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
|
||||||
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
||||||
|
/* ...then bits in the registers. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||||
|
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||||
|
|
||||||
|
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
|
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
|
/* Constants required to manipulate the VFP. */
|
||||||
|
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
||||||
|
|
||||||
|
/* Constants required to set up the initial stack. */
|
||||||
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
#define portINITIAL_EXEC_RETURN ( 0xfffffffd )
|
||||||
|
|
||||||
|
/* The priority used by the kernel is assigned to a variable to make access
|
||||||
|
from inline assembler easier. */
|
||||||
|
const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||||
|
* file is weak to allow application writers to change the timer used to
|
||||||
|
* generate the tick interrupt.
|
||||||
|
*/
|
||||||
|
void vPortSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception handlers.
|
||||||
|
*/
|
||||||
|
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
||||||
|
void xPortSysTickHandler( void );
|
||||||
|
void vPortSVCHandler( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
|
*/
|
||||||
|
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to enable the VFP.
|
||||||
|
*/
|
||||||
|
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The number of SysTick increments that make up one tick period.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long ulTimerReloadValueForOneTick = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
|
* 24 bit resolution of the SysTick timer.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
|
* power functionality only.
|
||||||
|
*/
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
static unsigned long ulStoppedTimerCompensation = 0;
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
|
interrupt. */
|
||||||
|
|
||||||
|
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||||
|
of interrupts, and to ensure alignment. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0; /* LR */
|
||||||
|
|
||||||
|
/* Save code space by skipping register initialisation. */
|
||||||
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
|
||||||
|
/* A save method is being used that requires each task to maintain its
|
||||||
|
own exec return value. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_EXEC_RETURN;
|
||||||
|
|
||||||
|
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSVCHandler( void )
|
||||||
|
{
|
||||||
|
__asm volatile (
|
||||||
|
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||||
|
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||||
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" bx r14 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvPortStartFirstTask( void )
|
||||||
|
{
|
||||||
|
__asm volatile(
|
||||||
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
|
" ldr r0, [r0] \n"
|
||||||
|
" ldr r0, [r0] \n"
|
||||||
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" svc 0 \n" /* System call to start first task. */
|
||||||
|
" nop \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||||
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
|
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
|
||||||
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
uxCriticalNesting = 0;
|
||||||
|
|
||||||
|
/* Ensure the VFP is enabled - it should be anyway. */
|
||||||
|
vPortEnableVFP();
|
||||||
|
|
||||||
|
/* Lazy save always. */
|
||||||
|
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
prvPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the CM4F port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldFromISR( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
uxCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
uxCriticalNesting--;
|
||||||
|
if( uxCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__(( naked )) unsigned long ulPortSetInterruptMask( void )
|
||||||
|
{
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" mrs r0, basepri \n" \
|
||||||
|
" mov r1, %0 \n" \
|
||||||
|
" msr basepri, r1 \n" \
|
||||||
|
" bx lr \n" \
|
||||||
|
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__(( naked )) void vPortClearInterruptMask( unsigned long ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile \
|
||||||
|
( \
|
||||||
|
" msr basepri, r0 \n" \
|
||||||
|
" bx lr \n" \
|
||||||
|
:::"r0" \
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xPortPendSVHandler( void )
|
||||||
|
{
|
||||||
|
/* This is a naked function. */
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
|
" ldr r2, [r3] \n"
|
||||||
|
" \n"
|
||||||
|
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
|
||||||
|
" it eq \n"
|
||||||
|
" vstmdbeq r0!, {s16-s31} \n"
|
||||||
|
" \n"
|
||||||
|
" stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
|
||||||
|
" \n"
|
||||||
|
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||||
|
" \n"
|
||||||
|
" stmdb sp!, {r3, r14} \n"
|
||||||
|
" mov r0, %0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n"
|
||||||
|
" ldmia sp!, {r3, r14} \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" ldr r0, [r1] \n"
|
||||||
|
" \n"
|
||||||
|
" ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */
|
||||||
|
" \n"
|
||||||
|
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */
|
||||||
|
" it eq \n"
|
||||||
|
" vldmiaeq r0!, {s16-s31} \n"
|
||||||
|
" \n"
|
||||||
|
" msr psp, r0 \n"
|
||||||
|
" bx r14 \n"
|
||||||
|
" \n"
|
||||||
|
" .align 2 \n"
|
||||||
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xPortSysTickHandler( void )
|
||||||
|
{
|
||||||
|
/* If using preemption, also force a context switch. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
|
||||||
|
1. If it is set to 0 tickless idle is not being used. If it is set to a
|
||||||
|
value other than 0 or 1 then a timer other than the SysTick is being used
|
||||||
|
to generate the tick interrupt. */
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
|
||||||
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
||||||
|
{
|
||||||
|
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements;
|
||||||
|
|
||||||
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
|
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||||
|
{
|
||||||
|
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
|
tick periods. -1 is used because this code will execute part way
|
||||||
|
through one of the tick periods, and the fraction of a tick period is
|
||||||
|
accounted for later. */
|
||||||
|
ulReloadValue = ( ulTimerReloadValueForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
|
{
|
||||||
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||||
|
is accounted for as best it can be, but using the tickless mode will
|
||||||
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
|
kernel with respect to calendar time. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
||||||
|
|
||||||
|
/* If a context switch is pending then abandon the low power entry as
|
||||||
|
the context switch might have been pended by an external interrupt that
|
||||||
|
requires processing. */
|
||||||
|
if( ( portNVIC_INT_CTRL_REG & portNVIC_PENDSVSET_BIT ) != 0 )
|
||||||
|
{
|
||||||
|
/* Restart SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Adjust the reload value to take into account that the current
|
||||||
|
time slice is already partially complete. */
|
||||||
|
ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) );
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||||
|
|
||||||
|
/* Clear the SysTick count flag and set the count value back to
|
||||||
|
zero. */
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
|
/* Restart SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
|
/* Sleep until something happens. */
|
||||||
|
configPRE_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
if( xExpectedIdleTime > 0 )
|
||||||
|
{
|
||||||
|
__asm volatile( "wfi" );
|
||||||
|
}
|
||||||
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
|
/* Stop SysTick. Again, the time the SysTick is stopped for is
|
||||||
|
accounted for as best it can be, but using the tickless mode will
|
||||||
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
|
kernel with respect to calendar time. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
||||||
|
|
||||||
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
|
{
|
||||||
|
/* The tick interrupt has already executed, and the SysTick
|
||||||
|
count reloaded with the portNVIC_SYSTICK_LOAD_REG value.
|
||||||
|
Reset the portNVIC_SYSTICK_LOAD_REG with whatever remains of
|
||||||
|
this tick period. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
|
|
||||||
|
/* The tick interrupt handler will already have pended the tick
|
||||||
|
processing in the kernel. As the pending tick will be
|
||||||
|
processed as soon as this function exits, the tick value
|
||||||
|
maintained by the tick is stepped forward by one less than the
|
||||||
|
time spent waiting. */
|
||||||
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Something other than the tick interrupt ended the sleep.
|
||||||
|
Work out how long the sleep lasted. */
|
||||||
|
ulCompletedSysTickIncrements = ( xExpectedIdleTime * ulTimerReloadValueForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
|
/* How many complete tick periods passed while the processor
|
||||||
|
was waiting? */
|
||||||
|
ulCompleteTickPeriods = ulCompletedSysTickIncrements / ulTimerReloadValueForOneTick;
|
||||||
|
|
||||||
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
|
period remains. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerReloadValueForOneTick ) - ulCompletedSysTickIncrements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
|
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
|
value. */
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if configUSE_TICKLESS_IDLE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
|
* frequency.
|
||||||
|
*/
|
||||||
|
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
|
#if configUSE_TICKLESS_IDLE == 1
|
||||||
|
{
|
||||||
|
ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||||
|
xMaximumPossibleSuppressedTicks = 0xffffffUL / ( ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
ulStoppedTimerCompensation = 45UL / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||||
|
}
|
||||||
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
|
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is a naked function. */
|
||||||
|
static void vPortEnableVFP( void )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */
|
||||||
|
" ldr r1, [r0] \n"
|
||||||
|
" \n"
|
||||||
|
" orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */
|
||||||
|
" str r1, [r0] \n"
|
||||||
|
" bx r14 "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
extern void vPortYieldFromISR( void );
|
||||||
|
#define portYIELD() vPortYieldFromISR()
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
extern unsigned long ulPortSetInterruptMask( void );
|
||||||
|
extern void vPortClearInterruptMask( unsigned long ulNewMaskValue );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||||
|
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
/* There are an uneven number of items on the initial stack, so
|
||||||
|
portALIGNMENT_ASSERT_pxCurrentTCB() will trigger false positive asserts. */
|
||||||
|
#define portALIGNMENT_ASSERT_pxCurrentTCB ( void )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
|
not necessary for to use this port. They are defined so the common demo files
|
||||||
|
(which build with all the ports) will build. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Tickless idle/low power functionality. */
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specific optimisations. */
|
||||||
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Generic helper function. */
|
||||||
|
__attribute__( ( always_inline ) ) static inline unsigned char ucPortCountLeadingZeros( unsigned long ulBitmap )
|
||||||
|
{
|
||||||
|
unsigned char ucReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||||
|
return ucReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* portNOP() is not required by this port. */
|
||||||
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,465 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Changes from V2.6.0
|
||||||
|
|
||||||
|
+ AVR port - Replaced the inb() and outb() functions with direct memory
|
||||||
|
access. This allows the port to be built with the 20050414 build of
|
||||||
|
WinAVR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the AVR port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Start tasks with interrupts enables. */
|
||||||
|
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 )
|
||||||
|
|
||||||
|
/* Hardware constants for timer 1. */
|
||||||
|
#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned char ) 0x08 )
|
||||||
|
#define portPRESCALE_64 ( ( unsigned char ) 0x03 )
|
||||||
|
#define portCLOCK_PRESCALER ( ( unsigned long ) 64 )
|
||||||
|
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned char ) 0x10 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
|
any details of its type. */
|
||||||
|
typedef void tskTCB;
|
||||||
|
extern volatile tskTCB * volatile pxCurrentTCB;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro to save all the general purpose registers, the save the stack pointer
|
||||||
|
* into the TCB.
|
||||||
|
*
|
||||||
|
* The first thing we do is save the flags then disable interrupts. This is to
|
||||||
|
* guard our stack against having a context switch interrupt after we have already
|
||||||
|
* pushed the registers onto the stack - causing the 32 registers to be on the
|
||||||
|
* stack twice.
|
||||||
|
*
|
||||||
|
* r1 is set to zero as the compiler expects it to be thus, however some
|
||||||
|
* of the math routines make use of R1.
|
||||||
|
*
|
||||||
|
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
|
||||||
|
* so we need not worry about reading/writing to the stack pointer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
asm volatile ( "push r0 \n\t" \
|
||||||
|
"in r0, __SREG__ \n\t" \
|
||||||
|
"cli \n\t" \
|
||||||
|
"push r0 \n\t" \
|
||||||
|
"push r1 \n\t" \
|
||||||
|
"clr r1 \n\t" \
|
||||||
|
"push r2 \n\t" \
|
||||||
|
"push r3 \n\t" \
|
||||||
|
"push r4 \n\t" \
|
||||||
|
"push r5 \n\t" \
|
||||||
|
"push r6 \n\t" \
|
||||||
|
"push r7 \n\t" \
|
||||||
|
"push r8 \n\t" \
|
||||||
|
"push r9 \n\t" \
|
||||||
|
"push r10 \n\t" \
|
||||||
|
"push r11 \n\t" \
|
||||||
|
"push r12 \n\t" \
|
||||||
|
"push r13 \n\t" \
|
||||||
|
"push r14 \n\t" \
|
||||||
|
"push r15 \n\t" \
|
||||||
|
"push r16 \n\t" \
|
||||||
|
"push r17 \n\t" \
|
||||||
|
"push r18 \n\t" \
|
||||||
|
"push r19 \n\t" \
|
||||||
|
"push r20 \n\t" \
|
||||||
|
"push r21 \n\t" \
|
||||||
|
"push r22 \n\t" \
|
||||||
|
"push r23 \n\t" \
|
||||||
|
"push r24 \n\t" \
|
||||||
|
"push r25 \n\t" \
|
||||||
|
"push r26 \n\t" \
|
||||||
|
"push r27 \n\t" \
|
||||||
|
"push r28 \n\t" \
|
||||||
|
"push r29 \n\t" \
|
||||||
|
"push r30 \n\t" \
|
||||||
|
"push r31 \n\t" \
|
||||||
|
"lds r26, pxCurrentTCB \n\t" \
|
||||||
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
|
"in r0, 0x3d \n\t" \
|
||||||
|
"st x+, r0 \n\t" \
|
||||||
|
"in r0, 0x3e \n\t" \
|
||||||
|
"st x+, r0 \n\t" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
|
||||||
|
* the context save so we can write to the stack pointer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
asm volatile ( "lds r26, pxCurrentTCB \n\t" \
|
||||||
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
|
"ld r28, x+ \n\t" \
|
||||||
|
"out __SP_L__, r28 \n\t" \
|
||||||
|
"ld r29, x+ \n\t" \
|
||||||
|
"out __SP_H__, r29 \n\t" \
|
||||||
|
"pop r31 \n\t" \
|
||||||
|
"pop r30 \n\t" \
|
||||||
|
"pop r29 \n\t" \
|
||||||
|
"pop r28 \n\t" \
|
||||||
|
"pop r27 \n\t" \
|
||||||
|
"pop r26 \n\t" \
|
||||||
|
"pop r25 \n\t" \
|
||||||
|
"pop r24 \n\t" \
|
||||||
|
"pop r23 \n\t" \
|
||||||
|
"pop r22 \n\t" \
|
||||||
|
"pop r21 \n\t" \
|
||||||
|
"pop r20 \n\t" \
|
||||||
|
"pop r19 \n\t" \
|
||||||
|
"pop r18 \n\t" \
|
||||||
|
"pop r17 \n\t" \
|
||||||
|
"pop r16 \n\t" \
|
||||||
|
"pop r15 \n\t" \
|
||||||
|
"pop r14 \n\t" \
|
||||||
|
"pop r13 \n\t" \
|
||||||
|
"pop r12 \n\t" \
|
||||||
|
"pop r11 \n\t" \
|
||||||
|
"pop r10 \n\t" \
|
||||||
|
"pop r9 \n\t" \
|
||||||
|
"pop r8 \n\t" \
|
||||||
|
"pop r7 \n\t" \
|
||||||
|
"pop r6 \n\t" \
|
||||||
|
"pop r5 \n\t" \
|
||||||
|
"pop r4 \n\t" \
|
||||||
|
"pop r3 \n\t" \
|
||||||
|
"pop r2 \n\t" \
|
||||||
|
"pop r1 \n\t" \
|
||||||
|
"pop r0 \n\t" \
|
||||||
|
"out __SREG__, r0 \n\t" \
|
||||||
|
"pop r0 \n\t" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform hardware setup to enable ticks from timer 1, compare match A.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short usAddress;
|
||||||
|
|
||||||
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is just useful for debugging. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x11;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Simulate how the stack would look after a call to vPortYield() generated by
|
||||||
|
the compiler. */
|
||||||
|
|
||||||
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
|
/* The start of the task code will be popped off the stack last, so place
|
||||||
|
it on first. */
|
||||||
|
usAddress = ( unsigned short ) pxCode;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
usAddress >>= 8;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
||||||
|
portSAVE_CONTEXT places the flags on the stack immediately after r0
|
||||||
|
to ensure the interrupts get disabled as soon as possible, and so ensuring
|
||||||
|
the stack use is minimal should a context switch interrupt occur. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
||||||
|
/* Now the remaining registers. The compiler expects R1 to be 0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Place the parameter on the stack in the expected location. */
|
||||||
|
usAddress = ( unsigned short ) pvParameters;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
usAddress >>= 8;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/*lint +e950 +e611 +e923 */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Setup the hardware to generate the tick. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
/* Simulate a function call end as generated by the compiler. We will now
|
||||||
|
jump to the start of the task the context of which we have just restored. */
|
||||||
|
asm volatile ( "ret" );
|
||||||
|
|
||||||
|
/* Should not get here. */
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the AVR port will get stopped. If required simply
|
||||||
|
disable the tick interrupt here. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch. The first thing we do is save the registers so we
|
||||||
|
* can use a naked attribute.
|
||||||
|
*/
|
||||||
|
void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
asm volatile ( "ret" );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context switch function used by the tick. This must be identical to
|
||||||
|
* vPortYield() from the call to vTaskSwitchContext() onwards. The only
|
||||||
|
* difference from vPortYield() is the tick count is incremented as the
|
||||||
|
* call comes from the tick ISR.
|
||||||
|
*/
|
||||||
|
void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
|
||||||
|
void vPortYieldFromTick( void )
|
||||||
|
{
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
vTaskIncrementTick();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
asm volatile ( "ret" );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup timer 1 compare match A to generate a tick interrupt.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
unsigned long ulCompareMatch;
|
||||||
|
unsigned char ucHighByte, ucLowByte;
|
||||||
|
|
||||||
|
/* Using 16bit timer 1 to generate the tick. Correct fuses must be
|
||||||
|
selected for the configCPU_CLOCK_HZ clock. */
|
||||||
|
|
||||||
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* We only have 16 bits so have to scale to get our required tick rate. */
|
||||||
|
ulCompareMatch /= portCLOCK_PRESCALER;
|
||||||
|
|
||||||
|
/* Adjust for correct value. */
|
||||||
|
ulCompareMatch -= ( unsigned long ) 1;
|
||||||
|
|
||||||
|
/* Setup compare match value for compare match A. Interrupts are disabled
|
||||||
|
before this is called so we need not worry here. */
|
||||||
|
ucLowByte = ( unsigned char ) ( ulCompareMatch & ( unsigned long ) 0xff );
|
||||||
|
ulCompareMatch >>= 8;
|
||||||
|
ucHighByte = ( unsigned char ) ( ulCompareMatch & ( unsigned long ) 0xff );
|
||||||
|
OCR1AH = ucHighByte;
|
||||||
|
OCR1AL = ucLowByte;
|
||||||
|
|
||||||
|
/* Setup clock source and compare match behaviour. */
|
||||||
|
ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
|
||||||
|
TCCR1B = ucLowByte;
|
||||||
|
|
||||||
|
/* Enable the interrupt - this is okay as interrupt are currently globally
|
||||||
|
disabled. */
|
||||||
|
ucLowByte = TIMSK;
|
||||||
|
ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
|
||||||
|
TIMSK = ucLowByte;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
||||||
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
|
* count is incremented after the context is saved.
|
||||||
|
*/
|
||||||
|
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
|
||||||
|
void SIG_OUTPUT_COMPARE1A( void )
|
||||||
|
{
|
||||||
|
vPortYieldFromTick();
|
||||||
|
asm volatile ( "reti" );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
|
* manual calls to taskYIELD();
|
||||||
|
*/
|
||||||
|
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );
|
||||||
|
void SIG_OUTPUT_COMPARE1A( void )
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.2.3
|
||||||
|
|
||||||
|
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
||||||
|
base 16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT int
|
||||||
|
#define portSTACK_TYPE unsigned portCHAR
|
||||||
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \
|
||||||
|
asm volatile ( "cli" :: ); \
|
||||||
|
asm volatile ( "push __tmp_reg__" :: )
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \
|
||||||
|
asm volatile ( "out __SREG__, __tmp_reg__" :: )
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: );
|
||||||
|
#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 1
|
||||||
|
#define portNOP() asm volatile ( "nop" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Kernel utilities. */
|
||||||
|
extern void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,297 @@
|
|||||||
|
/*This file is prepared for Doxygen automatic documentation generation.*/
|
||||||
|
/*! \file *********************************************************************
|
||||||
|
*
|
||||||
|
* \brief Exception and interrupt vectors.
|
||||||
|
*
|
||||||
|
* This file maps all events supported by an AVR32UC.
|
||||||
|
*
|
||||||
|
* - Compiler: GNU GCC for AVR32
|
||||||
|
* - Supported devices: All AVR32UC devices with an INTC module can be used.
|
||||||
|
* - AppNote:
|
||||||
|
*
|
||||||
|
* \author Atmel Corporation: http://www.atmel.com \n
|
||||||
|
* Support and FAQ: http://support.atmel.no/
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
|
||||||
|
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr32/io.h>
|
||||||
|
#include "intc.h"
|
||||||
|
|
||||||
|
|
||||||
|
//! @{
|
||||||
|
//! \verbatim
|
||||||
|
|
||||||
|
|
||||||
|
.section .exception, "ax", @progbits
|
||||||
|
|
||||||
|
|
||||||
|
// Start of Exception Vector Table.
|
||||||
|
|
||||||
|
// EVBA must be aligned with a power of two strictly greater than the EVBA-
|
||||||
|
// relative offset of the last vector.
|
||||||
|
.balign 0x200
|
||||||
|
|
||||||
|
// Export symbol.
|
||||||
|
.global _evba
|
||||||
|
.type _evba, @function
|
||||||
|
_evba:
|
||||||
|
|
||||||
|
.org 0x000
|
||||||
|
// Unrecoverable Exception.
|
||||||
|
_handle_Unrecoverable_Exception:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x004
|
||||||
|
// TLB Multiple Hit: UNUSED IN AVR32UC.
|
||||||
|
_handle_TLB_Multiple_Hit:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x008
|
||||||
|
// Bus Error Data Fetch.
|
||||||
|
_handle_Bus_Error_Data_Fetch:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x00C
|
||||||
|
// Bus Error Instruction Fetch.
|
||||||
|
_handle_Bus_Error_Instruction_Fetch:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x010
|
||||||
|
// NMI.
|
||||||
|
_handle_NMI:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x014
|
||||||
|
// Instruction Address.
|
||||||
|
_handle_Instruction_Address:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x018
|
||||||
|
// ITLB Protection.
|
||||||
|
_handle_ITLB_Protection:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x01C
|
||||||
|
// Breakpoint.
|
||||||
|
_handle_Breakpoint:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x020
|
||||||
|
// Illegal Opcode.
|
||||||
|
_handle_Illegal_Opcode:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x024
|
||||||
|
// Unimplemented Instruction.
|
||||||
|
_handle_Unimplemented_Instruction:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x028
|
||||||
|
// Privilege Violation.
|
||||||
|
_handle_Privilege_Violation:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x02C
|
||||||
|
// Floating-Point: UNUSED IN AVR32UC.
|
||||||
|
_handle_Floating_Point:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x030
|
||||||
|
// Coprocessor Absent: UNUSED IN AVR32UC.
|
||||||
|
_handle_Coprocessor_Absent:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x034
|
||||||
|
// Data Address (Read).
|
||||||
|
_handle_Data_Address_Read:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x038
|
||||||
|
// Data Address (Write).
|
||||||
|
_handle_Data_Address_Write:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x03C
|
||||||
|
// DTLB Protection (Read).
|
||||||
|
_handle_DTLB_Protection_Read:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x040
|
||||||
|
// DTLB Protection (Write).
|
||||||
|
_handle_DTLB_Protection_Write:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x044
|
||||||
|
// DTLB Modified: UNUSED IN AVR32UC.
|
||||||
|
_handle_DTLB_Modified:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x050
|
||||||
|
// ITLB Miss: UNUSED IN AVR32UC.
|
||||||
|
_handle_ITLB_Miss:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x060
|
||||||
|
// DTLB Miss (Read): UNUSED IN AVR32UC.
|
||||||
|
_handle_DTLB_Miss_Read:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x070
|
||||||
|
// DTLB Miss (Write): UNUSED IN AVR32UC.
|
||||||
|
_handle_DTLB_Miss_Write:
|
||||||
|
rjmp $
|
||||||
|
|
||||||
|
.org 0x100
|
||||||
|
// Supervisor Call.
|
||||||
|
_handle_Supervisor_Call:
|
||||||
|
lda.w pc, SCALLYield
|
||||||
|
|
||||||
|
|
||||||
|
// Interrupt support.
|
||||||
|
// The interrupt controller must provide the offset address relative to EVBA.
|
||||||
|
// Important note:
|
||||||
|
// All interrupts call a C function named _get_interrupt_handler.
|
||||||
|
// This function will read group and interrupt line number to then return in
|
||||||
|
// R12 a pointer to a user-provided interrupt handler.
|
||||||
|
|
||||||
|
.balign 4
|
||||||
|
|
||||||
|
_int0:
|
||||||
|
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||||
|
// CPU upon interrupt entry.
|
||||||
|
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||||
|
mfsr r12, AVR32_SR
|
||||||
|
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||||
|
cp.w r12, 0b110
|
||||||
|
brlo _int0_normal
|
||||||
|
lddsp r12, sp[0 * 4]
|
||||||
|
stdsp sp[6 * 4], r12
|
||||||
|
lddsp r12, sp[1 * 4]
|
||||||
|
stdsp sp[7 * 4], r12
|
||||||
|
lddsp r12, sp[3 * 4]
|
||||||
|
sub sp, -6 * 4
|
||||||
|
rete
|
||||||
|
_int0_normal:
|
||||||
|
#endif
|
||||||
|
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||||
|
call _get_interrupt_handler
|
||||||
|
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||||
|
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||||
|
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||||
|
|
||||||
|
_int1:
|
||||||
|
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||||
|
// CPU upon interrupt entry.
|
||||||
|
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||||
|
mfsr r12, AVR32_SR
|
||||||
|
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||||
|
cp.w r12, 0b110
|
||||||
|
brlo _int1_normal
|
||||||
|
lddsp r12, sp[0 * 4]
|
||||||
|
stdsp sp[6 * 4], r12
|
||||||
|
lddsp r12, sp[1 * 4]
|
||||||
|
stdsp sp[7 * 4], r12
|
||||||
|
lddsp r12, sp[3 * 4]
|
||||||
|
sub sp, -6 * 4
|
||||||
|
rete
|
||||||
|
_int1_normal:
|
||||||
|
#endif
|
||||||
|
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||||
|
call _get_interrupt_handler
|
||||||
|
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||||
|
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||||
|
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||||
|
|
||||||
|
_int2:
|
||||||
|
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||||
|
// CPU upon interrupt entry.
|
||||||
|
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||||
|
mfsr r12, AVR32_SR
|
||||||
|
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||||
|
cp.w r12, 0b110
|
||||||
|
brlo _int2_normal
|
||||||
|
lddsp r12, sp[0 * 4]
|
||||||
|
stdsp sp[6 * 4], r12
|
||||||
|
lddsp r12, sp[1 * 4]
|
||||||
|
stdsp sp[7 * 4], r12
|
||||||
|
lddsp r12, sp[3 * 4]
|
||||||
|
sub sp, -6 * 4
|
||||||
|
rete
|
||||||
|
_int2_normal:
|
||||||
|
#endif
|
||||||
|
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||||
|
call _get_interrupt_handler
|
||||||
|
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||||
|
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||||
|
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||||
|
|
||||||
|
_int3:
|
||||||
|
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||||
|
// CPU upon interrupt entry.
|
||||||
|
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||||
|
mfsr r12, AVR32_SR
|
||||||
|
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||||
|
cp.w r12, 0b110
|
||||||
|
brlo _int3_normal
|
||||||
|
lddsp r12, sp[0 * 4]
|
||||||
|
stdsp sp[6 * 4], r12
|
||||||
|
lddsp r12, sp[1 * 4]
|
||||||
|
stdsp sp[7 * 4], r12
|
||||||
|
lddsp r12, sp[3 * 4]
|
||||||
|
sub sp, -6 * 4
|
||||||
|
rete
|
||||||
|
_int3_normal:
|
||||||
|
#endif
|
||||||
|
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||||
|
call _get_interrupt_handler
|
||||||
|
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||||
|
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||||
|
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||||
|
|
||||||
|
|
||||||
|
// Constant data area.
|
||||||
|
|
||||||
|
.balign 4
|
||||||
|
|
||||||
|
// Values to store in the interrupt priority registers for the various interrupt priority levels.
|
||||||
|
// The interrupt priority registers contain the interrupt priority level and
|
||||||
|
// the EVBA-relative interrupt vector offset.
|
||||||
|
.global ipr_val
|
||||||
|
.type ipr_val, @object
|
||||||
|
ipr_val:
|
||||||
|
.word (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
|
||||||
|
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
|
||||||
|
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
|
||||||
|
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
|
||||||
|
|
||||||
|
|
||||||
|
//! \endverbatim
|
||||||
|
//! @}
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||||
|
/*! \file *********************************************************************
|
||||||
|
*
|
||||||
|
* \brief FreeRTOS port source for AVR32 UC3.
|
||||||
|
*
|
||||||
|
* - Compiler: GNU GCC for AVR32
|
||||||
|
* - Supported devices: All AVR32 devices can be used.
|
||||||
|
* - AppNote:
|
||||||
|
*
|
||||||
|
* \author Atmel Corporation: http://www.atmel.com \n
|
||||||
|
* Support and FAQ: http://support.atmel.no/
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <sys/cpu.h>
|
||||||
|
#include <sys/usart.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* AVR32 UC3 includes. */
|
||||||
|
#include <avr32/io.h>
|
||||||
|
#include "gpio.h"
|
||||||
|
#if( configTICK_USE_TC==1 )
|
||||||
|
#include "tc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Constants required to setup the task context. */
|
||||||
|
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )
|
||||||
|
|
||||||
|
/* Each task maintains its own critical nesting variable. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
#if( configTICK_USE_TC==0 )
|
||||||
|
static void prvScheduleNextTick( void );
|
||||||
|
#else
|
||||||
|
static void prvClearTcInt( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Low-level initialization routine called during startup, before the main
|
||||||
|
* function.
|
||||||
|
* This version comes in replacement to the default one provided by Newlib.
|
||||||
|
* Newlib's _init_startup only calls init_exceptions, but Newlib's exception
|
||||||
|
* vectors are not compatible with the SCALL management in the current FreeRTOS
|
||||||
|
* port. More low-level initializations are besides added here.
|
||||||
|
*/
|
||||||
|
void _init_startup(void)
|
||||||
|
{
|
||||||
|
/* Import the Exception Vector Base Address. */
|
||||||
|
extern void _evba;
|
||||||
|
|
||||||
|
#if configHEAP_INIT
|
||||||
|
extern void __heap_start__;
|
||||||
|
extern void __heap_end__;
|
||||||
|
portBASE_TYPE *pxMem;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Load the Exception Vector Base Address in the corresponding system register. */
|
||||||
|
Set_system_register( AVR32_EVBA, ( int ) &_evba );
|
||||||
|
|
||||||
|
/* Enable exceptions. */
|
||||||
|
ENABLE_ALL_EXCEPTIONS();
|
||||||
|
|
||||||
|
/* Initialize interrupt handling. */
|
||||||
|
INTC_init_interrupts();
|
||||||
|
|
||||||
|
#if configHEAP_INIT
|
||||||
|
|
||||||
|
/* Initialize the heap used by malloc. */
|
||||||
|
for( pxMem = &__heap_start__; pxMem < ( portBASE_TYPE * )&__heap_end__; )
|
||||||
|
{
|
||||||
|
*pxMem++ = 0xA5A5A5A5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
|
||||||
|
set_cpu_hz( configCPU_CLOCK_HZ );
|
||||||
|
|
||||||
|
/* Code section present if and only if the debug trace is activated. */
|
||||||
|
#if configDBG
|
||||||
|
{
|
||||||
|
static const gpio_map_t DBG_USART_GPIO_MAP =
|
||||||
|
{
|
||||||
|
{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
|
||||||
|
{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialize the USART used for the debug trace with the configured parameters. */
|
||||||
|
set_usart_base( ( void * ) configDBG_USART );
|
||||||
|
gpio_enable_module( DBG_USART_GPIO_MAP,
|
||||||
|
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
|
||||||
|
usart_init( configDBG_USART_BAUDRATE );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* malloc, realloc and free are meant to be called through respectively
|
||||||
|
* pvPortMalloc, pvPortRealloc and vPortFree.
|
||||||
|
* The latter functions call the former ones from within sections where tasks
|
||||||
|
* are suspended, so the latter functions are task-safe. __malloc_lock and
|
||||||
|
* __malloc_unlock use the same mechanism to also keep the former functions
|
||||||
|
* task-safe as they may be called directly from Newlib's functions.
|
||||||
|
* However, all these functions are interrupt-unsafe and SHALL THEREFORE NOT BE
|
||||||
|
* CALLED FROM WITHIN AN INTERRUPT, because __malloc_lock and __malloc_unlock do
|
||||||
|
* not call portENTER_CRITICAL and portEXIT_CRITICAL in order not to disable
|
||||||
|
* interrupts during memory allocation management as this may be a very time-
|
||||||
|
* consuming process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock routine called by Newlib on malloc / realloc / free entry to guarantee a
|
||||||
|
* safe section as memory allocation management uses global data.
|
||||||
|
* See the aforementioned details.
|
||||||
|
*/
|
||||||
|
void __malloc_lock(struct _reent *ptr)
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unlock routine called by Newlib on malloc / realloc / free exit to guarantee
|
||||||
|
* a safe section as memory allocation management uses global data.
|
||||||
|
* See the aforementioned details.
|
||||||
|
*/
|
||||||
|
void __malloc_unlock(struct _reent *ptr)
|
||||||
|
{
|
||||||
|
xTaskResumeAll();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Added as there is no such function in FreeRTOS. */
|
||||||
|
void *pvPortRealloc( void *pv, size_t xWantedSize )
|
||||||
|
{
|
||||||
|
void *pvReturn;
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
pvReturn = realloc( pv, xWantedSize );
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
simply increment the system tick. */
|
||||||
|
/* The preemptive scheduler is defined as "naked" as the full context is saved
|
||||||
|
on entry as part of the context switch. */
|
||||||
|
__attribute__((__naked__)) static void vTick( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT_OS_INT();
|
||||||
|
|
||||||
|
#if( configTICK_USE_TC==1 )
|
||||||
|
/* Clear the interrupt flag. */
|
||||||
|
prvClearTcInt();
|
||||||
|
#else
|
||||||
|
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||||
|
clock cycles from now. */
|
||||||
|
prvScheduleNextTick();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
||||||
|
calls in a critical section . */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
vTaskIncrementTick();
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* Restore the context of the "elected task". */
|
||||||
|
portRESTORE_CONTEXT_OS_INT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__((__naked__)) void SCALLYield( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT_SCALL();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_CONTEXT_SCALL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
|
in a variable, which is then saved as part of the stack context. */
|
||||||
|
__attribute__((__noinline__)) void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
__attribute__((__noinline__)) void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
|
||||||
|
{
|
||||||
|
ulCriticalNesting--;
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable all interrupt/exception. */
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* When the task starts, it will expect to find the function parameter in R12. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the AVR32 port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||||
|
clock cycles from now. */
|
||||||
|
#if( configTICK_USE_TC==0 )
|
||||||
|
static void prvScheduleFirstTick(void)
|
||||||
|
{
|
||||||
|
unsigned long lCycles;
|
||||||
|
|
||||||
|
lCycles = Get_system_register(AVR32_COUNT);
|
||||||
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
|
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||||
|
// generation feature does not get disabled.
|
||||||
|
if(0 == lCycles)
|
||||||
|
{
|
||||||
|
lCycles++;
|
||||||
|
}
|
||||||
|
Set_system_register(AVR32_COMPARE, lCycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((__noinline__)) static void prvScheduleNextTick(void)
|
||||||
|
{
|
||||||
|
unsigned long lCycles, lCount;
|
||||||
|
|
||||||
|
lCycles = Get_system_register(AVR32_COMPARE);
|
||||||
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
|
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||||
|
// generation feature does not get disabled.
|
||||||
|
if(0 == lCycles)
|
||||||
|
{
|
||||||
|
lCycles++;
|
||||||
|
}
|
||||||
|
lCount = Get_system_register(AVR32_COUNT);
|
||||||
|
if( lCycles < lCount )
|
||||||
|
{ // We missed a tick, recover for the next.
|
||||||
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
|
}
|
||||||
|
Set_system_register(AVR32_COMPARE, lCycles);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
__attribute__((__noinline__)) static void prvClearTcInt(void)
|
||||||
|
{
|
||||||
|
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt(void)
|
||||||
|
{
|
||||||
|
#if( configTICK_USE_TC==1 )
|
||||||
|
|
||||||
|
volatile avr32_tc_t *tc = &AVR32_TC;
|
||||||
|
|
||||||
|
// Options for waveform genration.
|
||||||
|
tc_waveform_opt_t waveform_opt =
|
||||||
|
{
|
||||||
|
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
|
||||||
|
|
||||||
|
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
|
||||||
|
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
|
||||||
|
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
|
||||||
|
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
|
||||||
|
|
||||||
|
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
|
||||||
|
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
|
||||||
|
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
|
||||||
|
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
|
||||||
|
|
||||||
|
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
|
||||||
|
.enetrg = FALSE, /* External event trigger enable. */
|
||||||
|
.eevt = 0, /* External event selection. */
|
||||||
|
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
|
||||||
|
.cpcdis = FALSE, /* Counter disable when RC compare. */
|
||||||
|
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
|
||||||
|
|
||||||
|
.burst = FALSE, /* Burst signal selection. */
|
||||||
|
.clki = FALSE, /* Clock inversion. */
|
||||||
|
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
|
||||||
|
};
|
||||||
|
|
||||||
|
tc_interrupt_t tc_interrupt =
|
||||||
|
{
|
||||||
|
.etrgs=0,
|
||||||
|
.ldrbs=0,
|
||||||
|
.ldras=0,
|
||||||
|
.cpcs =1,
|
||||||
|
.cpbs =0,
|
||||||
|
.cpas =0,
|
||||||
|
.lovrs=0,
|
||||||
|
.covfs=0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Disable all interrupt/exception. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Register the compare interrupt handler to the interrupt controller and
|
||||||
|
enable the compare interrupt. */
|
||||||
|
|
||||||
|
#if( configTICK_USE_TC==1 )
|
||||||
|
{
|
||||||
|
INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);
|
||||||
|
|
||||||
|
/* Initialize the timer/counter. */
|
||||||
|
tc_init_waveform(tc, &waveform_opt);
|
||||||
|
|
||||||
|
/* Set the compare triggers.
|
||||||
|
Remember TC counter is 16-bits, so counting second is not possible!
|
||||||
|
That's why we configure it to count ms. */
|
||||||
|
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
|
||||||
|
|
||||||
|
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
|
||||||
|
|
||||||
|
/* Start the timer/counter. */
|
||||||
|
tc_start(tc, configTICK_TC_CHANNEL);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
|
||||||
|
prvScheduleFirstTick();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,704 @@
|
|||||||
|
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||||
|
/*! \file *********************************************************************
|
||||||
|
*
|
||||||
|
* \brief FreeRTOS port source for AVR32 UC3.
|
||||||
|
*
|
||||||
|
* - Compiler: GNU GCC for AVR32
|
||||||
|
* - Supported devices: All AVR32 devices can be used.
|
||||||
|
* - AppNote:
|
||||||
|
*
|
||||||
|
* \author Atmel Corporation: http://www.atmel.com \n
|
||||||
|
* Support and FAQ: http://support.atmel.no/
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include <avr32/io.h>
|
||||||
|
#include "intc.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )
|
||||||
|
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
|
||||||
|
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
|
||||||
|
|
||||||
|
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portNOP() {__asm__ __volatile__ ("nop");}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* INTC-specific. */
|
||||||
|
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
|
||||||
|
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
|
||||||
|
|
||||||
|
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
|
||||||
|
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
|
||||||
|
|
||||||
|
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
|
||||||
|
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug trace.
|
||||||
|
* Activated if and only if configDBG is nonzero.
|
||||||
|
* Prints a formatted string to stdout.
|
||||||
|
* The current source file name and line number are output with a colon before
|
||||||
|
* the formatted string.
|
||||||
|
* A carriage return and a linefeed are appended to the output.
|
||||||
|
* stdout is redirected to the USART configured by configDBG_USART.
|
||||||
|
* The parameters are the same as for the standard printf function.
|
||||||
|
* There is no return value.
|
||||||
|
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
|
||||||
|
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
|
||||||
|
*/
|
||||||
|
#if configDBG
|
||||||
|
#define portDBG_TRACE(...) \
|
||||||
|
{\
|
||||||
|
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\
|
||||||
|
printf(__VA_ARGS__);\
|
||||||
|
fputs("\r\n", stdout);\
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define portDBG_TRACE(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
|
||||||
|
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
|
||||||
|
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
|
|
||||||
|
/* Added as there is no such function in FreeRTOS. */
|
||||||
|
extern void *pvPortRealloc( void *pv, size_t xSize );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*=============================================================================================*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore Context for cases other than INTi.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Set SP to point to new stack */ \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"ld.w sp, r0[0] \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore ulCriticalNesting variable */ \
|
||||||
|
"ld.w r0, sp++ \n\t"\
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"st.w r8[0], r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
/* R0-R7 should not be used below this line */ \
|
||||||
|
/* Skip PC and SR (will do it at the end) */ \
|
||||||
|
"sub sp, -2*4 \n\t"\
|
||||||
|
/* Restore R8..R12 and LR */ \
|
||||||
|
"ldm sp++, r8-r12, lr \n\t"\
|
||||||
|
/* Restore SR */ \
|
||||||
|
"ld.w r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */ \
|
||||||
|
"mtsr %[SR], r0 \n\t"\
|
||||||
|
/* Restore r0 */ \
|
||||||
|
"ld.w r0, sp[-9*4] \n\t"\
|
||||||
|
/* Restore PC */ \
|
||||||
|
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
|
[SR] "i" (AVR32_SR) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.
|
||||||
|
* portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.
|
||||||
|
*
|
||||||
|
* Had to make different versions because registers saved on the system stack
|
||||||
|
* are not the same between INT0..3 exceptions and the scall exception.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Task context stack layout:
|
||||||
|
// R8 (*)
|
||||||
|
// R9 (*)
|
||||||
|
// R10 (*)
|
||||||
|
// R11 (*)
|
||||||
|
// R12 (*)
|
||||||
|
// R14/LR (*)
|
||||||
|
// R15/PC (*)
|
||||||
|
// SR (*)
|
||||||
|
// R0
|
||||||
|
// R1
|
||||||
|
// R2
|
||||||
|
// R3
|
||||||
|
// R4
|
||||||
|
// R5
|
||||||
|
// R6
|
||||||
|
// R7
|
||||||
|
// ulCriticalNesting
|
||||||
|
// (*) automatically done for INT0..INT3, but not for SCALL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT_OS_INT() \
|
||||||
|
{ \
|
||||||
|
/* Save R0..R7 */ \
|
||||||
|
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||||
|
\
|
||||||
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
|
/* there is also no context save. */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT_OS_INT() \
|
||||||
|
{ \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7\n\t" \
|
||||||
|
\
|
||||||
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
|
/* there is also no context restore. */ \
|
||||||
|
"rete" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT_OS_INT() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
/* When we come here */ \
|
||||||
|
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Save R0..R7 */ \
|
||||||
|
"stm --sp, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||||
|
"mov r8, LO(%[ulCriticalNesting])\n\t" \
|
||||||
|
"orh r8, HI(%[ulCriticalNesting])\n\t" \
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"st.w --sp, r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
/* level and allow other lower interrupt level to occur). */ \
|
||||||
|
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||||
|
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||||
|
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||||
|
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||||
|
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
||||||
|
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
|
||||||
|
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
|
||||||
|
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
|
||||||
|
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
|
||||||
|
\
|
||||||
|
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||||
|
/* NOTE: we don't enter a critical section here because all interrupt handlers */ \
|
||||||
|
/* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
|
||||||
|
/* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
|
||||||
|
/* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB])\n\t" \
|
||||||
|
"orh r8, HI(%[pxCurrentTCB])\n\t" \
|
||||||
|
"ld.w r0, r8[0]\n\t" \
|
||||||
|
"st.w r0[0], sp\n" \
|
||||||
|
\
|
||||||
|
"LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
|
[LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT_OS_INT() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
/* level and allow other lower interrupt level to occur). */ \
|
||||||
|
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||||
|
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||||
|
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||||
|
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
|
||||||
|
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
|
||||||
|
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
|
||||||
|
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \
|
||||||
|
: \
|
||||||
|
: [LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/* Else */ \
|
||||||
|
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
|
||||||
|
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
|
||||||
|
portENTER_CRITICAL(); \
|
||||||
|
vTaskSwitchContext(); \
|
||||||
|
portEXIT_CRITICAL(); \
|
||||||
|
\
|
||||||
|
/* Restore all registers */ \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Set SP to point to new stack */ \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"ld.w sp, r0[0] \n"\
|
||||||
|
\
|
||||||
|
"LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore ulCriticalNesting variable */ \
|
||||||
|
"ld.w r0, sp++ \n\t" \
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"st.w r8[0], r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||||
|
"rete" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
|
[LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.
|
||||||
|
*
|
||||||
|
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT_SCALL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
|
||||||
|
/* If SR[M2:M0] == 001 */ \
|
||||||
|
/* PC and SR are on the stack. */ \
|
||||||
|
/* Else (other modes) */ \
|
||||||
|
/* Nothing on the stack. */ \
|
||||||
|
\
|
||||||
|
/* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \
|
||||||
|
/* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \
|
||||||
|
/* in an interrupt|exception handler. */ \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* in order to save R0-R7 */ \
|
||||||
|
"sub sp, 6*4 \n\t"\
|
||||||
|
/* Save R0..R7 */ \
|
||||||
|
"stm --sp, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* in order to save R8-R12 and LR */ \
|
||||||
|
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
||||||
|
"sub r7, sp,-16*4 \n\t"\
|
||||||
|
/* Copy PC and SR in other places in the stack. */ \
|
||||||
|
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
|
||||||
|
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
|
||||||
|
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
|
||||||
|
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
|
||||||
|
\
|
||||||
|
/* Save R8..R12 and LR on the stack. */ \
|
||||||
|
"stm --r7, r8-r12, lr \n\t"\
|
||||||
|
\
|
||||||
|
/* Arriving here we have the following stack organizations: */ \
|
||||||
|
/* R8..R12, LR, PC, SR, R0..R7. */ \
|
||||||
|
\
|
||||||
|
/* Now we can finalize the save. */ \
|
||||||
|
\
|
||||||
|
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"st.w --sp, r0" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
|
||||||
|
/* pxCurrentTCB). */ \
|
||||||
|
/* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \
|
||||||
|
/* critical section because it is a global structure. */ \
|
||||||
|
portENTER_CRITICAL(); \
|
||||||
|
\
|
||||||
|
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"st.w r0[0], sp" \
|
||||||
|
: \
|
||||||
|
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portRESTORE_CONTEXT() for SupervisorCALL exception.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT_SCALL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
/* Restore all registers */ \
|
||||||
|
\
|
||||||
|
/* Set SP to point to new stack */ \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"ld.w sp, r0[0]" \
|
||||||
|
: \
|
||||||
|
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/* Leave pxCurrentTCB variable access critical section */ \
|
||||||
|
portEXIT_CRITICAL(); \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Restore ulCriticalNesting variable */ \
|
||||||
|
"ld.w r0, sp++ \n\t"\
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"st.w r8[0], r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* skip PC and SR */ \
|
||||||
|
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
||||||
|
"sub r7, sp, -10*4 \n\t"\
|
||||||
|
/* Restore r8-r12 and LR */ \
|
||||||
|
"ldm r7++, r8-r12, lr \n\t"\
|
||||||
|
\
|
||||||
|
/* RETS will take care of the extra PC and SR restore. */ \
|
||||||
|
/* So, we have to prepare the stack for this. */ \
|
||||||
|
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
|
||||||
|
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
|
||||||
|
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
|
||||||
|
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
|
||||||
|
\
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
"sub sp, -6*4 \n\t"\
|
||||||
|
\
|
||||||
|
"rets" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR entry and exit macros. These are only required if a task switch
|
||||||
|
* is required from the ISR.
|
||||||
|
*/
|
||||||
|
#define portENTER_SWITCHING_ISR() \
|
||||||
|
{ \
|
||||||
|
/* Save R0..R7 */ \
|
||||||
|
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||||
|
\
|
||||||
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
|
/* there is also no context save. */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||||
|
*/
|
||||||
|
#define portEXIT_SWITCHING_ISR() \
|
||||||
|
{ \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
|
/* there is also no context restore. */ \
|
||||||
|
"rete" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR entry and exit macros. These are only required if a task switch
|
||||||
|
* is required from the ISR.
|
||||||
|
*/
|
||||||
|
#define portENTER_SWITCHING_ISR() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
/* When we come here */ \
|
||||||
|
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Save R0..R7 */ \
|
||||||
|
"stm --sp, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"st.w --sp, r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
/* level and allow other lower interrupt level to occur). */ \
|
||||||
|
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||||
|
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||||
|
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||||
|
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||||
|
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
||||||
|
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||||
|
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||||
|
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||||
|
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
|
||||||
|
\
|
||||||
|
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"st.w r0[0], sp \n"\
|
||||||
|
\
|
||||||
|
"LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
|
[LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||||
|
*/
|
||||||
|
#define portEXIT_SWITCHING_ISR() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||||
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
/* level and allow other lower interrupt level to occur). */ \
|
||||||
|
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
|
||||||
|
/* did not previously save SP in its TCB. */ \
|
||||||
|
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||||
|
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||||
|
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||||
|
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t"\
|
||||||
|
\
|
||||||
|
/* If a switch is required then we just need to call */ \
|
||||||
|
/* vTaskSwitchContext() as the context has already been */ \
|
||||||
|
/* saved. */ \
|
||||||
|
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
|
||||||
|
"brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \
|
||||||
|
: \
|
||||||
|
: [LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
|
||||||
|
portENTER_CRITICAL(); \
|
||||||
|
vTaskSwitchContext(); \
|
||||||
|
portEXIT_CRITICAL(); \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
|
"LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
|
/* Restore the context of which ever task is now the highest */ \
|
||||||
|
/* priority that is ready to run. */ \
|
||||||
|
\
|
||||||
|
/* Restore all registers */ \
|
||||||
|
\
|
||||||
|
/* Set SP to point to new stack */ \
|
||||||
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
|
"ld.w r0, r8[0] \n\t"\
|
||||||
|
"ld.w sp, r0[0] \n"\
|
||||||
|
\
|
||||||
|
"LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore ulCriticalNesting variable */ \
|
||||||
|
"ld.w r0, sp++ \n\t"\
|
||||||
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
|
"st.w r8[0], r0 \n\t"\
|
||||||
|
\
|
||||||
|
/* Restore R0..R7 */ \
|
||||||
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
\
|
||||||
|
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||||
|
"rete" \
|
||||||
|
: \
|
||||||
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
|
[LINE] "i" (__LINE__) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define portYIELD() {__asm__ __volatile__ ("scall");}
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Machine includes */
|
||||||
|
#include <machine/counter.h>
|
||||||
|
#include <machine/ic.h>
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The initial PSR has the Previous Interrupt Enabled (PIEN) flag set. */
|
||||||
|
#define portINITIAL_PSR ( 0x00020000 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform any hardware configuration necessary to generate the tick interrupt.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Make space on the stack for the context - this leaves a couple of spaces
|
||||||
|
empty. */
|
||||||
|
pxTopOfStack -= 20;
|
||||||
|
|
||||||
|
/* Fill the registers with known values to assist debugging. */
|
||||||
|
pxTopOfStack[ 16 ] = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
|
||||||
|
pxTopOfStack[ 15 ] = portINITIAL_PSR;
|
||||||
|
pxTopOfStack[ 14 ] = ( unsigned long ) pxCode;
|
||||||
|
pxTopOfStack[ 13 ] = 0x00000000UL; /* R15. */
|
||||||
|
pxTopOfStack[ 12 ] = 0x00000000UL; /* R14. */
|
||||||
|
pxTopOfStack[ 11 ] = 0x0d0d0d0dUL;
|
||||||
|
pxTopOfStack[ 10 ] = 0x0c0c0c0cUL;
|
||||||
|
pxTopOfStack[ 9 ] = 0x0b0b0b0bUL;
|
||||||
|
pxTopOfStack[ 8 ] = 0x0a0a0a0aUL;
|
||||||
|
pxTopOfStack[ 7 ] = 0x09090909UL;
|
||||||
|
pxTopOfStack[ 6 ] = 0x08080808UL;
|
||||||
|
pxTopOfStack[ 5 ] = 0x07070707UL;
|
||||||
|
pxTopOfStack[ 4 ] = 0x06060606UL;
|
||||||
|
pxTopOfStack[ 3 ] = 0x05050505UL;
|
||||||
|
pxTopOfStack[ 2 ] = 0x04040404UL;
|
||||||
|
pxTopOfStack[ 1 ] = 0x03030303UL;
|
||||||
|
pxTopOfStack[ 0 ] = ( unsigned long ) pvParameters;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Set-up the timer interrupt. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Enable the TRAP yield. */
|
||||||
|
irq[ portIRQ_TRAP_YIELD ].ien = 1;
|
||||||
|
irq[ portIRQ_TRAP_YIELD ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
|
||||||
|
|
||||||
|
/* Integrated Interrupt Controller: Enable all interrupts. */
|
||||||
|
ic->ien = 1;
|
||||||
|
|
||||||
|
/* Restore callee saved registers. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
/* Should not get here. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Enable timer interrupts */
|
||||||
|
counter1->reload = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1;
|
||||||
|
counter1->value = counter1->reload;
|
||||||
|
counter1->mask = 1;
|
||||||
|
|
||||||
|
/* Set the IRQ Handler priority and enable it. */
|
||||||
|
irq[ IRQ_COUNTER1 ].ien = 1;
|
||||||
|
irq[ IRQ_COUNTER1 ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Trap 31 handler. */
|
||||||
|
void interrupt31_handler( void ) __attribute__((naked));
|
||||||
|
void interrupt31_handler( void )
|
||||||
|
{
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
__asm volatile ( "call vTaskSwitchContext" );
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvProcessTick( void ) __attribute__((noinline));
|
||||||
|
static void prvProcessTick( void )
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
vTaskSwitchContext();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear the Tick Interrupt. */
|
||||||
|
counter1->expired = 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Timer 1 interrupt handler, used for tick interrupt. */
|
||||||
|
void interrupt7_handler( void ) __attribute__((naked));
|
||||||
|
void interrupt7_handler( void )
|
||||||
|
{
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
prvProcessTick();
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Nothing to do. Unlikely to want to end. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <machine/ic.h>
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portNOP() __asm__ volatile ( "mov r0, r0" )
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
#define portIRQ_TRAP_YIELD 31
|
||||||
|
#define portKERNEL_INTERRUPT_PRIORITY_LEVEL 0
|
||||||
|
#define portSYSTEM_INTERRUPT_PRIORITY_LEVEL 0
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
extern void vPortYield( void );
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portYIELD() asm __volatile__( " trap #%0 "::"i"(portIRQ_TRAP_YIELD):"memory")
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void vTaskEnterCritical( void );
|
||||||
|
extern void vTaskExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
#define portDISABLE_INTERRUPTS() ic->cpl = ( portSYSTEM_INTERRUPT_PRIORITY_LEVEL + 1 )
|
||||||
|
#define portENABLE_INTERRUPTS() ic->cpl = portKERNEL_INTERRUPT_PRIORITY_LEVEL
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken != pdFALSE ) vTaskSwitchContext()
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
asm __volatile__ \
|
||||||
|
( \
|
||||||
|
"sub r1, #68 \n" /* Make space on the stack for the context. */ \
|
||||||
|
"std r2, [r1] + 0 \n" \
|
||||||
|
"stq r4, [r1] + 8 \n" \
|
||||||
|
"stq r8, [r1] + 24 \n" \
|
||||||
|
"stq r12, [r1] + 40 \n" \
|
||||||
|
"mov r6, rtt \n" \
|
||||||
|
"mov r7, psr \n" \
|
||||||
|
"std r6, [r1] + 56 \n" \
|
||||||
|
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
||||||
|
"ldub r3, [r2] + 2 \n" /* Load the current interrupt mask. */ \
|
||||||
|
"st r3, [r1]+ 64 \n" /* Store the interrupt mask on the stack. */ \
|
||||||
|
"ld r2, [r0]+short(pxCurrentTCB) \n" /* Load the pointer to the TCB. */ \
|
||||||
|
"st r1, [r2] \n" /* Save the stack pointer into the TCB. */ \
|
||||||
|
"mov r14, r1 \n" /* Compiler expects r14 to be set to the function stack. */ \
|
||||||
|
);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
asm __volatile__( \
|
||||||
|
"ld r2, [r0]+short(pxCurrentTCB) \n" /* Load the TCB to find the stack pointer and context. */ \
|
||||||
|
"ld r1, [r2] \n" \
|
||||||
|
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
||||||
|
"ld r3, [r1] + 64 \n" /* Load the previous interrupt mask. */ \
|
||||||
|
"stb r3, [r2] + 2 \n" /* Set the current interrupt mask to be the previous. */ \
|
||||||
|
"ldd r6, [r1] + 56 \n" /* Restore context. */ \
|
||||||
|
"mov rtt, r6 \n" \
|
||||||
|
"mov psr, r7 \n" \
|
||||||
|
"ldd r2, [r1] + 0 \n" \
|
||||||
|
"ldq r4, [r1] + 8 \n" \
|
||||||
|
"ldq r8, [r1] + 24 \n" \
|
||||||
|
"ldq r12, [r1] + 40 \n" \
|
||||||
|
"add r1, #68 \n" \
|
||||||
|
"rti \n" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
|
||||||
|
|
||||||
|
/* Supervisor mode set. */
|
||||||
|
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
|
||||||
|
|
||||||
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
|
will be set to 0 prior to the first task being started. */
|
||||||
|
static unsigned long ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Exception stack frame starts with the return address. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
|
||||||
|
pxTopOfStack -= 14; /* A5 to D0. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
/* Configure the interrupts used by this port. */
|
||||||
|
vApplicationSetupInterrupts();
|
||||||
|
|
||||||
|
/* Start the first task executing. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented as there is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting == 0UL )
|
||||||
|
{
|
||||||
|
/* Guard against context switches being pended simultaneously with a
|
||||||
|
critical section being entered. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
if( MCF_INTC0_INTFRCL == 0UL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
} while( 1 );
|
||||||
|
}
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
ulCriticalNesting--;
|
||||||
|
if( ulCriticalNesting == 0 )
|
||||||
|
{
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYieldHandler( void )
|
||||||
|
{
|
||||||
|
unsigned long ulSavedInterruptMask;
|
||||||
|
|
||||||
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
MCF_INTC0_INTFRCL = 0;
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Purpose: Lowest level routines for all ColdFire processors.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
|
||||||
|
* supplied source files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global ulPortSetIPL
|
||||||
|
.global mcf5xxx_wr_cacr
|
||||||
|
.global __cs3_isr_interrupt_80
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.macro portSAVE_CONTEXT
|
||||||
|
|
||||||
|
lea.l (-60, %sp), %sp
|
||||||
|
movem.l %d0-%fp, (%sp)
|
||||||
|
move.l pxCurrentTCB, %a0
|
||||||
|
move.l %sp, (%a0)
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
move.l pxCurrentTCB, %a0
|
||||||
|
move.l (%a0), %sp
|
||||||
|
movem.l (%sp), %d0-%fp
|
||||||
|
lea.l %sp@(60), %sp
|
||||||
|
rte
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* This routines changes the IPL to the value passed into the routine.
|
||||||
|
* It also returns the old IPL value back.
|
||||||
|
* Calling convention from C:
|
||||||
|
* old_ipl = asm_set_ipl(new_ipl);
|
||||||
|
* For the Diab Data C compiler, it passes return value thru D0.
|
||||||
|
* Note that only the least significant three bits of the passed
|
||||||
|
* value are used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ulPortSetIPL:
|
||||||
|
link A6,#-8
|
||||||
|
movem.l D6-D7,(SP)
|
||||||
|
|
||||||
|
move.w SR,D7 /* current sr */
|
||||||
|
|
||||||
|
move.l D7,D0 /* prepare return value */
|
||||||
|
andi.l #0x0700,D0 /* mask out IPL */
|
||||||
|
lsr.l #8,D0 /* IPL */
|
||||||
|
|
||||||
|
move.l 8(A6),D6 /* get argument */
|
||||||
|
andi.l #0x07,D6 /* least significant three bits */
|
||||||
|
lsl.l #8,D6 /* move over to make mask */
|
||||||
|
|
||||||
|
andi.l #0x0000F8FF,D7 /* zero out current IPL */
|
||||||
|
or.l D6,D7 /* place new IPL in sr */
|
||||||
|
move.w D7,SR
|
||||||
|
|
||||||
|
movem.l (SP),D6-D7
|
||||||
|
lea 8(SP),SP
|
||||||
|
unlk A6
|
||||||
|
rts
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
mcf5xxx_wr_cacr:
|
||||||
|
move.l 4(sp),d0
|
||||||
|
.long 0x4e7b0002 /* movec d0,cacr */
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
/* Yield interrupt. */
|
||||||
|
__cs3_isr_interrupt_80:
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
jsr vPortYieldHandler
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portSTACK_GROWTH -1
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
unsigned portLONG ulPortSetIPL( unsigned portLONG );
|
||||||
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
|
||||||
|
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
|
{ \
|
||||||
|
portYIELD(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the H8S port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* When the task starts interrupts should be enabled. */
|
||||||
|
#define portINITIAL_CCR ( ( portSTACK_TYPE ) 0x00 )
|
||||||
|
|
||||||
|
/* Hardware specific constants used to generate the RTOS tick from the TPU. */
|
||||||
|
#define portCLEAR_ON_TGRA_COMPARE_MATCH ( ( unsigned char ) 0x20 )
|
||||||
|
#define portCLOCK_DIV_64 ( ( unsigned char ) 0x03 )
|
||||||
|
#define portCLOCK_DIV ( ( unsigned long ) 64 )
|
||||||
|
#define portTGRA_INTERRUPT_ENABLE ( ( unsigned char ) 0x01 )
|
||||||
|
#define portTIMER_CHANNEL ( ( unsigned char ) 0x02 )
|
||||||
|
#define portMSTP13 ( ( unsigned short ) 0x2000 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup TPU channel one for the RTOS tick at the requested frequency.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISR used by portYIELD(). This is installed as a trap handler.
|
||||||
|
*/
|
||||||
|
void vPortYield( void ) __attribute__ ( ( saveall, interrupt_handler ) );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long ulValue;
|
||||||
|
|
||||||
|
/* This requires an even address. */
|
||||||
|
ulValue = ( unsigned long ) pxTopOfStack;
|
||||||
|
if( ulValue & 1UL )
|
||||||
|
{
|
||||||
|
pxTopOfStack = pxTopOfStack - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is just useful for debugging. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xaa;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xbb;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xcc;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xdd;
|
||||||
|
|
||||||
|
/* The initial stack mimics an interrupt stack. First there is the program
|
||||||
|
counter (24 bits). */
|
||||||
|
ulValue = ( unsigned long ) pxCode;
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
ulValue >>= 8UL;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
ulValue >>= 8UL;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
|
||||||
|
/* Followed by the CCR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_CCR;
|
||||||
|
|
||||||
|
/* Next all the general purpose registers - with the parameters being passed
|
||||||
|
in ER0. The parameter order must match that used by the compiler when the
|
||||||
|
"saveall" function attribute is used. */
|
||||||
|
|
||||||
|
/* ER6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x66;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x66;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x66;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x66;
|
||||||
|
|
||||||
|
/* ER0 */
|
||||||
|
ulValue = ( unsigned long ) pvParameters;
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
ulValue >>= 8UL;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
ulValue >>= 8UL;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
pxTopOfStack--;
|
||||||
|
ulValue >>= 8UL;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
|
||||||
|
|
||||||
|
/* ER1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x11;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x11;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x11;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x11;
|
||||||
|
|
||||||
|
/* ER2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22;
|
||||||
|
|
||||||
|
/* ER3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33;
|
||||||
|
|
||||||
|
/* ER4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x44;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x44;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x44;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x44;
|
||||||
|
|
||||||
|
/* ER5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x55;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x55;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x55;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x55;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void * pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Setup the hardware to generate the tick. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. This
|
||||||
|
mirrors the function epilogue code generated by the compiler when the
|
||||||
|
"saveall" function attribute is used. */
|
||||||
|
asm volatile (
|
||||||
|
"MOV.L @_pxCurrentTCB, ER6 \n\t"
|
||||||
|
"MOV.L @ER6, ER7 \n\t"
|
||||||
|
"LDM.L @SP+, (ER4-ER5) \n\t"
|
||||||
|
"LDM.L @SP+, (ER0-ER3) \n\t"
|
||||||
|
"MOV.L @ER7+, ER6 \n\t"
|
||||||
|
"RTE \n\t"
|
||||||
|
);
|
||||||
|
|
||||||
|
( void ) pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Should not get here. */
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the h8 port will get stopped. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch. This is a trap handler. The "saveall" function
|
||||||
|
* attribute is used so the context is saved by the compiler prologue. All
|
||||||
|
* we have to do is save the stack pointer.
|
||||||
|
*/
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
portSAVE_STACK_POINTER();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_STACK_POINTER();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt handler installed for the RTOS tick depends on whether the
|
||||||
|
* preemptive or cooperative scheduler is being used.
|
||||||
|
*/
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The preemptive scheduler is used so the ISR calls vTaskSwitchContext().
|
||||||
|
* The function prologue saves the context so all we have to do is save
|
||||||
|
* the stack pointer.
|
||||||
|
*/
|
||||||
|
void vTickISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
|
||||||
|
void vTickISR( void )
|
||||||
|
{
|
||||||
|
portSAVE_STACK_POINTER();
|
||||||
|
|
||||||
|
vTaskIncrementTick();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Clear the interrupt. */
|
||||||
|
TSR1 &= ~0x01;
|
||||||
|
|
||||||
|
portRESTORE_STACK_POINTER();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The cooperative scheduler is being used so all we have to do is
|
||||||
|
* periodically increment the tick. This can just be a normal ISR and
|
||||||
|
* the "saveall" attribute is not required.
|
||||||
|
*/
|
||||||
|
void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );
|
||||||
|
void vTickISR( void )
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Clear the interrupt. */
|
||||||
|
TSR1 &= ~0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup timer 1 compare match to generate a tick interrupt.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
const unsigned long ulCompareMatch = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / portCLOCK_DIV;
|
||||||
|
|
||||||
|
/* Turn the module on. */
|
||||||
|
MSTPCR &= ~portMSTP13;
|
||||||
|
|
||||||
|
/* Configure timer 1. */
|
||||||
|
TCR1 = portCLEAR_ON_TGRA_COMPARE_MATCH | portCLOCK_DIV_64;
|
||||||
|
|
||||||
|
/* Configure the compare match value for a tick of configTICK_RATE_HZ. */
|
||||||
|
TGR1A = ulCompareMatch;
|
||||||
|
|
||||||
|
/* Start the timer and enable the interrupt - we can do this here as
|
||||||
|
interrupts are globally disabled when this function is called. */
|
||||||
|
TIER1 |= portTGRA_INTERRUPT_ENABLE;
|
||||||
|
TSTR |= portTIMER_CHANNEL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portCHAR
|
||||||
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 2
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portYIELD() asm volatile( "TRAPA #0" )
|
||||||
|
#define portNOP() asm volatile( "NOP" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
#define portENABLE_INTERRUPTS() asm volatile( "ANDC #0x7F, CCR" );
|
||||||
|
#define portDISABLE_INTERRUPTS() asm volatile( "ORC #0x80, CCR" );
|
||||||
|
|
||||||
|
/* Push the CCR then disable interrupts. */
|
||||||
|
#define portENTER_CRITICAL() asm volatile( "STC CCR, @-ER7" ); \
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Pop the CCR to set the interrupt masking back to its previous state. */
|
||||||
|
#define portEXIT_CRITICAL() asm volatile( "LDC @ER7+, CCR" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/* Context switch macros. These macros are very simple as the context
|
||||||
|
is saved simply by selecting the saveall attribute of the context switch
|
||||||
|
interrupt service routines. These macros save and restore the stack
|
||||||
|
pointer to the TCB. */
|
||||||
|
|
||||||
|
#define portSAVE_STACK_POINTER() \
|
||||||
|
extern void* pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
asm volatile( \
|
||||||
|
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
|
||||||
|
"MOV.L ER7, @ER5 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) pxCurrentTCB;
|
||||||
|
|
||||||
|
|
||||||
|
#define portRESTORE_STACK_POINTER() \
|
||||||
|
extern void* pxCurrentTCB; \
|
||||||
|
\
|
||||||
|
asm volatile( \
|
||||||
|
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
|
||||||
|
"MOV.L @ER5, ER7 \n\t" \
|
||||||
|
); \
|
||||||
|
( void ) pxCurrentTCB;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Macros to allow a context switch from within an application ISR. */
|
||||||
|
|
||||||
|
#define portENTER_SWITCHING_ISR() portSAVE_STACK_POINTER(); {
|
||||||
|
|
||||||
|
#define portEXIT_SWITCHING_ISR( x ) \
|
||||||
|
if( x ) \
|
||||||
|
{ \
|
||||||
|
extern void vTaskSwitchContext( void ); \
|
||||||
|
vTaskSwitchContext(); \
|
||||||
|
} \
|
||||||
|
} portRESTORE_STACK_POINTER();
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* GCC/HCS12 port by Jefferson L Smith, 2005 */
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Port includes */
|
||||||
|
#include <sys/ports_def.h>
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure a timer to generate the RTOS tick at the frequency specified
|
||||||
|
* within FreeRTOSConfig.h.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* NOTE: Interrupt service routines must be in non-banked memory - as does the
|
||||||
|
scheduler startup function. */
|
||||||
|
#define ATTR_NEAR __attribute__((near))
|
||||||
|
|
||||||
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
|
// __attribute__((interrupt))
|
||||||
|
void ATTR_NEAR vPortYield( void );
|
||||||
|
|
||||||
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
|
// __attribute__((interrupt))
|
||||||
|
void ATTR_NEAR vPortTickInterrupt( void );
|
||||||
|
|
||||||
|
/* Function in non-banked memory which actually switches to first task. */
|
||||||
|
portBASE_TYPE ATTR_NEAR xStartSchedulerNear( void );
|
||||||
|
|
||||||
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
|
critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
|
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
|
depth. Each task maintains it's own critical nesting depth variable so
|
||||||
|
uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
|
switch. */
|
||||||
|
volatile unsigned portBASE_TYPE uxCriticalNesting = 0x80; // un-initialized
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
|
expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );
|
||||||
|
|
||||||
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
|
||||||
|
/* Y register */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0xff;
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0xee;
|
||||||
|
|
||||||
|
/* X register */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0xdd;
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0xcc;
|
||||||
|
|
||||||
|
/* A register contains parameter high byte. */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );
|
||||||
|
|
||||||
|
/* B register contains parameter low byte. */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );
|
||||||
|
|
||||||
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
|
"I" bit of CCR is cleared */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0x80; // keeps Stop disabled (MCU default)
|
||||||
|
|
||||||
|
/* tmp softregs used by GCC. Values right now don't matter. */
|
||||||
|
__asm("\n\
|
||||||
|
movw _.frame, 2,-%0 \n\
|
||||||
|
movw _.tmp, 2,-%0 \n\
|
||||||
|
movw _.z, 2,-%0 \n\
|
||||||
|
movw _.xy, 2,-%0 \n\
|
||||||
|
;movw _.d2, 2,-%0 \n\
|
||||||
|
;movw _.d1, 2,-%0 \n\
|
||||||
|
": "=A"(pxTopOfStack) : "0"(pxTopOfStack) );
|
||||||
|
|
||||||
|
#ifdef BANKED_MODEL
|
||||||
|
/* The page of the task. */
|
||||||
|
*--pxTopOfStack = 0x30; // can only directly start in PPAGE 0x30
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The critical nesting depth is initialised with 0 (meaning not in
|
||||||
|
a critical section). */
|
||||||
|
*--pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the HCS12 port will get stopped. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Enable hardware RTI timer */
|
||||||
|
/* Ignores configTICK_RATE_HZ */
|
||||||
|
RTICTL = 0x50; // 16 MHz xtal: 976.56 Hz, 1024mS
|
||||||
|
CRGINT |= 0x80; // RTIE
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
|
the header file containing the xPortStartScheduler() prototype is part
|
||||||
|
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
|
Instead it simply calls the locally defined xNearStartScheduler() -
|
||||||
|
which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
|
short register d;
|
||||||
|
__asm ("jmp xStartSchedulerNear ; will never return": "=d"(d));
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xStartSchedulerNear( void )
|
||||||
|
{
|
||||||
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
|
disabled when this function is called. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Restore the context of the first task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
portISR_TAIL();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context switch functions. These are interrupt service routines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch forced by calling portYIELD(). This is the SWI
|
||||||
|
* handler.
|
||||||
|
*/
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
portISR_HEAD();
|
||||||
|
/* NOTE: This is the trap routine (swi) although not defined as a trap.
|
||||||
|
It will fill the stack the same way as an ISR in order to mix preemtion
|
||||||
|
and cooperative yield. */
|
||||||
|
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
portISR_TAIL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTOS tick interrupt service routine. If the cooperative scheduler is
|
||||||
|
* being used then this simply increments the tick count. If the
|
||||||
|
* preemptive scheduler is being used a context switch can occur.
|
||||||
|
*/
|
||||||
|
void vPortTickInterrupt( void )
|
||||||
|
{
|
||||||
|
portISR_HEAD();
|
||||||
|
|
||||||
|
/* Clear tick timer flag */
|
||||||
|
CRGFLG = 0x80;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
{
|
||||||
|
/* A context switch might happen so save the context. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the tick ... */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* ... then see if the new tick value has necessitated a
|
||||||
|
context switch. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Restore the context of a task - which may be a different task
|
||||||
|
to that interrupted. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
portISR_TAIL();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portCHAR
|
||||||
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 1
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portYIELD() __asm( "swi" );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section handling. */
|
||||||
|
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable interrupts before incrementing the count of critical section nesting.
|
||||||
|
* The nesting count is maintained so we know when interrupts should be
|
||||||
|
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
||||||
|
* directly. Each task maintains its own nesting count.
|
||||||
|
*/
|
||||||
|
#define portENTER_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
portDISABLE_INTERRUPTS(); \
|
||||||
|
uxCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
|
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
||||||
|
* section and interrupts can be re-enabled.
|
||||||
|
*/
|
||||||
|
#define portEXIT_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
\
|
||||||
|
uxCriticalNesting--; \
|
||||||
|
if( uxCriticalNesting == 0 ) \
|
||||||
|
{ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are very simple as the processor automatically saves and
|
||||||
|
* restores its registers as interrupts are entered and exited. In
|
||||||
|
* addition to the (automatically stacked) registers we also stack the
|
||||||
|
* critical nesting count. Each task maintains its own critical nesting
|
||||||
|
* count as it is legitimate for a task to yield from within a critical
|
||||||
|
* section. If the banked memory model is being used then the PPAGE
|
||||||
|
* register is also stored as part of the tasks context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef BANKED_MODEL
|
||||||
|
/*
|
||||||
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
|
* count and PPAGE register from the stack. The remains of the
|
||||||
|
* context are restored by the RTI instruction.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
__asm( " \n\
|
||||||
|
.globl pxCurrentTCB ; void * \n\
|
||||||
|
.globl uxCriticalNesting ; char \n\
|
||||||
|
\n\
|
||||||
|
ldx pxCurrentTCB \n\
|
||||||
|
lds 0,x ; Stack \n\
|
||||||
|
\n\
|
||||||
|
movb 1,sp+,uxCriticalNesting \n\
|
||||||
|
movb 1,sp+,0x30 ; PPAGE \n\
|
||||||
|
" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By the time this macro is called the processor has already stacked the
|
||||||
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
|
* the task stack pointer.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
__asm( " \n\
|
||||||
|
.globl pxCurrentTCB ; void * \n\
|
||||||
|
.globl uxCriticalNesting ; char \n\
|
||||||
|
\n\
|
||||||
|
movb 0x30, 1,-sp ; PPAGE \n\
|
||||||
|
movb uxCriticalNesting, 1,-sp \n\
|
||||||
|
\n\
|
||||||
|
ldx pxCurrentTCB \n\
|
||||||
|
sts 0,x ; Stack \n\
|
||||||
|
" ); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
|
* and restoring the PPAGE register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
__asm( " \n\
|
||||||
|
.globl pxCurrentTCB ; void * \n\
|
||||||
|
.globl uxCriticalNesting ; char \n\
|
||||||
|
\n\
|
||||||
|
ldx pxCurrentTCB \n\
|
||||||
|
lds 0,x ; Stack \n\
|
||||||
|
\n\
|
||||||
|
movb 1,sp+,uxCriticalNesting \n\
|
||||||
|
" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
{ \
|
||||||
|
__asm( " \n\
|
||||||
|
.globl pxCurrentTCB ; void * \n\
|
||||||
|
.globl uxCriticalNesting ; char \n\
|
||||||
|
\n\
|
||||||
|
movb uxCriticalNesting, 1,-sp \n\
|
||||||
|
\n\
|
||||||
|
ldx pxCurrentTCB \n\
|
||||||
|
sts 0,x ; Stack \n\
|
||||||
|
" ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility macros to save/restore correct software registers for GCC. This is
|
||||||
|
* useful when GCC does not generate appropriate ISR head/tail code.
|
||||||
|
*/
|
||||||
|
#define portISR_HEAD() \
|
||||||
|
{ \
|
||||||
|
__asm(" \n\
|
||||||
|
movw _.frame, 2,-sp \n\
|
||||||
|
movw _.tmp, 2,-sp \n\
|
||||||
|
movw _.z, 2,-sp \n\
|
||||||
|
movw _.xy, 2,-sp \n\
|
||||||
|
;movw _.d2, 2,-sp \n\
|
||||||
|
;movw _.d1, 2,-sp \n\
|
||||||
|
"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portISR_TAIL() \
|
||||||
|
{ \
|
||||||
|
__asm(" \n\
|
||||||
|
movw 2,sp+, _.xy \n\
|
||||||
|
movw 2,sp+, _.z \n\
|
||||||
|
movw 2,sp+, _.tmp \n\
|
||||||
|
movw 2,sp+, _.frame \n\
|
||||||
|
;movw 2,sp+, _.d1 \n\
|
||||||
|
;movw 2,sp+, _.d2 \n\
|
||||||
|
rti \n\
|
||||||
|
"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
* task switch from within a standard ISR. This macro can only be used if
|
||||||
|
* the ISR does not use any local (stack) variables. If the ISR uses stack
|
||||||
|
* variables portYIELD() should be used in it's place.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define portTASK_SWITCH_FROM_ISR() \
|
||||||
|
portSAVE_CONTEXT(); \
|
||||||
|
vTaskSwitchContext(); \
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||||
|
MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License** as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with FreeRTOS; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
A special exception to the GPL can be applied should you wish to distribute
|
||||||
|
a combined work that includes FreeRTOS, without being obliged to provide
|
||||||
|
the source code for any proprietary components. See the licensing section
|
||||||
|
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||||
|
can be applied.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* This is a concise, step by step, 'hands on' guide that describes both *
|
||||||
|
* general multitasking concepts and FreeRTOS specifics. It presents and *
|
||||||
|
* explains numerous examples that are written using the FreeRTOS API. *
|
||||||
|
* Full source code for all the examples is provided in an accompanying *
|
||||||
|
* .zip file. *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
Please ensure to read the configuration and relevant port sections of the
|
||||||
|
online documentation.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* ------------------------ Types ----------------------------------------- */
|
||||||
|
typedef volatile unsigned long vuint32;
|
||||||
|
typedef volatile unsigned short vuint16;
|
||||||
|
typedef volatile unsigned char vuint8;
|
||||||
|
|
||||||
|
/* ------------------------ Defines --------------------------------------- */
|
||||||
|
#define portVECTOR_TABLE __RAMVEC
|
||||||
|
#define portVECTOR_SYSCALL ( 32 + portTRAP_YIELD )
|
||||||
|
#define portVECTOR_TIMER ( 64 + 36 )
|
||||||
|
|
||||||
|
#define MCF_PIT_PRESCALER 512UL
|
||||||
|
#define MCF_PIT_TIMER_TICKS ( FSYS_2 / MCF_PIT_PRESCALER )
|
||||||
|
#define MCF_PIT_MODULUS_REGISTER(freq) ( MCF_PIT_TIMER_TICKS / ( freq ) - 1UL)
|
||||||
|
|
||||||
|
#define MCF_PIT_PMR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150002 ] ) )
|
||||||
|
#define MCF_PIT_PCSR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150000 ] ) )
|
||||||
|
#define MCF_PIT_PCSR_PRE(x) ( ( ( x ) & 0x000F ) << 8 )
|
||||||
|
#define MCF_PIT_PCSR_EN ( 0x0001 )
|
||||||
|
#define MCF_PIT_PCSR_RLD ( 0x0002 )
|
||||||
|
#define MCF_PIT_PCSR_PIF ( 0x0004 )
|
||||||
|
#define MCF_PIT_PCSR_PIE ( 0x0008 )
|
||||||
|
#define MCF_PIT_PCSR_OVW ( 0x0010 )
|
||||||
|
#define MCF_INTC0_ICR36 ( *( vuint8 * )( void * )( &__IPSBAR[ 0x000C64 ] ) )
|
||||||
|
#define MCF_INTC0_IMRH ( *( vuint32 * )( void * )( &__IPSBAR[ 0x000C08 ] ) )
|
||||||
|
#define MCF_INTC0_IMRH_INT_MASK36 ( 0x00000010 )
|
||||||
|
#define MCF_INTC0_IMRH_MASKALL ( 0x00000001 )
|
||||||
|
#define MCF_INTC0_ICRn_IP(x) ( ( ( x ) & 0x07 ) << 0 )
|
||||||
|
#define MCF_INTC0_ICRn_IL(x) ( ( ( x ) & 0x07 ) << 3 )
|
||||||
|
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
#define portINITIAL_CRITICAL_NESTING ( ( unsigned long ) 10 )
|
||||||
|
|
||||||
|
/* ------------------------ Static variables ------------------------------ */
|
||||||
|
volatile unsigned long ulCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
|
|
||||||
|
/* ------------------------ Static functions ------------------------------ */
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
static void prvPortPreemptiveTick ( void ) __attribute__ ((interrupt_handler));
|
||||||
|
#else
|
||||||
|
static void prvPortPreemptiveTick ( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------------ Start implementation -------------------------- */
|
||||||
|
|
||||||
|
portSTACK_TYPE *
|
||||||
|
pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode,
|
||||||
|
void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Place the parameter on the stack in the expected location. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Place dummy return address on stack. Tasks should never terminate so
|
||||||
|
* we can set this to anything. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Create a Motorola Coldfire exception stack frame. First comes the return
|
||||||
|
* address. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Format, fault-status, vector number for exception stack frame. Task
|
||||||
|
* run in supervisor mode. */
|
||||||
|
*pxTopOfStack = 0x40002000UL | ( portVECTOR_SYSCALL + 32 ) << 18;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Set the initial critical section nesting counter to zero. This value
|
||||||
|
* is used to restore the value of ulCriticalNesting. */
|
||||||
|
*pxTopOfStack = 0;
|
||||||
|
*pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA6; /* A6 / FP */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA5; /* A5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA4; /* A4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA3; /* A3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA2; /* A2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA1; /* A1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xA0; /* A0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD7; /* D7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD6; /* D6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD5; /* D5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD4; /* D4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD3; /* D3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD2; /* D2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD1; /* D1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xD0; /* D0 */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
prvPortYield( void )
|
||||||
|
{
|
||||||
|
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
||||||
|
#if _GCC_USES_FP == 1
|
||||||
|
asm volatile ( "unlk %fp\n\t" );
|
||||||
|
#endif
|
||||||
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT( );
|
||||||
|
|
||||||
|
/* Find the highest priority task that is ready to run. */
|
||||||
|
vTaskSwitchContext( );
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT( );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
/*
|
||||||
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
|
* the preemptive scheduler is being used.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
prvPortPreemptiveTick ( void )
|
||||||
|
{
|
||||||
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
|
* simply increment the system tick.
|
||||||
|
*/
|
||||||
|
|
||||||
|
vTaskIncrementTick( );
|
||||||
|
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void
|
||||||
|
prvPortPreemptiveTick( void )
|
||||||
|
{
|
||||||
|
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
||||||
|
#if _GCC_USES_FP == 1
|
||||||
|
asm volatile ( "unlk %fp\n\t" );
|
||||||
|
#endif
|
||||||
|
portSAVE_CONTEXT( );
|
||||||
|
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
||||||
|
vTaskIncrementTick( );
|
||||||
|
vTaskSwitchContext( );
|
||||||
|
portRESTORE_CONTEXT( );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
vPortEnterCritical()
|
||||||
|
{
|
||||||
|
/* FIXME: We should store the old IPL here - How are we supposed to do
|
||||||
|
* this.
|
||||||
|
*/
|
||||||
|
( void )portSET_IPL( portIPL_MAX );
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
* portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vPortExitCritical()
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
( void )portSET_IPL( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
portBASE_TYPE
|
||||||
|
xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void ( *portVECTOR_TABLE[ ] ) ( );
|
||||||
|
|
||||||
|
/* Add entry in vector table for yield system call. */
|
||||||
|
portVECTOR_TABLE[ portVECTOR_SYSCALL ] = prvPortYield;
|
||||||
|
/* Add entry in vector table for periodic timer. */
|
||||||
|
portVECTOR_TABLE[ portVECTOR_TIMER ] = prvPortPreemptiveTick;
|
||||||
|
|
||||||
|
/* Configure the timer for the system clock. */
|
||||||
|
if ( configTICK_RATE_HZ > 0)
|
||||||
|
{
|
||||||
|
/* Configure prescaler */
|
||||||
|
MCF_PIT_PCSR0 = MCF_PIT_PCSR_PRE( 0x9 ) | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_OVW;
|
||||||
|
/* Initialize the periodic timer interrupt. */
|
||||||
|
MCF_PIT_PMR0 = MCF_PIT_MODULUS_REGISTER( configTICK_RATE_HZ );
|
||||||
|
/* Configure interrupt priority and level and unmask interrupt. */
|
||||||
|
MCF_INTC0_ICR36 = MCF_INTC0_ICRn_IL( 0x1 ) | MCF_INTC0_ICRn_IP( 0x1 );
|
||||||
|
MCF_INTC0_IMRH &= ~( MCF_INTC0_IMRH_INT_MASK36 | MCF_INTC0_IMRH_MASKALL );
|
||||||
|
/* Enable interrupts */
|
||||||
|
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_EN | MCF_PIT_PCSR_PIF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
portRESTORE_CONTEXT( );
|
||||||
|
|
||||||
|
/* Should not get here. */
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||||
|
MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License** as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with FreeRTOS; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
A special exception to the GPL can be applied should you wish to distribute
|
||||||
|
a combined work that includes FreeRTOS, without being obliged to provide
|
||||||
|
the source code for any proprietary components. See the licensing section
|
||||||
|
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||||
|
can be applied.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* This is a concise, step by step, 'hands on' guide that describes both *
|
||||||
|
* general multitasking concepts and FreeRTOS specifics. It presents and *
|
||||||
|
* explains numerous examples that are written using the FreeRTOS API. *
|
||||||
|
* Full source code for all the examples is provided in an accompanying *
|
||||||
|
* .zip file. *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
Please ensure to read the configuration and relevant port sections of the
|
||||||
|
online documentation.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------------ Data types for Coldfire ----------------------- */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned int
|
||||||
|
#define portBASE_TYPE int
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------------ Architecture specifics ------------------------ */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
|
||||||
|
#define portTRAP_YIELD 0 /* Trap 0 */
|
||||||
|
#define portIPL_MAX 7 /* Only NMI interrupt 7 allowed. */
|
||||||
|
|
||||||
|
/* ------------------------ FreeRTOS macros for port ---------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function must be called when the current state of the active task
|
||||||
|
* should be stored. It must be called immediately after exception
|
||||||
|
* processing from the CPU, i.e. there exists a Coldfire exception frame at
|
||||||
|
* the current position in the stack. The function reserves space on
|
||||||
|
* the stack for the CPU registers and other task dependent values (e.g
|
||||||
|
* ulCriticalNesting) and updates the top of the stack in the TCB.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
asm volatile ( /* reserve space for task state. */ \
|
||||||
|
"lea.l (-64, %sp), %sp\n\t" \
|
||||||
|
/* push data register %d0-%d7/%a0-%a6 on stack. */ \
|
||||||
|
"movem.l %d0-%d7/%a0-%a6, (%sp)\n\t" \
|
||||||
|
/* push ulCriticalNesting counter on stack. */ \
|
||||||
|
"lea.l (60, %sp), %a0\n\t" \
|
||||||
|
"move.l ulCriticalNesting, (%a0)\n\t" \
|
||||||
|
/* set the new top of the stack in the TCB. */ \
|
||||||
|
"move.l pxCurrentTCB, %a0\n\t" \
|
||||||
|
"move.l %sp, (%a0)");
|
||||||
|
|
||||||
|
/*.
|
||||||
|
* This function restores the current active and continues its execution.
|
||||||
|
* It loads the current TCB and restores the processor registers, the
|
||||||
|
* task dependent values (e.g ulCriticalNesting). Finally execution
|
||||||
|
* is continued by executing an rte instruction.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
asm volatile ( "move.l pxCurrentTCB, %sp\n\t" \
|
||||||
|
"move.l (%sp), %sp\n\t" \
|
||||||
|
/* stack pointer now points to the saved registers. */ \
|
||||||
|
"movem.l (%sp), %d0-%d7/%a0-%a6\n\t" \
|
||||||
|
/* restore ulCriticalNesting counter from stack. */ \
|
||||||
|
"lea.l (%sp, 60), %sp\n\t" \
|
||||||
|
"move.l (%sp)+, ulCriticalNesting\n\t" \
|
||||||
|
/* stack pointer now points to exception frame. */ \
|
||||||
|
"rte\n\t" );
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() \
|
||||||
|
vPortEnterCritical();
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() \
|
||||||
|
vPortExitCritical();
|
||||||
|
|
||||||
|
#define portSET_IPL( xIPL ) \
|
||||||
|
asm_set_ipl( xIPL )
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
do { ( void )portSET_IPL( portIPL_MAX ); } while( 0 )
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
do { ( void )portSET_IPL( 0 ); } while( 0 )
|
||||||
|
|
||||||
|
#define portYIELD() \
|
||||||
|
asm volatile ( " trap %0\n\t" : : "i"(portTRAP_YIELD) )
|
||||||
|
|
||||||
|
#define portNOP() \
|
||||||
|
asm volatile ( "nop\n\t" )
|
||||||
|
|
||||||
|
#define portENTER_SWITCHING_ISR() \
|
||||||
|
asm volatile ( "move.w #0x2700, %sr" ); \
|
||||||
|
/* Save the context of the interrupted task. */ \
|
||||||
|
portSAVE_CONTEXT( ); \
|
||||||
|
{
|
||||||
|
|
||||||
|
#define portEXIT_SWITCHING_ISR( SwitchRequired ) \
|
||||||
|
/* If a switch is required we call vTaskSwitchContext(). */ \
|
||||||
|
if( SwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
vTaskSwitchContext( ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
portRESTORE_CONTEXT( );
|
||||||
|
|
||||||
|
/* ------------------------ Function prototypes --------------------------- */
|
||||||
|
void vPortEnterCritical( void );
|
||||||
|
void vPortExitCritical( void );
|
||||||
|
int asm_set_ipl( unsigned long int uiNewIPL );
|
||||||
|
|
||||||
|
/* ------------------------ Compiler specifics ---------------------------- */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
|
||||||
|
void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) \
|
||||||
|
void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.5.2
|
||||||
|
|
||||||
|
+ usCriticalNesting now has a volatile qualifier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the MSP430 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
|
not the MCLK. */
|
||||||
|
#define portACLK_FREQUENCY_HZ ( ( portTickType ) 32768 )
|
||||||
|
#define portINITIAL_CRITICAL_NESTING ( ( unsigned short ) 10 )
|
||||||
|
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x08 )
|
||||||
|
|
||||||
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
|
any details of its type. */
|
||||||
|
typedef void tskTCB;
|
||||||
|
extern volatile tskTCB * volatile pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Most ports implement critical sections by placing the interrupt flags on
|
||||||
|
the stack before disabling interrupts. Exiting the critical section is then
|
||||||
|
simply a case of popping the flags from the stack. As mspgcc does not use
|
||||||
|
a frame pointer this cannot be done as modifying the stack will clobber all
|
||||||
|
the stack variables. Instead each task maintains a count of the critical
|
||||||
|
section nesting depth. Each time a critical section is entered the count is
|
||||||
|
incremented. Each time a critical section is left the count is decremented -
|
||||||
|
with interrupts only being re-enabled if the count is zero.
|
||||||
|
|
||||||
|
usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
|
not be initialised to zero as this will cause problems during the startup
|
||||||
|
sequence. */
|
||||||
|
volatile unsigned short usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro to save a task context to the task stack. This simply pushes all the
|
||||||
|
* general purpose msp430 registers onto the stack, followed by the
|
||||||
|
* usCriticalNesting value used by the task. Finally the resultant stack
|
||||||
|
* pointer value is saved into the task control block so it can be retrieved
|
||||||
|
* the next time the task executes.
|
||||||
|
*/
|
||||||
|
#define portSAVE_CONTEXT() \
|
||||||
|
asm volatile ( "push r4 \n\t" \
|
||||||
|
"push r5 \n\t" \
|
||||||
|
"push r6 \n\t" \
|
||||||
|
"push r7 \n\t" \
|
||||||
|
"push r8 \n\t" \
|
||||||
|
"push r9 \n\t" \
|
||||||
|
"push r10 \n\t" \
|
||||||
|
"push r11 \n\t" \
|
||||||
|
"push r12 \n\t" \
|
||||||
|
"push r13 \n\t" \
|
||||||
|
"push r14 \n\t" \
|
||||||
|
"push r15 \n\t" \
|
||||||
|
"mov.w usCriticalNesting, r14 \n\t" \
|
||||||
|
"push r14 \n\t" \
|
||||||
|
"mov.w pxCurrentTCB, r12 \n\t" \
|
||||||
|
"mov.w r1, @r12 \n\t" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro to restore a task context from the task stack. This is effectively
|
||||||
|
* the reverse of portSAVE_CONTEXT(). First the stack pointer value is
|
||||||
|
* loaded from the task control block. Next the value for usCriticalNesting
|
||||||
|
* used by the task is retrieved from the stack - followed by the value of all
|
||||||
|
* the general purpose msp430 registers.
|
||||||
|
*
|
||||||
|
* The bic instruction ensures there are no low power bits set in the status
|
||||||
|
* register that is about to be popped from the stack.
|
||||||
|
*/
|
||||||
|
#define portRESTORE_CONTEXT() \
|
||||||
|
asm volatile ( "mov.w pxCurrentTCB, r12 \n\t" \
|
||||||
|
"mov.w @r12, r1 \n\t" \
|
||||||
|
"pop r15 \n\t" \
|
||||||
|
"mov.w r15, usCriticalNesting \n\t" \
|
||||||
|
"pop r15 \n\t" \
|
||||||
|
"pop r14 \n\t" \
|
||||||
|
"pop r13 \n\t" \
|
||||||
|
"pop r12 \n\t" \
|
||||||
|
"pop r11 \n\t" \
|
||||||
|
"pop r10 \n\t" \
|
||||||
|
"pop r9 \n\t" \
|
||||||
|
"pop r8 \n\t" \
|
||||||
|
"pop r7 \n\t" \
|
||||||
|
"pop r6 \n\t" \
|
||||||
|
"pop r5 \n\t" \
|
||||||
|
"pop r4 \n\t" \
|
||||||
|
"bic #(0xf0),0(r1) \n\t" \
|
||||||
|
"reti \n\t" \
|
||||||
|
);
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
|
||||||
|
* could have alternatively used the watchdog timer or timer 1.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See the header file portable.h.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is just useful for debugging and can be included if required.
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x3333;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The msp430 automatically pushes the PC then SR onto the stack before
|
||||||
|
executing an ISR. We want the stack to look just as if this has happened
|
||||||
|
so place a pointer to the start of the task on the stack first - followed
|
||||||
|
by the flags we want the task to use when it starts up. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Next the general purpose registers. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x4444;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x5555;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x6666;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x7777;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x8888;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x9999;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaa;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xbbbb;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xcccc;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xdddd;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xeeee;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R15. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The code generated by the mspgcc compiler does not maintain separate
|
||||||
|
stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
|
||||||
|
use the stack as per other ports. Instead a variable is used to keep
|
||||||
|
track of the critical section nesting. This variable has to be stored
|
||||||
|
as part of the task context and is initially set to zero. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
|
be stored in the task control block for the task. */
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
|
this function is called. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
/* Should not get here as the tasks are now running! */
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
|
disable the tick interrupt here. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch called by portYIELD or taskYIELD.
|
||||||
|
*
|
||||||
|
* The first thing we do is save the registers so we can use a naked attribute.
|
||||||
|
*/
|
||||||
|
void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
/* We want the stack of the task being saved to look exactly as if the task
|
||||||
|
was saved during a pre-emptive RTOS tick ISR. Before calling an ISR the
|
||||||
|
msp430 places the status register onto the stack. As this is a function
|
||||||
|
call and not an ISR we have to do this manually. */
|
||||||
|
asm volatile ( "push r2" );
|
||||||
|
_DINT();
|
||||||
|
|
||||||
|
/* Save the context of the current task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Switch to the highest priority task that is ready to run. */
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initialisation to generate the RTOS tick. This uses timer 0
|
||||||
|
* but could alternatively use the watchdog timer or timer 1.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Ensure the timer is stopped. */
|
||||||
|
TACTL = 0;
|
||||||
|
|
||||||
|
/* Run the timer of the ACLK. */
|
||||||
|
TACTL = TASSEL_1;
|
||||||
|
|
||||||
|
/* Clear everything to start with. */
|
||||||
|
TACTL |= TACLR;
|
||||||
|
|
||||||
|
/* Set the compare match value according to the tick rate we want. */
|
||||||
|
TACCR0 = portACLK_FREQUENCY_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
/* Enable the interrupts. */
|
||||||
|
TACCTL0 = CCIE;
|
||||||
|
|
||||||
|
/* Start up clean. */
|
||||||
|
TACTL |= TACLR;
|
||||||
|
|
||||||
|
/* Up mode. */
|
||||||
|
TACTL |= MC_1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt service routine used depends on whether the pre-emptive
|
||||||
|
* scheduler is being used or not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
||||||
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
|
* count is incremented after the context is saved.
|
||||||
|
*/
|
||||||
|
interrupt (TIMERA0_VECTOR) prvTickISR( void ) __attribute__ ( ( naked ) );
|
||||||
|
interrupt (TIMERA0_VECTOR) prvTickISR( void )
|
||||||
|
{
|
||||||
|
/* Save the context of the interrupted task. */
|
||||||
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
|
/* Increment the tick count then switch to the highest priority task
|
||||||
|
that is ready to run. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
vTaskSwitchContext();
|
||||||
|
|
||||||
|
/* Restore the context of the new task. */
|
||||||
|
portRESTORE_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
|
* manual calls to taskYIELD();
|
||||||
|
*/
|
||||||
|
interrupt (TIMERA0_VECTOR) prvTickISR( void );
|
||||||
|
interrupt (TIMERA0_VECTOR) prvTickISR( void )
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT int
|
||||||
|
#define portSTACK_TYPE unsigned portSHORT
|
||||||
|
#define portBASE_TYPE portSHORT
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Interrupt control macros. */
|
||||||
|
#define portDISABLE_INTERRUPTS() asm volatile ( "DINT" ); asm volatile ( "NOP" )
|
||||||
|
#define portENABLE_INTERRUPTS() asm volatile ( "EINT" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section control macros. */
|
||||||
|
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned portSHORT ) 0 )
|
||||||
|
|
||||||
|
#define portENTER_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portSHORT usCriticalNesting; \
|
||||||
|
\
|
||||||
|
portDISABLE_INTERRUPTS(); \
|
||||||
|
\
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed */ \
|
||||||
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
|
usCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() \
|
||||||
|
{ \
|
||||||
|
extern volatile unsigned portSHORT usCriticalNesting; \
|
||||||
|
\
|
||||||
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
|
{ \
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */ \
|
||||||
|
usCriticalNesting--; \
|
||||||
|
\
|
||||||
|
/* If the nesting level has reached zero then interrupts should be */ \
|
||||||
|
/* re-enabled. */ \
|
||||||
|
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
|
{ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
extern void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardwware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 2
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Hardware includes. */
|
||||||
|
#include <xintc.h>
|
||||||
|
#include <xintc_i.h>
|
||||||
|
#include <xtmrctr.h>
|
||||||
|
|
||||||
|
/* Tasks are started with interrupts enabled. */
|
||||||
|
#define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 )
|
||||||
|
|
||||||
|
/* Tasks are started with a critical section nesting of 0 - however prior
|
||||||
|
to the scheduler being commenced we don't want the critical nesting level
|
||||||
|
to reach zero, so it is initialised to a high value. */
|
||||||
|
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||||
|
|
||||||
|
/* Our hardware setup only uses one counter. */
|
||||||
|
#define portCOUNTER_0 0
|
||||||
|
|
||||||
|
/* The stack used by the ISR is filled with a known value to assist in
|
||||||
|
debugging. */
|
||||||
|
#define portISR_STACK_FILL_VALUE 0x55555555
|
||||||
|
|
||||||
|
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||||
|
maintains it's own count, so this variable is saved as part of the task
|
||||||
|
context. */
|
||||||
|
volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||||
|
|
||||||
|
/* To limit the amount of stack required by each task, this port uses a
|
||||||
|
separate stack for interrupts. */
|
||||||
|
unsigned long *pulISRStack;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
|
||||||
|
* could have alternatively used the watchdog timer or timer 1.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been made.
|
||||||
|
*
|
||||||
|
* See the header file portable.h.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||||
|
const unsigned long ulR2 = ( unsigned long ) &_SDA2_BASE_;
|
||||||
|
const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
||||||
|
|
||||||
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is essential for the Microblaze port and these lines must
|
||||||
|
not be omitted. The parameter value will overwrite the
|
||||||
|
0x22222222 value during the function prologue. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x22222222;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x33333333;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* First stack an initial value for the critical section nesting. This
|
||||||
|
is initialised to zero as tasks are started with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0. */
|
||||||
|
|
||||||
|
/* Place an initial value for all the general purpose registers. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ulR2; /* R2 - small data area. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;/* R5 contains the function call parameters. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0a; /* R10. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0b; /* R11. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0c; /* R12. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ulR13; /* R13 - small data read write area. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* R14. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0f; /* R15. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R16. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R17. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R18. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R19. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R20. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R21. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R22. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R23. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R24. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R25. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1a; /* R26. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1b; /* R27. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1c; /* R28. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1d; /* R29. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1e; /* R30. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The MSR is stacked between R30 and R31. */
|
||||||
|
*pxTopOfStack = portINITIAL_MSR_STATE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1f; /* R31. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
|
be stored in the task control block for the task. */
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void ( __FreeRTOS_interrupt_Handler )( void );
|
||||||
|
extern void ( vStartFirstTask )( void );
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup the FreeRTOS interrupt handler. Code copied from crt0.s. */
|
||||||
|
asm volatile ( "la r6, r0, __FreeRTOS_interrupt_handler \n\t" \
|
||||||
|
"sw r6, r1, r0 \n\t" \
|
||||||
|
"lhu r7, r1, r0 \n\t" \
|
||||||
|
"shi r7, r0, 0x12 \n\t" \
|
||||||
|
"shi r6, r0, 0x16 " );
|
||||||
|
|
||||||
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
|
this function is called. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Allocate the stack to be used by the interrupt handler. */
|
||||||
|
pulISRStack = ( unsigned long * ) pvPortMalloc( configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ) );
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
if( pulISRStack != NULL )
|
||||||
|
{
|
||||||
|
/* Fill the ISR stack with a known value to facilitate debugging. */
|
||||||
|
memset( pulISRStack, portISR_STACK_FILL_VALUE, configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ) );
|
||||||
|
pulISRStack += ( configMINIMAL_STACK_SIZE - 1 );
|
||||||
|
|
||||||
|
/* Kick off the first task. */
|
||||||
|
vStartFirstTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should not get here as the tasks are now running! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch called by portYIELD or taskYIELD.
|
||||||
|
*/
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
extern void VPortYieldASM( void );
|
||||||
|
|
||||||
|
/* Perform the context switch in a critical section to assure it is
|
||||||
|
not interrupted by the tick ISR. It is not a problem to do this as
|
||||||
|
each task maintains it's own interrupt status. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
/* Jump directly to the yield function to ensure there is no
|
||||||
|
compiler generated prologue code. */
|
||||||
|
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||||
|
"or r0, r0, r0 \n\t" );
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initialisation to generate the RTOS tick.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
XTmrCtr xTimer;
|
||||||
|
const unsigned long ulCounterValue = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
unsigned portBASE_TYPE uxMask;
|
||||||
|
|
||||||
|
/* The OPB timer1 is used to generate the tick. Use the provided library
|
||||||
|
functions to enable the timer and set the tick frequency. */
|
||||||
|
XTmrCtr_mDisable( XPAR_OPB_TIMER_1_BASEADDR, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
|
XTmrCtr_Initialize( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
|
XTmrCtr_mSetLoadReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue );
|
||||||
|
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK );
|
||||||
|
|
||||||
|
/* Set the timer interrupt enable bit while maintaining the other bit
|
||||||
|
states. */
|
||||||
|
uxMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
|
||||||
|
uxMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK;
|
||||||
|
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
|
||||||
|
|
||||||
|
XTmrCtr_Start( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
|
XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK );
|
||||||
|
XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 1 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt handler placed in the interrupt vector when the scheduler is
|
||||||
|
* started. The task context has already been saved when this is called.
|
||||||
|
* This handler determines the interrupt source and calls the relevant
|
||||||
|
* peripheral handler.
|
||||||
|
*/
|
||||||
|
void vTaskISRHandler( void )
|
||||||
|
{
|
||||||
|
static unsigned long ulPending;
|
||||||
|
|
||||||
|
/* Which interrupts are pending? */
|
||||||
|
ulPending = XIntc_In32( ( XPAR_INTC_SINGLE_BASEADDR + XIN_IVR_OFFSET ) );
|
||||||
|
|
||||||
|
if( ulPending < XPAR_INTC_MAX_NUM_INTR_INPUTS )
|
||||||
|
{
|
||||||
|
static XIntc_VectorTableEntry *pxTablePtr;
|
||||||
|
static XIntc_Config *pxConfig;
|
||||||
|
static unsigned long ulInterruptMask;
|
||||||
|
|
||||||
|
ulInterruptMask = ( unsigned long ) 1 << ulPending;
|
||||||
|
|
||||||
|
/* Get the configuration data using the device ID */
|
||||||
|
pxConfig = &XIntc_ConfigTable[ ( unsigned long ) XPAR_INTC_SINGLE_DEVICE_ID ];
|
||||||
|
|
||||||
|
pxTablePtr = &( pxConfig->HandlerTable[ ulPending ] );
|
||||||
|
if( pxConfig->AckBeforeService & ( ulInterruptMask ) )
|
||||||
|
{
|
||||||
|
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
|
||||||
|
pxTablePtr->Handler( pxTablePtr->CallBackRef );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxTablePtr->Handler( pxTablePtr->CallBackRef );
|
||||||
|
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handler for the timer interrupt.
|
||||||
|
*/
|
||||||
|
void vTickISR( void *pvBaseAddress )
|
||||||
|
{
|
||||||
|
unsigned long ulCSR;
|
||||||
|
|
||||||
|
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* Clear the timer interrupt */
|
||||||
|
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
|
||||||
|
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
|
||||||
|
|
||||||
|
/* If we are using the preemptive scheduler then we also need to determine
|
||||||
|
if this tick should cause a context switch. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
vTaskSwitchContext();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
.extern pxCurrentTCB
|
||||||
|
.extern vTaskISRHandler
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
.extern uxCriticalNesting
|
||||||
|
.extern pulISRStack
|
||||||
|
|
||||||
|
.global __FreeRTOS_interrupt_handler
|
||||||
|
.global VPortYieldASM
|
||||||
|
.global vStartFirstTask
|
||||||
|
|
||||||
|
|
||||||
|
.macro portSAVE_CONTEXT
|
||||||
|
/* Make room for the context on the stack. */
|
||||||
|
addik r1, r1, -132
|
||||||
|
/* Save r31 so it can then be used. */
|
||||||
|
swi r31, r1, 4
|
||||||
|
/* Copy the msr into r31 - this is stacked later. */
|
||||||
|
mfs r31, rmsr
|
||||||
|
/* Stack general registers. */
|
||||||
|
swi r30, r1, 12
|
||||||
|
swi r29, r1, 16
|
||||||
|
swi r28, r1, 20
|
||||||
|
swi r27, r1, 24
|
||||||
|
swi r26, r1, 28
|
||||||
|
swi r25, r1, 32
|
||||||
|
swi r24, r1, 36
|
||||||
|
swi r23, r1, 40
|
||||||
|
swi r22, r1, 44
|
||||||
|
swi r21, r1, 48
|
||||||
|
swi r20, r1, 52
|
||||||
|
swi r19, r1, 56
|
||||||
|
swi r18, r1, 60
|
||||||
|
swi r17, r1, 64
|
||||||
|
swi r16, r1, 68
|
||||||
|
swi r15, r1, 72
|
||||||
|
swi r13, r1, 80
|
||||||
|
swi r12, r1, 84
|
||||||
|
swi r11, r1, 88
|
||||||
|
swi r10, r1, 92
|
||||||
|
swi r9, r1, 96
|
||||||
|
swi r8, r1, 100
|
||||||
|
swi r7, r1, 104
|
||||||
|
swi r6, r1, 108
|
||||||
|
swi r5, r1, 112
|
||||||
|
swi r4, r1, 116
|
||||||
|
swi r3, r1, 120
|
||||||
|
swi r2, r1, 124
|
||||||
|
/* Stack the critical section nesting value. */
|
||||||
|
lwi r3, r0, uxCriticalNesting
|
||||||
|
swi r3, r1, 128
|
||||||
|
/* Save the top of stack value to the TCB. */
|
||||||
|
lwi r3, r0, pxCurrentTCB
|
||||||
|
sw r1, r0, r3
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_CONTEXT
|
||||||
|
/* Load the top of stack value from the TCB. */
|
||||||
|
lwi r3, r0, pxCurrentTCB
|
||||||
|
lw r1, r0, r3
|
||||||
|
/* Restore the general registers. */
|
||||||
|
lwi r31, r1, 4
|
||||||
|
lwi r30, r1, 12
|
||||||
|
lwi r29, r1, 16
|
||||||
|
lwi r28, r1, 20
|
||||||
|
lwi r27, r1, 24
|
||||||
|
lwi r26, r1, 28
|
||||||
|
lwi r25, r1, 32
|
||||||
|
lwi r24, r1, 36
|
||||||
|
lwi r23, r1, 40
|
||||||
|
lwi r22, r1, 44
|
||||||
|
lwi r21, r1, 48
|
||||||
|
lwi r20, r1, 52
|
||||||
|
lwi r19, r1, 56
|
||||||
|
lwi r18, r1, 60
|
||||||
|
lwi r17, r1, 64
|
||||||
|
lwi r16, r1, 68
|
||||||
|
lwi r15, r1, 72
|
||||||
|
lwi r14, r1, 76
|
||||||
|
lwi r13, r1, 80
|
||||||
|
lwi r12, r1, 84
|
||||||
|
lwi r11, r1, 88
|
||||||
|
lwi r10, r1, 92
|
||||||
|
lwi r9, r1, 96
|
||||||
|
lwi r8, r1, 100
|
||||||
|
lwi r7, r1, 104
|
||||||
|
lwi r6, r1, 108
|
||||||
|
lwi r5, r1, 112
|
||||||
|
lwi r4, r1, 116
|
||||||
|
lwi r2, r1, 124
|
||||||
|
|
||||||
|
/* Load the critical nesting value. */
|
||||||
|
lwi r3, r1, 128
|
||||||
|
swi r3, r0, uxCriticalNesting
|
||||||
|
|
||||||
|
/* Obtain the MSR value from the stack. */
|
||||||
|
lwi r3, r1, 8
|
||||||
|
|
||||||
|
/* Are interrupts enabled in the MSR? If so return using an return from
|
||||||
|
interrupt instruction to ensure interrupts are enabled only once the task
|
||||||
|
is running again. */
|
||||||
|
andi r3, r3, 2
|
||||||
|
beqid r3, 36
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
/* Reload the rmsr from the stack, clear the enable interrupt bit in the
|
||||||
|
value before saving back to rmsr register, then return enabling interrupts
|
||||||
|
as we return. */
|
||||||
|
lwi r3, r1, 8
|
||||||
|
andi r3, r3, ~2
|
||||||
|
mts rmsr, r3
|
||||||
|
lwi r3, r1, 120
|
||||||
|
addik r1, r1, 132
|
||||||
|
rtid r14, 0
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
/* Reload the rmsr from the stack, place it in the rmsr register, and
|
||||||
|
return without enabling interrupts. */
|
||||||
|
lwi r3, r1, 8
|
||||||
|
mts rmsr, r3
|
||||||
|
lwi r3, r1, 120
|
||||||
|
addik r1, r1, 132
|
||||||
|
rtsd r14, 0
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
|
||||||
|
__FreeRTOS_interrupt_handler:
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
/* Entered via an interrupt so interrupts must be enabled in msr. */
|
||||||
|
ori r31, r31, 2
|
||||||
|
/* Stack msr. */
|
||||||
|
swi r31, r1, 8
|
||||||
|
/* Stack the return address. As we entered via an interrupt we do
|
||||||
|
not need to modify the return address prior to stacking. */
|
||||||
|
swi r14, r1, 76
|
||||||
|
/* Now switch to use the ISR stack. */
|
||||||
|
lwi r3, r0, pulISRStack
|
||||||
|
add r1, r3, r0
|
||||||
|
bralid r15, vTaskISRHandler
|
||||||
|
or r0, r0, r0
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
|
||||||
|
VPortYieldASM:
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
/* Stack msr. */
|
||||||
|
swi r31, r1, 8
|
||||||
|
/* Modify the return address so we return to the instruction after the
|
||||||
|
exception. */
|
||||||
|
addi r14, r14, 8
|
||||||
|
swi r14, r1, 76
|
||||||
|
/* Now switch to use the ISR stack. */
|
||||||
|
lwi r3, r0, pulISRStack
|
||||||
|
add r1, r3, r0
|
||||||
|
bralid r15, vTaskSwitchContext
|
||||||
|
or r0, r0, r0
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
vStartFirstTask:
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Interrupt control macros. */
|
||||||
|
void microblaze_disable_interrupts( void );
|
||||||
|
void microblaze_enable_interrupts( void );
|
||||||
|
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||||
|
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section macros. */
|
||||||
|
void vPortEnterCritical( void );
|
||||||
|
void vPortExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() { \
|
||||||
|
extern unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
microblaze_disable_interrupts(); \
|
||||||
|
uxCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() { \
|
||||||
|
extern unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
/* Interrupts are disabled, so we can */ \
|
||||||
|
/* access the variable directly. */ \
|
||||||
|
uxCriticalNesting--; \
|
||||||
|
if( uxCriticalNesting == 0 ) \
|
||||||
|
{ \
|
||||||
|
/* The nesting has unwound and we \
|
||||||
|
can enable interrupts again. */ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
void vPortYield( void );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
|
void vTaskSwitchContext();
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,485 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Hardware includes. */
|
||||||
|
#include <xintc_i.h>
|
||||||
|
#include <xil_exception.h>
|
||||||
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
|
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
||||||
|
the scheduler being commenced interrupts should not be enabled, so the critical
|
||||||
|
nesting variable is initialised to a non-zero value. */
|
||||||
|
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||||
|
|
||||||
|
/* The bit within the MSR register that enabled/disables interrupts. */
|
||||||
|
#define portMSR_IE ( 0x02U )
|
||||||
|
|
||||||
|
/* If the floating point unit is included in the MicroBlaze build, then the
|
||||||
|
FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
||||||
|
given to the FSR register when the initial context is set up for a task being
|
||||||
|
created. */
|
||||||
|
#define portINITIAL_FSR ( 0U )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the interrupt controller instance.
|
||||||
|
*/
|
||||||
|
static long prvInitialiseInterruptController( void );
|
||||||
|
|
||||||
|
/* Ensure the interrupt controller instance variable is initialised before it is
|
||||||
|
* used, and that the initialisation only happens once.
|
||||||
|
*/
|
||||||
|
static long prvEnsureInterruptControllerIsInitialised( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||||
|
maintains its own count, so this variable is saved as part of the task
|
||||||
|
context. */
|
||||||
|
volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||||
|
|
||||||
|
/* This port uses a separate stack for interrupts. This prevents the stack of
|
||||||
|
every task needing to be large enough to hold an entire interrupt stack on top
|
||||||
|
of the task stack. */
|
||||||
|
unsigned long *pulISRStack;
|
||||||
|
|
||||||
|
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
||||||
|
get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
||||||
|
handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
||||||
|
will call vTaskSwitchContext() to ensure the task that runs immediately after
|
||||||
|
the interrupt exists is the highest priority task that is able to run. This is
|
||||||
|
an unusual mechanism, but is used for this port because a single interrupt can
|
||||||
|
cause the servicing of multiple peripherals - and it is inefficient to call
|
||||||
|
vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
||||||
|
volatile unsigned long ulTaskSwitchRequested = 0UL;
|
||||||
|
|
||||||
|
/* The instance of the interrupt controller used by this port. This is required
|
||||||
|
by the Xilinx library API functions. */
|
||||||
|
static XIntc xInterruptControllerInstance;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been made.
|
||||||
|
*
|
||||||
|
* See the portable.h header file.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||||
|
const unsigned long ulR2 = ( unsigned long ) &_SDA2_BASE_;
|
||||||
|
const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
||||||
|
|
||||||
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
|
This is essential for the Microblaze port and these lines must
|
||||||
|
not be omitted. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
/* The FSR value placed in the initial task context is just 0. */
|
||||||
|
*pxTopOfStack = portINITIAL_FSR;
|
||||||
|
pxTopOfStack--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The MSR value placed in the initial task context should have interrupts
|
||||||
|
disabled. Each task will enable interrupts automatically when it enters
|
||||||
|
the running state for the first time. */
|
||||||
|
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* First stack an initial value for the critical section nesting. This
|
||||||
|
is initialised to zero. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
|
||||||
|
|
||||||
|
/* R0 is always zero. */
|
||||||
|
/* R1 is the SP. */
|
||||||
|
|
||||||
|
/* Place an initial value for all the general purpose registers. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ulR2; /* R2 - read only small data area. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 - return values and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 - return values and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;/* R5 contains the function call parameters. */
|
||||||
|
|
||||||
|
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 - other parameters and temporaries. Used as the return address from vPortTaskEntryPoint. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 - other parameters and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 - other parameters and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 - other parameters and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0a; /* R10 - other parameters and temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0b; /* R11 - temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x0c; /* R12 - temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
#else
|
||||||
|
pxTopOfStack-= 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) ulR13; /* R13 - read/write small data area. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* R14 - return address for interrupt. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) NULL; /* R15 - return address for subroutine. */
|
||||||
|
|
||||||
|
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R16 - return address for trap (debugger). */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R17 - return address for exceptions, if configured. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R18 - reserved for assembler and compiler temporaries. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
#else
|
||||||
|
pxTopOfStack -= 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R19 - must be saved across function calls. Callee-save. Seems to be interpreted as the frame pointer. */
|
||||||
|
|
||||||
|
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R20 - reserved for storing a pointer to the Global Offset Table (GOT) in Position Independent Code (PIC). Non-volatile in non-PIC code. Must be saved across function calls. Callee-save. Not used by FreeRTOS. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R21 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R22 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R23 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R24 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R25 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1a; /* R26 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1b; /* R27 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1c; /* R28 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1d; /* R29 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1e; /* R30 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
#else
|
||||||
|
pxTopOfStack -= 13;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Return a pointer to the top of the stack that has been generated so this
|
||||||
|
can be stored in the task control block for the task. */
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void ( vPortStartFirstTask )( void );
|
||||||
|
extern unsigned long _stack[];
|
||||||
|
|
||||||
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
|
this function is called.
|
||||||
|
|
||||||
|
This port uses an application defined callback function to install the tick
|
||||||
|
interrupt handler because the kernel will run on lots of different
|
||||||
|
MicroBlaze and FPGA configurations - not all of which will have the same
|
||||||
|
timer peripherals defined or available. An example definition of
|
||||||
|
vApplicationSetupTimerInterrupt() is provided in the official demo
|
||||||
|
application that accompanies this port. */
|
||||||
|
vApplicationSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
||||||
|
pulISRStack = ( unsigned long * ) _stack;
|
||||||
|
|
||||||
|
/* Ensure there is enough space for the functions called from the interrupt
|
||||||
|
service routines to write back into the stack frame of the caller. */
|
||||||
|
pulISRStack -= 2;
|
||||||
|
|
||||||
|
/* Restore the context of the first task that is going to run. From here
|
||||||
|
on, the created tasks will be executing. */
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here as the tasks are now running! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual context switch called by portYIELD or taskYIELD.
|
||||||
|
*/
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
extern void VPortYieldASM( void );
|
||||||
|
|
||||||
|
/* Perform the context switch in a critical section to assure it is
|
||||||
|
not interrupted by the tick ISR. It is not a problem to do this as
|
||||||
|
each task maintains its own interrupt status. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Jump directly to the yield function to ensure there is no
|
||||||
|
compiler generated prologue code. */
|
||||||
|
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||||
|
"or r0, r0, r0 \n\t" );
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnableInterrupt( unsigned char ucInterruptID )
|
||||||
|
{
|
||||||
|
long lReturn;
|
||||||
|
|
||||||
|
/* An API function is provided to enable an interrupt in the interrupt
|
||||||
|
controller because the interrupt controller instance variable is private
|
||||||
|
to this file. */
|
||||||
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
if( lReturn == pdPASS )
|
||||||
|
{
|
||||||
|
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( lReturn );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortDisableInterrupt( unsigned char ucInterruptID )
|
||||||
|
{
|
||||||
|
long lReturn;
|
||||||
|
|
||||||
|
/* An API function is provided to disable an interrupt in the interrupt
|
||||||
|
controller because the interrupt controller instance variable is private
|
||||||
|
to this file. */
|
||||||
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
|
if( lReturn == pdPASS )
|
||||||
|
{
|
||||||
|
XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( lReturn );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
|
{
|
||||||
|
long lReturn;
|
||||||
|
|
||||||
|
/* An API function is provided to install an interrupt handler because the
|
||||||
|
interrupt controller instance variable is private to this file. */
|
||||||
|
|
||||||
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
|
if( lReturn == pdPASS )
|
||||||
|
{
|
||||||
|
lReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lReturn == XST_SUCCESS )
|
||||||
|
{
|
||||||
|
lReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( lReturn == pdPASS );
|
||||||
|
|
||||||
|
return lReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static long prvEnsureInterruptControllerIsInitialised( void )
|
||||||
|
{
|
||||||
|
static long lInterruptControllerInitialised = pdFALSE;
|
||||||
|
long lReturn;
|
||||||
|
|
||||||
|
/* Ensure the interrupt controller instance variable is initialised before
|
||||||
|
it is used, and that the initialisation only happens once. */
|
||||||
|
if( lInterruptControllerInitialised != pdTRUE )
|
||||||
|
{
|
||||||
|
lReturn = prvInitialiseInterruptController();
|
||||||
|
|
||||||
|
if( lReturn == pdPASS )
|
||||||
|
{
|
||||||
|
lInterruptControllerInitialised = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handler for the timer interrupt. This is the handler that the application
|
||||||
|
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
||||||
|
*/
|
||||||
|
void vPortTickISR( void *pvUnused )
|
||||||
|
{
|
||||||
|
extern void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||||
|
( void ) pvUnused;
|
||||||
|
|
||||||
|
/* This port uses an application defined callback function to clear the tick
|
||||||
|
interrupt because the kernel will run on lots of different MicroBlaze and
|
||||||
|
FPGA configurations - not all of which will have the same timer peripherals
|
||||||
|
defined or available. An example definition of
|
||||||
|
vApplicationClearTimerInterrupt() is provided in the official demo
|
||||||
|
application that accompanies this port. */
|
||||||
|
vApplicationClearTimerInterrupt();
|
||||||
|
|
||||||
|
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* If the preemptive scheduler is being used then a context switch should be
|
||||||
|
requested in case incrementing the tick unblocked a task, or a time slice
|
||||||
|
should cause another task to enter the Running state. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
|
||||||
|
ulTaskSwitchRequested = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static long prvInitialiseInterruptController( void )
|
||||||
|
{
|
||||||
|
long lStatus;
|
||||||
|
|
||||||
|
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||||
|
|
||||||
|
if( lStatus == XST_SUCCESS )
|
||||||
|
{
|
||||||
|
/* Initialise the exception table. */
|
||||||
|
Xil_ExceptionInit();
|
||||||
|
|
||||||
|
/* Service all pending interrupts each time the handler is entered. */
|
||||||
|
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
||||||
|
|
||||||
|
/* Install exception handlers if the MicroBlaze is configured to handle
|
||||||
|
exceptions, and the application defined constant
|
||||||
|
configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
||||||
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
|
{
|
||||||
|
vPortExceptionsInstallHandlers();
|
||||||
|
}
|
||||||
|
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
||||||
|
|
||||||
|
/* Start the interrupt controller. Interrupts are enabled when the
|
||||||
|
scheduler starts. */
|
||||||
|
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||||
|
|
||||||
|
if( lStatus == XST_SUCCESS )
|
||||||
|
{
|
||||||
|
lStatus = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( lStatus == pdPASS );
|
||||||
|
|
||||||
|
return lStatus;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Hardware includes. */
|
||||||
|
#include <microblaze_exceptions_i.h>
|
||||||
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
|
/* The Xilinx library defined exception entry point stacks a number of
|
||||||
|
registers. These definitions are offsets from the stack pointer to the various
|
||||||
|
stacked register values. */
|
||||||
|
#define portexR3_STACK_OFFSET 4
|
||||||
|
#define portexR4_STACK_OFFSET 5
|
||||||
|
#define portexR5_STACK_OFFSET 6
|
||||||
|
#define portexR6_STACK_OFFSET 7
|
||||||
|
#define portexR7_STACK_OFFSET 8
|
||||||
|
#define portexR8_STACK_OFFSET 9
|
||||||
|
#define portexR9_STACK_OFFSET 10
|
||||||
|
#define portexR10_STACK_OFFSET 11
|
||||||
|
#define portexR11_STACK_OFFSET 12
|
||||||
|
#define portexR12_STACK_OFFSET 13
|
||||||
|
#define portexR15_STACK_OFFSET 16
|
||||||
|
#define portexR18_STACK_OFFSET 19
|
||||||
|
#define portexMSR_STACK_OFFSET 20
|
||||||
|
#define portexR19_STACK_OFFSET -1
|
||||||
|
|
||||||
|
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
||||||
|
the Xilinx standard library exception entry point. It is required to determine
|
||||||
|
the stack pointer value prior to the exception being entered. */
|
||||||
|
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
||||||
|
|
||||||
|
/* The number of bytes a MicroBlaze instruction consumes. */
|
||||||
|
#define portexINSTRUCTION_SIZE 4
|
||||||
|
|
||||||
|
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
||||||
|
exceptions, or the application defined configuration constant
|
||||||
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
|
|
||||||
|
/* This variable is set in the exception entry code, before
|
||||||
|
vPortExceptionHandler is called. */
|
||||||
|
unsigned long *pulStackPointerOnFunctionEntry = NULL;
|
||||||
|
|
||||||
|
/* This is the structure that is filled with the MicroBlaze context as it
|
||||||
|
existed immediately prior to the exception occurrence. A pointer to this
|
||||||
|
structure is passed into the vApplicationExceptionRegisterDump() callback
|
||||||
|
function, if one is defined. */
|
||||||
|
static xPortRegisterDump xRegisterDump;
|
||||||
|
|
||||||
|
/* This is the FreeRTOS exception handler that is installed for all exception
|
||||||
|
types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
||||||
|
in portasm.S. */
|
||||||
|
void vPortExceptionHandler( void *pvExceptionID );
|
||||||
|
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
|
application can optionally define to receive a populated xPortRegisterDump
|
||||||
|
structure. If the application chooses not to define a version of
|
||||||
|
vApplicationExceptionRegisterDump() then this weekly defined default
|
||||||
|
implementation will be called instead. */
|
||||||
|
extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
|
||||||
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
|
||||||
|
{
|
||||||
|
( void ) xRegisterDump;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
portNOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExceptionHandler( void *pvExceptionID )
|
||||||
|
{
|
||||||
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
|
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
||||||
|
was immediately before the exception occurrence. */
|
||||||
|
|
||||||
|
/* First fill in the name and handle of the task that was in the Running
|
||||||
|
state when the exception occurred. */
|
||||||
|
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
||||||
|
xRegisterDump.pcCurrentTaskName = pcTaskGetTaskName( NULL );
|
||||||
|
|
||||||
|
configASSERT( pulStackPointerOnFunctionEntry );
|
||||||
|
|
||||||
|
/* Obtain the values of registers that were stacked prior to this function
|
||||||
|
being called, and may have changed since they were stacked. */
|
||||||
|
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR6 = pulStackPointerOnFunctionEntry[ portexR6_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR7 = pulStackPointerOnFunctionEntry[ portexR7_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR8 = pulStackPointerOnFunctionEntry[ portexR8_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR9 = pulStackPointerOnFunctionEntry[ portexR9_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
|
||||||
|
xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
|
||||||
|
|
||||||
|
/* Obtain the value of all other registers. */
|
||||||
|
xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
|
||||||
|
xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );
|
||||||
|
xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );
|
||||||
|
xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );
|
||||||
|
xRegisterDump.ulR17_return_address_from_exceptions = mfgpr( R17 );
|
||||||
|
xRegisterDump.ulR20 = mfgpr( R20 );
|
||||||
|
xRegisterDump.ulR21 = mfgpr( R21 );
|
||||||
|
xRegisterDump.ulR22 = mfgpr( R22 );
|
||||||
|
xRegisterDump.ulR23 = mfgpr( R23 );
|
||||||
|
xRegisterDump.ulR24 = mfgpr( R24 );
|
||||||
|
xRegisterDump.ulR25 = mfgpr( R25 );
|
||||||
|
xRegisterDump.ulR26 = mfgpr( R26 );
|
||||||
|
xRegisterDump.ulR27 = mfgpr( R27 );
|
||||||
|
xRegisterDump.ulR28 = mfgpr( R28 );
|
||||||
|
xRegisterDump.ulR29 = mfgpr( R29 );
|
||||||
|
xRegisterDump.ulR30 = mfgpr( R30 );
|
||||||
|
xRegisterDump.ulR31 = mfgpr( R31 );
|
||||||
|
xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;
|
||||||
|
xRegisterDump.ulEAR = mfear();
|
||||||
|
xRegisterDump.ulESR = mfesr();
|
||||||
|
xRegisterDump.ulEDR = mfedr();
|
||||||
|
|
||||||
|
/* Move the saved program counter back to the instruction that was executed
|
||||||
|
when the exception occurred. This is only valid for certain types of
|
||||||
|
exception. */
|
||||||
|
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
{
|
||||||
|
xRegisterDump.ulFSR = mffsr();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
xRegisterDump.ulFSR = 0UL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Also fill in a string that describes what type of exception this is.
|
||||||
|
The string uses the same ID names as defined in the MicroBlaze standard
|
||||||
|
library exception header files. */
|
||||||
|
switch( ( unsigned long ) pvExceptionID )
|
||||||
|
{
|
||||||
|
case XEXC_ID_FSL :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FSL";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_UNALIGNED_ACCESS :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_ILLEGAL_OPCODE :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_M_AXI_I_EXCEPTION :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_M_AXI_D_EXCEPTION :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_DIV_BY_ZERO :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_DIV_BY_ZERO";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XEXC_ID_STACK_VIOLATION :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
|
||||||
|
case XEXC_ID_FPU :
|
||||||
|
xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU see ulFSR value";
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_USE_FPU */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
|
application can optionally define to receive the populated xPortRegisterDump
|
||||||
|
structure. If the application chooses not to define a version of
|
||||||
|
vApplicationExceptionRegisterDump() then the weekly defined default
|
||||||
|
implementation within this file will be called instead. */
|
||||||
|
vApplicationExceptionRegisterDump( &xRegisterDump );
|
||||||
|
|
||||||
|
/* Must not attempt to leave this function! */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
portNOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExceptionsInstallHandlers( void )
|
||||||
|
{
|
||||||
|
static unsigned long ulHandlersAlreadyInstalled = pdFALSE;
|
||||||
|
|
||||||
|
if( ulHandlersAlreadyInstalled == pdFALSE )
|
||||||
|
{
|
||||||
|
ulHandlersAlreadyInstalled = pdTRUE;
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_ILLEGAL_OPCODE, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_ILLEGAL_OPCODE );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_M_AXI_I_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_I_EXCEPTION );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_M_AXI_D_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_D_EXCEPTION );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_IPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_IPLB_EXCEPTION );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_DPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DPLB_EXCEPTION );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_DIV_BY_ZERO, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DIV_BY_ZERO );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_FPU_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_FPU, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FPU );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_FPU_EXCEPTION*/
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_FSL_EXCEPTION == 1
|
||||||
|
microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );
|
||||||
|
#endif /* XPAR_MICROBLAZE_0_FSL_EXCEPTION*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
||||||
|
exceptions, or the application defined configuration item
|
||||||
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
|
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,369 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Xilinx library includes. */
|
||||||
|
#include "microblaze_exceptions_g.h"
|
||||||
|
#include "xparameters.h"
|
||||||
|
|
||||||
|
/* The context is oversized to allow functions called from the ISR to write
|
||||||
|
back into the caller stack. */
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
#define portCONTEXT_SIZE 136
|
||||||
|
#define portMINUS_CONTEXT_SIZE -136
|
||||||
|
#else
|
||||||
|
#define portCONTEXT_SIZE 132
|
||||||
|
#define portMINUS_CONTEXT_SIZE -132
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Offsets from the stack pointer at which saved registers are placed. */
|
||||||
|
#define portR31_OFFSET 4
|
||||||
|
#define portR30_OFFSET 8
|
||||||
|
#define portR29_OFFSET 12
|
||||||
|
#define portR28_OFFSET 16
|
||||||
|
#define portR27_OFFSET 20
|
||||||
|
#define portR26_OFFSET 24
|
||||||
|
#define portR25_OFFSET 28
|
||||||
|
#define portR24_OFFSET 32
|
||||||
|
#define portR23_OFFSET 36
|
||||||
|
#define portR22_OFFSET 40
|
||||||
|
#define portR21_OFFSET 44
|
||||||
|
#define portR20_OFFSET 48
|
||||||
|
#define portR19_OFFSET 52
|
||||||
|
#define portR18_OFFSET 56
|
||||||
|
#define portR17_OFFSET 60
|
||||||
|
#define portR16_OFFSET 64
|
||||||
|
#define portR15_OFFSET 68
|
||||||
|
#define portR14_OFFSET 72
|
||||||
|
#define portR13_OFFSET 76
|
||||||
|
#define portR12_OFFSET 80
|
||||||
|
#define portR11_OFFSET 84
|
||||||
|
#define portR10_OFFSET 88
|
||||||
|
#define portR9_OFFSET 92
|
||||||
|
#define portR8_OFFSET 96
|
||||||
|
#define portR7_OFFSET 100
|
||||||
|
#define portR6_OFFSET 104
|
||||||
|
#define portR5_OFFSET 108
|
||||||
|
#define portR4_OFFSET 112
|
||||||
|
#define portR3_OFFSET 116
|
||||||
|
#define portR2_OFFSET 120
|
||||||
|
#define portCRITICAL_NESTING_OFFSET 124
|
||||||
|
#define portMSR_OFFSET 128
|
||||||
|
#define portFSR_OFFSET 132
|
||||||
|
|
||||||
|
.extern pxCurrentTCB
|
||||||
|
.extern XIntc_DeviceInterruptHandler
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
.extern uxCriticalNesting
|
||||||
|
.extern pulISRStack
|
||||||
|
.extern ulTaskSwitchRequested
|
||||||
|
.extern vPortExceptionHandler
|
||||||
|
.extern pulStackPointerOnFunctionEntry
|
||||||
|
|
||||||
|
.global _interrupt_handler
|
||||||
|
.global VPortYieldASM
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global vPortExceptionHandlerEntry
|
||||||
|
|
||||||
|
|
||||||
|
.macro portSAVE_CONTEXT
|
||||||
|
|
||||||
|
/* Make room for the context on the stack. */
|
||||||
|
addik r1, r1, portMINUS_CONTEXT_SIZE
|
||||||
|
|
||||||
|
/* Stack general registers. */
|
||||||
|
swi r31, r1, portR31_OFFSET
|
||||||
|
swi r30, r1, portR30_OFFSET
|
||||||
|
swi r29, r1, portR29_OFFSET
|
||||||
|
swi r28, r1, portR28_OFFSET
|
||||||
|
swi r27, r1, portR27_OFFSET
|
||||||
|
swi r26, r1, portR26_OFFSET
|
||||||
|
swi r25, r1, portR25_OFFSET
|
||||||
|
swi r24, r1, portR24_OFFSET
|
||||||
|
swi r23, r1, portR23_OFFSET
|
||||||
|
swi r22, r1, portR22_OFFSET
|
||||||
|
swi r21, r1, portR21_OFFSET
|
||||||
|
swi r20, r1, portR20_OFFSET
|
||||||
|
swi r19, r1, portR19_OFFSET
|
||||||
|
swi r18, r1, portR18_OFFSET
|
||||||
|
swi r17, r1, portR17_OFFSET
|
||||||
|
swi r16, r1, portR16_OFFSET
|
||||||
|
swi r15, r1, portR15_OFFSET
|
||||||
|
/* R14 is saved later as it needs adjustment if a yield is performed. */
|
||||||
|
swi r13, r1, portR13_OFFSET
|
||||||
|
swi r12, r1, portR12_OFFSET
|
||||||
|
swi r11, r1, portR11_OFFSET
|
||||||
|
swi r10, r1, portR10_OFFSET
|
||||||
|
swi r9, r1, portR9_OFFSET
|
||||||
|
swi r8, r1, portR8_OFFSET
|
||||||
|
swi r7, r1, portR7_OFFSET
|
||||||
|
swi r6, r1, portR6_OFFSET
|
||||||
|
swi r5, r1, portR5_OFFSET
|
||||||
|
swi r4, r1, portR4_OFFSET
|
||||||
|
swi r3, r1, portR3_OFFSET
|
||||||
|
swi r2, r1, portR2_OFFSET
|
||||||
|
|
||||||
|
/* Stack the critical section nesting value. */
|
||||||
|
lwi r18, r0, uxCriticalNesting
|
||||||
|
swi r18, r1, portCRITICAL_NESTING_OFFSET
|
||||||
|
|
||||||
|
/* Stack MSR. */
|
||||||
|
mfs r18, rmsr
|
||||||
|
swi r18, r1, portMSR_OFFSET
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
/* Stack FSR. */
|
||||||
|
mfs r18, rfsr
|
||||||
|
swi r18, r1, portFSR_OFFSET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Save the top of stack value to the TCB. */
|
||||||
|
lwi r3, r0, pxCurrentTCB
|
||||||
|
sw r1, r0, r3
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
/* Load the top of stack value from the TCB. */
|
||||||
|
lwi r18, r0, pxCurrentTCB
|
||||||
|
lw r1, r0, r18
|
||||||
|
|
||||||
|
/* Restore the general registers. */
|
||||||
|
lwi r31, r1, portR31_OFFSET
|
||||||
|
lwi r30, r1, portR30_OFFSET
|
||||||
|
lwi r29, r1, portR29_OFFSET
|
||||||
|
lwi r28, r1, portR28_OFFSET
|
||||||
|
lwi r27, r1, portR27_OFFSET
|
||||||
|
lwi r26, r1, portR26_OFFSET
|
||||||
|
lwi r25, r1, portR25_OFFSET
|
||||||
|
lwi r24, r1, portR24_OFFSET
|
||||||
|
lwi r23, r1, portR23_OFFSET
|
||||||
|
lwi r22, r1, portR22_OFFSET
|
||||||
|
lwi r21, r1, portR21_OFFSET
|
||||||
|
lwi r20, r1, portR20_OFFSET
|
||||||
|
lwi r19, r1, portR19_OFFSET
|
||||||
|
lwi r17, r1, portR17_OFFSET
|
||||||
|
lwi r16, r1, portR16_OFFSET
|
||||||
|
lwi r15, r1, portR15_OFFSET
|
||||||
|
lwi r14, r1, portR14_OFFSET
|
||||||
|
lwi r13, r1, portR13_OFFSET
|
||||||
|
lwi r12, r1, portR12_OFFSET
|
||||||
|
lwi r11, r1, portR11_OFFSET
|
||||||
|
lwi r10, r1, portR10_OFFSET
|
||||||
|
lwi r9, r1, portR9_OFFSET
|
||||||
|
lwi r8, r1, portR8_OFFSET
|
||||||
|
lwi r7, r1, portR7_OFFSET
|
||||||
|
lwi r6, r1, portR6_OFFSET
|
||||||
|
lwi r5, r1, portR5_OFFSET
|
||||||
|
lwi r4, r1, portR4_OFFSET
|
||||||
|
lwi r3, r1, portR3_OFFSET
|
||||||
|
lwi r2, r1, portR2_OFFSET
|
||||||
|
|
||||||
|
/* Reload the rmsr from the stack. */
|
||||||
|
lwi r18, r1, portMSR_OFFSET
|
||||||
|
mts rmsr, r18
|
||||||
|
|
||||||
|
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||||
|
/* Reload the FSR from the stack. */
|
||||||
|
lwi r18, r1, portFSR_OFFSET
|
||||||
|
mts rfsr, r18
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Load the critical nesting value. */
|
||||||
|
lwi r18, r1, portCRITICAL_NESTING_OFFSET
|
||||||
|
swi r18, r0, uxCriticalNesting
|
||||||
|
|
||||||
|
/* Test the critical nesting value. If it is non zero then the task last
|
||||||
|
exited the running state using a yield. If it is zero, then the task
|
||||||
|
last exited the running state through an interrupt. */
|
||||||
|
xori r18, r18, 0
|
||||||
|
bnei r18, exit_from_yield
|
||||||
|
|
||||||
|
/* r18 was being used as a temporary. Now restore its true value from the
|
||||||
|
stack. */
|
||||||
|
lwi r18, r1, portR18_OFFSET
|
||||||
|
|
||||||
|
/* Remove the stack frame. */
|
||||||
|
addik r1, r1, portCONTEXT_SIZE
|
||||||
|
|
||||||
|
/* Return using rtid so interrupts are re-enabled as this function is
|
||||||
|
exited. */
|
||||||
|
rtid r14, 0
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* This function is used to exit portRESTORE_CONTEXT() if the task being
|
||||||
|
returned to last left the Running state by calling taskYIELD() (rather than
|
||||||
|
being preempted by an interrupt). */
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
exit_from_yield:
|
||||||
|
|
||||||
|
/* r18 was being used as a temporary. Now restore its true value from the
|
||||||
|
stack. */
|
||||||
|
lwi r18, r1, portR18_OFFSET
|
||||||
|
|
||||||
|
/* Remove the stack frame. */
|
||||||
|
addik r1, r1, portCONTEXT_SIZE
|
||||||
|
|
||||||
|
/* Return to the task. */
|
||||||
|
rtsd r14, 0
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
_interrupt_handler:
|
||||||
|
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
/* Stack the return address. */
|
||||||
|
swi r14, r1, portR14_OFFSET
|
||||||
|
|
||||||
|
/* Switch to the ISR stack. */
|
||||||
|
lwi r1, r0, pulISRStack
|
||||||
|
|
||||||
|
/* The parameter to the interrupt handler. */
|
||||||
|
ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
|
||||||
|
|
||||||
|
/* Execute any pending interrupts. */
|
||||||
|
bralid r15, XIntc_DeviceInterruptHandler
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
/* See if a new task should be selected to execute. */
|
||||||
|
lwi r18, r0, ulTaskSwitchRequested
|
||||||
|
or r18, r18, r0
|
||||||
|
|
||||||
|
/* If ulTaskSwitchRequested is already zero, then jump straight to
|
||||||
|
restoring the task that is already in the Running state. */
|
||||||
|
beqi r18, task_switch_not_requested
|
||||||
|
|
||||||
|
/* Set ulTaskSwitchRequested back to zero as a task switch is about to be
|
||||||
|
performed. */
|
||||||
|
swi r0, r0, ulTaskSwitchRequested
|
||||||
|
|
||||||
|
/* ulTaskSwitchRequested was not 0 when tested. Select the next task to
|
||||||
|
execute. */
|
||||||
|
bralid r15, vTaskSwitchContext
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
task_switch_not_requested:
|
||||||
|
|
||||||
|
/* Restore the context of the next task scheduled to execute. */
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
VPortYieldASM:
|
||||||
|
|
||||||
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
/* Modify the return address so a return is done to the instruction after
|
||||||
|
the call to VPortYieldASM. */
|
||||||
|
addi r14, r14, 8
|
||||||
|
swi r14, r1, portR14_OFFSET
|
||||||
|
|
||||||
|
/* Switch to use the ISR stack. */
|
||||||
|
lwi r1, r0, pulISRStack
|
||||||
|
|
||||||
|
/* Select the next task to execute. */
|
||||||
|
bralid r15, vTaskSwitchContext
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
/* Restore the context of the next task scheduled to execute. */
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
vPortStartFirstTask:
|
||||||
|
|
||||||
|
portRESTORE_CONTEXT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MICROBLAZE_EXCEPTIONS_ENABLED == 1
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
vPortExceptionHandlerEntry:
|
||||||
|
|
||||||
|
/* Take a copy of the stack pointer before vPortExecptionHandler is called,
|
||||||
|
storing its value prior to the function stack frame being created. */
|
||||||
|
swi r1, r0, pulStackPointerOnFunctionEntry
|
||||||
|
bralid r15, vPortExceptionHandler
|
||||||
|
or r0, r0, r0
|
||||||
|
|
||||||
|
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BSP includes. */
|
||||||
|
#include <mb_interface.h>
|
||||||
|
#include <xparameters.h>
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned long
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Interrupt control macros and functions. */
|
||||||
|
void microblaze_disable_interrupts( void );
|
||||||
|
void microblaze_enable_interrupts( void );
|
||||||
|
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||||
|
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section macros. */
|
||||||
|
void vPortEnterCritical( void );
|
||||||
|
void vPortExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() { \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
microblaze_disable_interrupts(); \
|
||||||
|
uxCriticalNesting++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portEXIT_CRITICAL() { \
|
||||||
|
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
|
||||||
|
/* Interrupts are disabled, so we can */ \
|
||||||
|
/* access the variable directly. */ \
|
||||||
|
uxCriticalNesting--; \
|
||||||
|
if( uxCriticalNesting == 0 ) \
|
||||||
|
{ \
|
||||||
|
/* The nesting has unwound and we \
|
||||||
|
can enable interrupts again. */ \
|
||||||
|
portENABLE_INTERRUPTS(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The yield macro maps directly to the vPortYield() function. */
|
||||||
|
void vPortYield( void );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
|
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
||||||
|
sets a flag to say that a yield has been requested. The interrupt exit code
|
||||||
|
then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
||||||
|
context, if the flag is not false. This is done to prevent multiple calls to
|
||||||
|
vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
||||||
|
can result in multiple peripherals being serviced. */
|
||||||
|
extern volatile unsigned long ulTaskSwitchRequested;
|
||||||
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) ulTaskSwitchRequested = 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The following structure is used by the FreeRTOS exception handler. It is
|
||||||
|
filled with the MicroBlaze context as it was at the time the exception occurred.
|
||||||
|
This is done as an aid to debugging exception occurrences. */
|
||||||
|
typedef struct PORT_REGISTER_DUMP
|
||||||
|
{
|
||||||
|
/* The following structure members hold the values of the MicroBlaze
|
||||||
|
registers at the time the exception was raised. */
|
||||||
|
unsigned long ulR1_SP;
|
||||||
|
unsigned long ulR2_small_data_area;
|
||||||
|
unsigned long ulR3;
|
||||||
|
unsigned long ulR4;
|
||||||
|
unsigned long ulR5;
|
||||||
|
unsigned long ulR6;
|
||||||
|
unsigned long ulR7;
|
||||||
|
unsigned long ulR8;
|
||||||
|
unsigned long ulR9;
|
||||||
|
unsigned long ulR10;
|
||||||
|
unsigned long ulR11;
|
||||||
|
unsigned long ulR12;
|
||||||
|
unsigned long ulR13_read_write_small_data_area;
|
||||||
|
unsigned long ulR14_return_address_from_interrupt;
|
||||||
|
unsigned long ulR15_return_address_from_subroutine;
|
||||||
|
unsigned long ulR16_return_address_from_trap;
|
||||||
|
unsigned long ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */
|
||||||
|
unsigned long ulR18;
|
||||||
|
unsigned long ulR19;
|
||||||
|
unsigned long ulR20;
|
||||||
|
unsigned long ulR21;
|
||||||
|
unsigned long ulR22;
|
||||||
|
unsigned long ulR23;
|
||||||
|
unsigned long ulR24;
|
||||||
|
unsigned long ulR25;
|
||||||
|
unsigned long ulR26;
|
||||||
|
unsigned long ulR27;
|
||||||
|
unsigned long ulR28;
|
||||||
|
unsigned long ulR29;
|
||||||
|
unsigned long ulR30;
|
||||||
|
unsigned long ulR31;
|
||||||
|
unsigned long ulPC;
|
||||||
|
unsigned long ulESR;
|
||||||
|
unsigned long ulMSR;
|
||||||
|
unsigned long ulEAR;
|
||||||
|
unsigned long ulFSR;
|
||||||
|
unsigned long ulEDR;
|
||||||
|
|
||||||
|
/* A human readable description of the exception cause. The strings used
|
||||||
|
are the same as the #define constant names found in the
|
||||||
|
microblaze_exceptions_i.h header file */
|
||||||
|
signed char *pcExceptionCause;
|
||||||
|
|
||||||
|
/* The human readable name of the task that was running at the time the
|
||||||
|
exception occurred. This is the name that was given to the task when the
|
||||||
|
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||||
|
signed char *pcCurrentTaskName;
|
||||||
|
|
||||||
|
/* The handle of the task that was running a the time the exception
|
||||||
|
occurred. */
|
||||||
|
void * xCurrentTaskHandle;
|
||||||
|
|
||||||
|
} xPortRegisterDump;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Installs pxHandler as the interrupt handler for the peripheral specified by
|
||||||
|
* the ucInterruptID parameter.
|
||||||
|
*
|
||||||
|
* ucInterruptID:
|
||||||
|
*
|
||||||
|
* The ID of the peripheral that will have pxHandler assigned as its interrupt
|
||||||
|
* handler. Peripheral IDs are defined in the xparameters.h header file, which
|
||||||
|
* is itself part of the BSP project. For example, in the official demo
|
||||||
|
* application for this port, xparameters.h defines the following IDs for the
|
||||||
|
* four possible interrupt sources:
|
||||||
|
*
|
||||||
|
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||||
|
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||||
|
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||||
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* pxHandler:
|
||||||
|
*
|
||||||
|
* A pointer to the interrupt handler function itself. This must be a void
|
||||||
|
* function that takes a (void *) parameter.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* pvCallBackRef:
|
||||||
|
*
|
||||||
|
* The parameter passed into the handler function. In many cases this will not
|
||||||
|
* be used and can be NULL. Some times it is used to pass in a reference to
|
||||||
|
* the peripheral instance variable, so it can be accessed from inside the
|
||||||
|
* handler function.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* pdPASS is returned if the function executes successfully. Any other value
|
||||||
|
* being returned indicates that the function did not execute correctly.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enables the interrupt, within the interrupt controller, for the peripheral
|
||||||
|
* specified by the ucInterruptID parameter.
|
||||||
|
*
|
||||||
|
* ucInterruptID:
|
||||||
|
*
|
||||||
|
* The ID of the peripheral that will have its interrupt enabled in the
|
||||||
|
* interrupt controller. Peripheral IDs are defined in the xparameters.h header
|
||||||
|
* file, which is itself part of the BSP project. For example, in the official
|
||||||
|
* demo application for this port, xparameters.h defines the following IDs for
|
||||||
|
* the four possible interrupt sources:
|
||||||
|
*
|
||||||
|
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||||
|
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||||
|
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||||
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void vPortEnableInterrupt( unsigned char ucInterruptID );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disables the interrupt, within the interrupt controller, for the peripheral
|
||||||
|
* specified by the ucInterruptID parameter.
|
||||||
|
*
|
||||||
|
* ucInterruptID:
|
||||||
|
*
|
||||||
|
* The ID of the peripheral that will have its interrupt disabled in the
|
||||||
|
* interrupt controller. Peripheral IDs are defined in the xparameters.h header
|
||||||
|
* file, which is itself part of the BSP project. For example, in the official
|
||||||
|
* demo application for this port, xparameters.h defines the following IDs for
|
||||||
|
* the four possible interrupt sources:
|
||||||
|
*
|
||||||
|
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||||
|
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||||
|
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||||
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void vPortDisableInterrupt( unsigned char ucInterruptID );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an application defined callback function used to install the tick
|
||||||
|
* interrupt handler. It is provided as an application callback because the
|
||||||
|
* kernel will run on lots of different MicroBlaze and FPGA configurations - not
|
||||||
|
* all of which will have the same timer peripherals defined or available. This
|
||||||
|
* example uses the AXI Timer 0. If that is available on your hardware platform
|
||||||
|
* then this example callback implementation should not require modification.
|
||||||
|
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
||||||
|
* which the function below declares as an extern.
|
||||||
|
*/
|
||||||
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an application defined callback function used to clear whichever
|
||||||
|
* interrupt was installed by the the vApplicationSetupTimerInterrupt() callback
|
||||||
|
* function - in this case the interrupt generated by the AXI timer. It is
|
||||||
|
* provided as an application callback because the kernel will run on lots of
|
||||||
|
* different MicroBlaze and FPGA configurations - not all of which will have the
|
||||||
|
* same timer peripherals defined or available. This example uses the AXI Timer 0.
|
||||||
|
* If that is available on your hardware platform then this example callback
|
||||||
|
* implementation should not require modification provided the example definition
|
||||||
|
* of vApplicationSetupTimerInterrupt() is also not modified.
|
||||||
|
*/
|
||||||
|
void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
||||||
|
* is configured to include exception functionality, and
|
||||||
|
* configINSTALL_EXCEPTION_HANDLERS is set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* vPortExceptionsInstallHandlers() installs the FreeRTOS exception handler
|
||||||
|
* for every possible exception cause.
|
||||||
|
*
|
||||||
|
* vPortExceptionsInstallHandlers() can be called explicitly from application
|
||||||
|
* code. After that is done, the default FreeRTOS exception handler that will
|
||||||
|
* have been installed can be replaced for any specific exception cause by using
|
||||||
|
* the standard Xilinx library function microblaze_register_exception_handler().
|
||||||
|
*
|
||||||
|
* If vPortExceptionsInstallHandlers() is not called explicitly by the
|
||||||
|
* application, it will be called automatically by the kernel the first time
|
||||||
|
* xPortInstallInterruptHandler() is called. At that time, any exception
|
||||||
|
* handlers that may have already been installed will be replaced.
|
||||||
|
*
|
||||||
|
* See the description of vApplicationExceptionRegisterDump() for information
|
||||||
|
* on the processing performed by the FreeRTOS exception handler.
|
||||||
|
*/
|
||||||
|
void vPortExceptionsInstallHandlers( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
||||||
|
* in portmacro.h) with the MicroBlaze context, as it was at the time the
|
||||||
|
* exception occurred. The exception handler then calls
|
||||||
|
* vApplicationExceptionRegisterDump(), passing in the completed
|
||||||
|
* xPortRegisterDump structure as its parameter.
|
||||||
|
*
|
||||||
|
* The FreeRTOS kernel provides its own implementation of
|
||||||
|
* vApplicationExceptionRegisterDump(), but the kernel provided implementation
|
||||||
|
* is declared as being 'weak'. The weak definition allows the application
|
||||||
|
* writer to provide their own implementation, should they wish to use the
|
||||||
|
* register dump information. For example, an implementation could be provided
|
||||||
|
* that wrote the register dump data to a display, or a UART port.
|
||||||
|
*/
|
||||||
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the NIOS2 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Standard Includes. */
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Altera includes. */
|
||||||
|
#include "sys/alt_irq.h"
|
||||||
|
#include "altera_avalon_timer_regs.h"
|
||||||
|
#include "priv/alt_irq_table.h"
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Interrupts are enabled. */
|
||||||
|
#define portINITIAL_ESTATUS ( portSTACK_TYPE ) 0x01
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the timer to generate the tick interrupts.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call back for the alarm function.
|
||||||
|
*/
|
||||||
|
void vPortSysTickHandler( void * context, alt_u32 id );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvReadGp( unsigned long *ulValue )
|
||||||
|
{
|
||||||
|
asm( "stw gp, (%0)" :: "r"(ulValue) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxFramePointer = pxTopOfStack - 1;
|
||||||
|
portSTACK_TYPE xGlobalPointer;
|
||||||
|
|
||||||
|
prvReadGp( &xGlobalPointer );
|
||||||
|
|
||||||
|
/* End of stack marker. */
|
||||||
|
*pxTopOfStack = 0xdeadbeef;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxFramePointer;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = xGlobalPointer;
|
||||||
|
|
||||||
|
/* Space for R23 to R16. */
|
||||||
|
pxTopOfStack -= 9;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = portINITIAL_ESTATUS;
|
||||||
|
|
||||||
|
/* Space for R15 to R5. */
|
||||||
|
pxTopOfStack -= 12;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
|
||||||
|
/* Space for R3 to R1, muldiv and RA. */
|
||||||
|
pxTopOfStack -= 5;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
asm volatile ( " movia r2, restore_sp_from_pxCurrentTCB \n"
|
||||||
|
" jmp r2 " );
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the NIOS2 port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
|
* frequency.
|
||||||
|
*/
|
||||||
|
void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
/* Try to register the interrupt handler. */
|
||||||
|
if ( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )
|
||||||
|
{
|
||||||
|
/* Failed to install the Interrupt Handler. */
|
||||||
|
asm( "break" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_PERIODL( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) & 0xFFFF );
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_PERIODH( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) >> 16 );
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_CONT_MSK | ALTERA_AVALON_TIMER_CONTROL_START_MSK | ALTERA_AVALON_TIMER_CONTROL_ITO_MSK );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear any already pending interrupts generated by the Timer. */
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSysTickHandler( void * context, alt_u32 id )
|
||||||
|
{
|
||||||
|
/* Increment the Kernel Tick. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
/* If using preemption, also force a context switch. */
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
vTaskSwitchContext();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear the interrupt. */
|
||||||
|
IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** This function is a re-implementation of the Altera provided function.
|
||||||
|
* The function is re-implemented to prevent it from enabling an interrupt
|
||||||
|
* when it is registered. Interrupts should only be enabled after the FreeRTOS.org
|
||||||
|
* kernel has its scheduler started so that contexts are saved and switched
|
||||||
|
* correctly.
|
||||||
|
*/
|
||||||
|
int alt_irq_register( alt_u32 id, void* context, void (*handler)(void*, alt_u32) )
|
||||||
|
{
|
||||||
|
int rc = -EINVAL;
|
||||||
|
alt_irq_context status;
|
||||||
|
|
||||||
|
if (id < ALT_NIRQ)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* interrupts are disabled while the handler tables are updated to ensure
|
||||||
|
* that an interrupt doesn't occur while the tables are in an inconsistent
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
status = alt_irq_disable_all ();
|
||||||
|
|
||||||
|
alt_irq[id].handler = handler;
|
||||||
|
alt_irq[id].context = context;
|
||||||
|
|
||||||
|
rc = (handler) ? alt_irq_enable (id): alt_irq_disable (id);
|
||||||
|
|
||||||
|
/* alt_irq_enable_all(status); This line is removed to prevent the interrupt from being immediately enabled. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
|
||||||
|
.set noat
|
||||||
|
|
||||||
|
# Exported to start the first task.
|
||||||
|
.globl restore_sp_from_pxCurrentTCB
|
||||||
|
|
||||||
|
# Entry point for exceptions.
|
||||||
|
.section .exceptions.entry, "xa"
|
||||||
|
|
||||||
|
# Save the entire context of a task.
|
||||||
|
save_context:
|
||||||
|
addi ea, ea, -4 # Point to the next instruction.
|
||||||
|
addi sp, sp, -116 # Create space on the stack.
|
||||||
|
stw ra, 0(sp)
|
||||||
|
# Leave a gap for muldiv 0
|
||||||
|
stw at, 8(sp)
|
||||||
|
stw r2, 12(sp)
|
||||||
|
stw r3, 16(sp)
|
||||||
|
stw r4, 20(sp)
|
||||||
|
stw r5, 24(sp)
|
||||||
|
stw r6, 28(sp)
|
||||||
|
stw r7, 32(sp)
|
||||||
|
stw r8, 36(sp)
|
||||||
|
stw r9, 40(sp)
|
||||||
|
stw r10, 44(sp)
|
||||||
|
stw r11, 48(sp)
|
||||||
|
stw r12, 52(sp)
|
||||||
|
stw r13, 56(sp)
|
||||||
|
stw r14, 60(sp)
|
||||||
|
stw r15, 64(sp)
|
||||||
|
rdctl r5, estatus # Save the eStatus
|
||||||
|
stw r5, 68(sp)
|
||||||
|
stw ea, 72(sp) # Save the PC
|
||||||
|
stw r16, 76(sp) # Save the remaining registers
|
||||||
|
stw r17, 80(sp)
|
||||||
|
stw r18, 84(sp)
|
||||||
|
stw r19, 88(sp)
|
||||||
|
stw r20, 92(sp)
|
||||||
|
stw r21, 96(sp)
|
||||||
|
stw r22, 100(sp)
|
||||||
|
stw r23, 104(sp)
|
||||||
|
stw gp, 108(sp)
|
||||||
|
stw fp, 112(sp)
|
||||||
|
|
||||||
|
save_sp_to_pxCurrentTCB:
|
||||||
|
movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
|
||||||
|
ldw et, (et) # Load the value of the pxCurrentTCB pointer
|
||||||
|
stw sp, (et) # Store the stack pointer into the top of the TCB
|
||||||
|
|
||||||
|
.section .exceptions.irqtest, "xa"
|
||||||
|
hw_irq_test:
|
||||||
|
/*
|
||||||
|
* Test to see if the exception was a software exception or caused
|
||||||
|
* by an external interrupt, and vector accordingly.
|
||||||
|
*/
|
||||||
|
rdctl r4, ipending # Load the Pending Interrupts indication
|
||||||
|
rdctl r5, estatus # Load the eStatus (enabled interrupts).
|
||||||
|
andi r2, r5, 1 # Are interrupts enabled globally.
|
||||||
|
beq r2, zero, soft_exceptions # Interrupts are not enabled.
|
||||||
|
beq r4, zero, soft_exceptions # There are no interrupts triggered.
|
||||||
|
|
||||||
|
.section .exceptions.irqhandler, "xa"
|
||||||
|
hw_irq_handler:
|
||||||
|
call alt_irq_handler # Call the alt_irq_handler to deliver to the registered interrupt handler.
|
||||||
|
|
||||||
|
.section .exceptions.irqreturn, "xa"
|
||||||
|
restore_sp_from_pxCurrentTCB:
|
||||||
|
movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
|
||||||
|
ldw et, (et) # Load the value of the pxCurrentTCB pointer
|
||||||
|
ldw sp, (et) # Load the stack pointer with the top value of the TCB
|
||||||
|
|
||||||
|
restore_context:
|
||||||
|
ldw ra, 0(sp) # Restore the registers.
|
||||||
|
# Leave a gap for muldiv 0.
|
||||||
|
ldw at, 8(sp)
|
||||||
|
ldw r2, 12(sp)
|
||||||
|
ldw r3, 16(sp)
|
||||||
|
ldw r4, 20(sp)
|
||||||
|
ldw r5, 24(sp)
|
||||||
|
ldw r6, 28(sp)
|
||||||
|
ldw r7, 32(sp)
|
||||||
|
ldw r8, 36(sp)
|
||||||
|
ldw r9, 40(sp)
|
||||||
|
ldw r10, 44(sp)
|
||||||
|
ldw r11, 48(sp)
|
||||||
|
ldw r12, 52(sp)
|
||||||
|
ldw r13, 56(sp)
|
||||||
|
ldw r14, 60(sp)
|
||||||
|
ldw r15, 64(sp)
|
||||||
|
ldw et, 68(sp) # Load the eStatus
|
||||||
|
wrctl estatus, et # Write the eStatus
|
||||||
|
ldw ea, 72(sp) # Load the Program Counter
|
||||||
|
ldw r16, 76(sp)
|
||||||
|
ldw r17, 80(sp)
|
||||||
|
ldw r18, 84(sp)
|
||||||
|
ldw r19, 88(sp)
|
||||||
|
ldw r20, 92(sp)
|
||||||
|
ldw r21, 96(sp)
|
||||||
|
ldw r22, 100(sp)
|
||||||
|
ldw r23, 104(sp)
|
||||||
|
ldw gp, 108(sp)
|
||||||
|
ldw fp, 112(sp)
|
||||||
|
addi sp, sp, 116 # Release stack space
|
||||||
|
|
||||||
|
eret # Return to address ea, loading eStatus into Status.
|
||||||
|
|
||||||
|
.section .exceptions.soft, "xa"
|
||||||
|
soft_exceptions:
|
||||||
|
ldw et, 0(ea) # Load the instruction where the interrupt occured.
|
||||||
|
movhi at, %hi(0x003B683A) # Load the registers with the trap instruction code
|
||||||
|
ori at, at, %lo(0x003B683A)
|
||||||
|
cmpne et, et, at # Compare the trap instruction code to the last excuted instruction
|
||||||
|
beq et, r0, call_scheduler # its a trap so switchcontext
|
||||||
|
break # This is an un-implemented instruction or muldiv problem.
|
||||||
|
br restore_context # its something else
|
||||||
|
|
||||||
|
call_scheduler:
|
||||||
|
addi ea, ea, 4 # A trap was called, increment the program counter so it is not called again.
|
||||||
|
stw ea, 72(sp) # Save the new program counter to the context.
|
||||||
|
call vTaskSwitchContext # Pick the next context.
|
||||||
|
br restore_sp_from_pxCurrentTCB # Switch in the task context and restore.
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sys/alt_irq.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void vTaskSwitchContext( void );
|
||||||
|
#define portYIELD() asm volatile ( "trap" );
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
||||||
|
|
||||||
|
|
||||||
|
/* Include the port_asm.S file where the Context saving/restoring is defined. */
|
||||||
|
__asm__( "\n\t.globl save_context" );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void vTaskEnterCritical( void );
|
||||||
|
extern void vTaskExitCritical( void );
|
||||||
|
|
||||||
|
#define portDISABLE_INTERRUPTS() alt_irq_disable_all()
|
||||||
|
#define portENABLE_INTERRUPTS() alt_irq_enable_all( 0x01 );
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* When switching out a task, if the task tag contains a buffer address then
|
||||||
|
save the flop context into the buffer. */
|
||||||
|
#define traceTASK_SWITCHED_OUT() \
|
||||||
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
|
{ \
|
||||||
|
extern void vPortSaveFPURegisters( void * ); \
|
||||||
|
vPortSaveFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When switching in a task, if the task tag contains a buffer address then
|
||||||
|
load the flop context from the buffer. */
|
||||||
|
#define traceTASK_SWITCHED_IN() \
|
||||||
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
|
{ \
|
||||||
|
extern void vPortRestoreFPURegisters( void * ); \
|
||||||
|
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the PPC405 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Library includes. */
|
||||||
|
#include "xtime_l.h"
|
||||||
|
#include "xintc.h"
|
||||||
|
#include "xintc_i.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Definitions to set the initial MSR of each task. */
|
||||||
|
#define portCRITICAL_INTERRUPT_ENABLE ( 1UL << 17UL )
|
||||||
|
#define portEXTERNAL_INTERRUPT_ENABLE ( 1UL << 15UL )
|
||||||
|
#define portMACHINE_CHECK_ENABLE ( 1UL << 12UL )
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
#define portAPU_PRESENT ( 1UL << 25UL )
|
||||||
|
#define portFCM_FPU_PRESENT ( 1UL << 13UL )
|
||||||
|
#else
|
||||||
|
#define portAPU_PRESENT ( 0UL )
|
||||||
|
#define portFCM_FPU_PRESENT ( 0UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portINITIAL_MSR ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )
|
||||||
|
|
||||||
|
|
||||||
|
extern const unsigned _SDA_BASE_;
|
||||||
|
extern const unsigned _SDA2_BASE_;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the system timer to generate the tick interrupt.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The handler for the tick interrupt - defined in portasm.s.
|
||||||
|
*/
|
||||||
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The handler for the yield function - defined in portasm.s.
|
||||||
|
*/
|
||||||
|
extern void vPortYield( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to start the scheduler running by starting the highest
|
||||||
|
* priority task that has thus far been created.
|
||||||
|
*/
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Structure used to hold the state of the interrupt controller. */
|
||||||
|
static XIntc xInterruptController;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if the task had been
|
||||||
|
* interrupted.
|
||||||
|
*
|
||||||
|
* See the header file portable.h.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Place a known value at the bottom of the stack for debugging. */
|
||||||
|
*pxTopOfStack = 0xDEADBEEF;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* EABI stack frame. */
|
||||||
|
pxTopOfStack -= 20; /* Previous backchain and LR, R31 to R4 inclusive. */
|
||||||
|
|
||||||
|
/* Parameters in R13. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA_BASE_; /* address of the first small data area */
|
||||||
|
pxTopOfStack -= 10;
|
||||||
|
|
||||||
|
/* Parameters in R3. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Parameters in R2. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA2_BASE_; /* address of the second small data area */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* R1 is the stack pointer so is omitted. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x10000001UL;; /* R0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* CR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* XER. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* CTR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler; /* LR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL;/* Backchain. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here as the tasks are now running! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initialisation to generate the RTOS tick.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
const unsigned long ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
|
||||||
|
XTime_PITClearInterrupt();
|
||||||
|
XTime_FITClearInterrupt();
|
||||||
|
XTime_WDTClearInterrupt();
|
||||||
|
XTime_WDTDisableInterrupt();
|
||||||
|
XTime_FITDisableInterrupt();
|
||||||
|
|
||||||
|
XExc_RegisterHandler( XEXC_ID_PIT_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );
|
||||||
|
|
||||||
|
XTime_PITEnableAutoReload();
|
||||||
|
XTime_PITSetInterval( ulInterval );
|
||||||
|
XTime_PITEnableInterrupt();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRHandler( void *pvNullDoNotUse )
|
||||||
|
{
|
||||||
|
unsigned long ulInterruptStatus, ulInterruptMask = 1UL;
|
||||||
|
portBASE_TYPE xInterruptNumber;
|
||||||
|
XIntc_Config *pxInterruptController;
|
||||||
|
XIntc_VectorTableEntry *pxTable;
|
||||||
|
|
||||||
|
/* Just to remove compiler warning. */
|
||||||
|
( void ) pvNullDoNotUse;
|
||||||
|
|
||||||
|
/* Get the configuration by using the device ID - in this case it is
|
||||||
|
assumed that only one interrupt controller is being used. */
|
||||||
|
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
||||||
|
|
||||||
|
/* Which interrupts are pending? */
|
||||||
|
ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );
|
||||||
|
|
||||||
|
for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )
|
||||||
|
{
|
||||||
|
if( ulInterruptStatus & 0x01UL )
|
||||||
|
{
|
||||||
|
/* Clear the pending interrupt. */
|
||||||
|
XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );
|
||||||
|
|
||||||
|
/* Call the registered handler. */
|
||||||
|
pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );
|
||||||
|
pxTable->Handler( pxTable->CallBackRef );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the next interrupt. */
|
||||||
|
ulInterruptMask <<= 0x01UL;
|
||||||
|
ulInterruptStatus >>= 0x01UL;
|
||||||
|
|
||||||
|
/* Have we serviced all interrupts? */
|
||||||
|
if( ulInterruptStatus == 0UL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSetupInterruptController( void )
|
||||||
|
{
|
||||||
|
extern void vPortISRWrapper( void );
|
||||||
|
|
||||||
|
/* Perform all library calls necessary to initialise the exception table
|
||||||
|
and interrupt controller. This assumes only one interrupt controller is in
|
||||||
|
use. */
|
||||||
|
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
XExc_Init();
|
||||||
|
|
||||||
|
/* The library functions save the context - we then jump to a wrapper to
|
||||||
|
save the stack into the TCB. The wrapper then calls the handler defined
|
||||||
|
above. */
|
||||||
|
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
||||||
|
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
||||||
|
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn = pdFAIL;
|
||||||
|
|
||||||
|
/* This function is defined here so the scope of xInterruptController can
|
||||||
|
remain within this file. */
|
||||||
|
|
||||||
|
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
||||||
|
{
|
||||||
|
XIntc_Enable( &xInterruptController, ucInterruptID );
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
.extern pxCurrentTCB
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
.extern vTaskIncrementTick
|
||||||
|
.extern vPortISRHandler
|
||||||
|
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global vPortYield
|
||||||
|
.global vPortTickISR
|
||||||
|
.global vPortISRWrapper
|
||||||
|
.global vPortSaveFPURegisters
|
||||||
|
.global vPortRestoreFPURegisters
|
||||||
|
|
||||||
|
.set BChainField, 0
|
||||||
|
.set NextLRField, BChainField + 4
|
||||||
|
.set MSRField, NextLRField + 4
|
||||||
|
.set PCField, MSRField + 4
|
||||||
|
.set LRField, PCField + 4
|
||||||
|
.set CTRField, LRField + 4
|
||||||
|
.set XERField, CTRField + 4
|
||||||
|
.set CRField, XERField + 4
|
||||||
|
.set USPRG0Field, CRField + 4
|
||||||
|
.set r0Field, USPRG0Field + 4
|
||||||
|
.set r2Field, r0Field + 4
|
||||||
|
.set r3r31Field, r2Field + 4
|
||||||
|
.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
|
||||||
|
|
||||||
|
|
||||||
|
.macro portSAVE_STACK_POINTER_AND_LR
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis R2, R0, pxCurrentTCB@ha
|
||||||
|
lwz R2, pxCurrentTCB@l( R2 )
|
||||||
|
|
||||||
|
/* Store the stack pointer into the TCB */
|
||||||
|
stw SP, 0( R2 )
|
||||||
|
|
||||||
|
/* Save the link register */
|
||||||
|
stwu R1, -24( R1 )
|
||||||
|
mflr R0
|
||||||
|
stw R31, 20( R1 )
|
||||||
|
stw R0, 28( R1 )
|
||||||
|
mr R31, r1
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
|
||||||
|
/* Restore the link register */
|
||||||
|
lwz R11, 0( R1 )
|
||||||
|
lwz R0, 4( R11 )
|
||||||
|
mtlr R0
|
||||||
|
lwz R31, -4( R11 )
|
||||||
|
mr R1, R11
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis SP, R0, pxCurrentTCB@ha
|
||||||
|
lwz SP, pxCurrentTCB@l( R1 )
|
||||||
|
|
||||||
|
/* Get the task stack pointer from the TCB. */
|
||||||
|
lwz SP, 0( SP )
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis SP, R0, pxCurrentTCB@ha
|
||||||
|
lwz SP, pxCurrentTCB@l( SP )
|
||||||
|
|
||||||
|
/* Get the task stack pointer from the TCB. */
|
||||||
|
lwz SP, 0( SP )
|
||||||
|
|
||||||
|
/* Restore MSR register to SRR1. */
|
||||||
|
lwz R0, MSRField(R1)
|
||||||
|
mtsrr1 R0
|
||||||
|
|
||||||
|
/* Restore current PC location to SRR0. */
|
||||||
|
lwz R0, PCField(R1)
|
||||||
|
mtsrr0 R0
|
||||||
|
|
||||||
|
/* Save USPRG0 register */
|
||||||
|
lwz R0, USPRG0Field(R1)
|
||||||
|
mtspr 0x100,R0
|
||||||
|
|
||||||
|
/* Restore Condition register */
|
||||||
|
lwz R0, CRField(R1)
|
||||||
|
mtcr R0
|
||||||
|
|
||||||
|
/* Restore Fixed Point Exception register */
|
||||||
|
lwz R0, XERField(R1)
|
||||||
|
mtxer R0
|
||||||
|
|
||||||
|
/* Restore Counter register */
|
||||||
|
lwz R0, CTRField(R1)
|
||||||
|
mtctr R0
|
||||||
|
|
||||||
|
/* Restore Link register */
|
||||||
|
lwz R0, LRField(R1)
|
||||||
|
mtlr R0
|
||||||
|
|
||||||
|
/* Restore remaining GPR registers. */
|
||||||
|
lmw R3,r3r31Field(R1)
|
||||||
|
|
||||||
|
/* Restore r0 and r2. */
|
||||||
|
lwz R0, r0Field(R1)
|
||||||
|
lwz R2, r2Field(R1)
|
||||||
|
|
||||||
|
/* Remove frame from stack */
|
||||||
|
addi R1,R1,IFrameSize
|
||||||
|
|
||||||
|
/* Return into the first task */
|
||||||
|
rfi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vPortYield:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
vPortTickISR:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vTaskIncrementTick
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear the interrupt */
|
||||||
|
lis R0, 2048
|
||||||
|
mttsr R0
|
||||||
|
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
vPortISRWrapper:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vPortISRHandler
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
|
||||||
|
vPortSaveFPURegisters:
|
||||||
|
|
||||||
|
/* Enable APU and mark FPU as present. */
|
||||||
|
mfmsr r0
|
||||||
|
xor r30, r30, r30
|
||||||
|
oris r30, r30, 512
|
||||||
|
ori r30, r30, 8192
|
||||||
|
or r0, r0, r30
|
||||||
|
mtmsr r0
|
||||||
|
|
||||||
|
#ifdef USE_DP_FPU
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Save each flop register into an offset from
|
||||||
|
this buffer address. */
|
||||||
|
stfd f0, 0(r3)
|
||||||
|
stfd f1, 8(r3)
|
||||||
|
stfd f2, 16(r3)
|
||||||
|
stfd f3, 24(r3)
|
||||||
|
stfd f4, 32(r3)
|
||||||
|
stfd f5, 40(r3)
|
||||||
|
stfd f6, 48(r3)
|
||||||
|
stfd f7, 56(r3)
|
||||||
|
stfd f8, 64(r3)
|
||||||
|
stfd f9, 72(r3)
|
||||||
|
stfd f10, 80(r3)
|
||||||
|
stfd f11, 88(r3)
|
||||||
|
stfd f12, 96(r3)
|
||||||
|
stfd f13, 104(r3)
|
||||||
|
stfd f14, 112(r3)
|
||||||
|
stfd f15, 120(r3)
|
||||||
|
stfd f16, 128(r3)
|
||||||
|
stfd f17, 136(r3)
|
||||||
|
stfd f18, 144(r3)
|
||||||
|
stfd f19, 152(r3)
|
||||||
|
stfd f20, 160(r3)
|
||||||
|
stfd f21, 168(r3)
|
||||||
|
stfd f22, 176(r3)
|
||||||
|
stfd f23, 184(r3)
|
||||||
|
stfd f24, 192(r3)
|
||||||
|
stfd f25, 200(r3)
|
||||||
|
stfd f26, 208(r3)
|
||||||
|
stfd f27, 216(r3)
|
||||||
|
stfd f28, 224(r3)
|
||||||
|
stfd f29, 232(r3)
|
||||||
|
stfd f30, 240(r3)
|
||||||
|
stfd f31, 248(r3)
|
||||||
|
|
||||||
|
/* Also save the FPSCR. */
|
||||||
|
mffs f31
|
||||||
|
stfs f31, 256(r3)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Save each flop register into an offset from
|
||||||
|
this buffer address. */
|
||||||
|
stfs f0, 0(r3)
|
||||||
|
stfs f1, 4(r3)
|
||||||
|
stfs f2, 8(r3)
|
||||||
|
stfs f3, 12(r3)
|
||||||
|
stfs f4, 16(r3)
|
||||||
|
stfs f5, 20(r3)
|
||||||
|
stfs f6, 24(r3)
|
||||||
|
stfs f7, 28(r3)
|
||||||
|
stfs f8, 32(r3)
|
||||||
|
stfs f9, 36(r3)
|
||||||
|
stfs f10, 40(r3)
|
||||||
|
stfs f11, 44(r3)
|
||||||
|
stfs f12, 48(r3)
|
||||||
|
stfs f13, 52(r3)
|
||||||
|
stfs f14, 56(r3)
|
||||||
|
stfs f15, 60(r3)
|
||||||
|
stfs f16, 64(r3)
|
||||||
|
stfs f17, 68(r3)
|
||||||
|
stfs f18, 72(r3)
|
||||||
|
stfs f19, 76(r3)
|
||||||
|
stfs f20, 80(r3)
|
||||||
|
stfs f21, 84(r3)
|
||||||
|
stfs f22, 88(r3)
|
||||||
|
stfs f23, 92(r3)
|
||||||
|
stfs f24, 96(r3)
|
||||||
|
stfs f25, 100(r3)
|
||||||
|
stfs f26, 104(r3)
|
||||||
|
stfs f27, 108(r3)
|
||||||
|
stfs f28, 112(r3)
|
||||||
|
stfs f29, 116(r3)
|
||||||
|
stfs f30, 120(r3)
|
||||||
|
stfs f31, 124(r3)
|
||||||
|
|
||||||
|
/* Also save the FPSCR. */
|
||||||
|
mffs f31
|
||||||
|
stfs f31, 128(r3)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
||||||
|
#endif /* configUSE_FPU. */
|
||||||
|
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
|
||||||
|
vPortRestoreFPURegisters:
|
||||||
|
|
||||||
|
/* Enable APU and mark FPU as present. */
|
||||||
|
mfmsr r0
|
||||||
|
xor r30, r30, r30
|
||||||
|
oris r30, r30, 512
|
||||||
|
ori r30, r30, 8192
|
||||||
|
or r0, r0, r30
|
||||||
|
mtmsr r0
|
||||||
|
|
||||||
|
#ifdef USE_DP_FPU
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Restore each flop register from an offset
|
||||||
|
into this buffer.
|
||||||
|
|
||||||
|
First the FPSCR. */
|
||||||
|
lfs f31, 256(r3)
|
||||||
|
mtfsf f31, 7
|
||||||
|
|
||||||
|
lfd f0, 0(r3)
|
||||||
|
lfd f1, 8(r3)
|
||||||
|
lfd f2, 16(r3)
|
||||||
|
lfd f3, 24(r3)
|
||||||
|
lfd f4, 32(r3)
|
||||||
|
lfd f5, 40(r3)
|
||||||
|
lfd f6, 48(r3)
|
||||||
|
lfd f7, 56(r3)
|
||||||
|
lfd f8, 64(r3)
|
||||||
|
lfd f9, 72(r3)
|
||||||
|
lfd f10, 80(r3)
|
||||||
|
lfd f11, 88(r3)
|
||||||
|
lfd f12, 96(r3)
|
||||||
|
lfd f13, 104(r3)
|
||||||
|
lfd f14, 112(r3)
|
||||||
|
lfd f15, 120(r3)
|
||||||
|
lfd f16, 128(r3)
|
||||||
|
lfd f17, 136(r3)
|
||||||
|
lfd f18, 144(r3)
|
||||||
|
lfd f19, 152(r3)
|
||||||
|
lfd f20, 160(r3)
|
||||||
|
lfd f21, 168(r3)
|
||||||
|
lfd f22, 176(r3)
|
||||||
|
lfd f23, 184(r3)
|
||||||
|
lfd f24, 192(r3)
|
||||||
|
lfd f25, 200(r3)
|
||||||
|
lfd f26, 208(r3)
|
||||||
|
lfd f27, 216(r3)
|
||||||
|
lfd f28, 224(r3)
|
||||||
|
lfd f29, 232(r3)
|
||||||
|
lfd f30, 240(r3)
|
||||||
|
lfd f31, 248(r3)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Restore each flop register from an offset
|
||||||
|
into this buffer.
|
||||||
|
|
||||||
|
First the FPSCR. */
|
||||||
|
lfs f31, 128(r3)
|
||||||
|
mtfsf f31, 7
|
||||||
|
|
||||||
|
lfs f0, 0(r3)
|
||||||
|
lfs f1, 4(r3)
|
||||||
|
lfs f2, 8(r3)
|
||||||
|
lfs f3, 12(r3)
|
||||||
|
lfs f4, 16(r3)
|
||||||
|
lfs f5, 20(r3)
|
||||||
|
lfs f6, 24(r3)
|
||||||
|
lfs f7, 28(r3)
|
||||||
|
lfs f8, 32(r3)
|
||||||
|
lfs f9, 36(r3)
|
||||||
|
lfs f10, 40(r3)
|
||||||
|
lfs f11, 44(r3)
|
||||||
|
lfs f12, 48(r3)
|
||||||
|
lfs f13, 52(r3)
|
||||||
|
lfs f14, 56(r3)
|
||||||
|
lfs f15, 60(r3)
|
||||||
|
lfs f16, 64(r3)
|
||||||
|
lfs f17, 68(r3)
|
||||||
|
lfs f18, 72(r3)
|
||||||
|
lfs f19, 76(r3)
|
||||||
|
lfs f20, 80(r3)
|
||||||
|
lfs f21, 84(r3)
|
||||||
|
lfs f22, 88(r3)
|
||||||
|
lfs f23, 92(r3)
|
||||||
|
lfs f24, 96(r3)
|
||||||
|
lfs f25, 100(r3)
|
||||||
|
lfs f26, 104(r3)
|
||||||
|
lfs f27, 108(r3)
|
||||||
|
lfs f28, 112(r3)
|
||||||
|
lfs f29, 116(r3)
|
||||||
|
lfs f30, 120(r3)
|
||||||
|
lfs f31, 124(r3)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
||||||
|
#endif /* configUSE_FPU. */
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#include "xexception_l.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This port uses the critical nesting count from the TCB rather than
|
||||||
|
maintaining a separate value and then saving this value in the task stack. */
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
|
||||||
|
/* Interrupt control macros. */
|
||||||
|
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section macros. */
|
||||||
|
void vTaskEnterCritical( void );
|
||||||
|
void vTaskExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
void vPortYield( void );
|
||||||
|
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
|
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
||||||
|
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
/* Port specific interrupt handling functions. */
|
||||||
|
void vPortSetupInterruptController( void );
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* When switching out a task, if the task tag contains a buffer address then
|
||||||
|
save the flop context into the buffer. */
|
||||||
|
#define traceTASK_SWITCHED_OUT() \
|
||||||
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
|
{ \
|
||||||
|
extern void vPortSaveFPURegisters( void * ); \
|
||||||
|
vPortSaveFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When switching in a task, if the task tag contains a buffer address then
|
||||||
|
load the flop context from the buffer. */
|
||||||
|
#define traceTASK_SWITCHED_IN() \
|
||||||
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
|
{ \
|
||||||
|
extern void vPortRestoreFPURegisters( void * ); \
|
||||||
|
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the PPC440 port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Library includes. */
|
||||||
|
#include "xtime_l.h"
|
||||||
|
#include "xintc.h"
|
||||||
|
#include "xintc_i.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Definitions to set the initial MSR of each task. */
|
||||||
|
#define portCRITICAL_INTERRUPT_ENABLE ( 1UL << 17UL )
|
||||||
|
#define portEXTERNAL_INTERRUPT_ENABLE ( 1UL << 15UL )
|
||||||
|
#define portMACHINE_CHECK_ENABLE ( 1UL << 12UL )
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
#define portAPU_PRESENT ( 1UL << 25UL )
|
||||||
|
#define portFCM_FPU_PRESENT ( 1UL << 13UL )
|
||||||
|
#else
|
||||||
|
#define portAPU_PRESENT ( 0UL )
|
||||||
|
#define portFCM_FPU_PRESENT ( 0UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portINITIAL_MSR ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )
|
||||||
|
|
||||||
|
|
||||||
|
extern const unsigned _SDA_BASE_;
|
||||||
|
extern const unsigned _SDA2_BASE_;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the system timer to generate the tick interrupt.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The handler for the tick interrupt - defined in portasm.s.
|
||||||
|
*/
|
||||||
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The handler for the yield function - defined in portasm.s.
|
||||||
|
*/
|
||||||
|
extern void vPortYield( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to start the scheduler running by starting the highest
|
||||||
|
* priority task that has thus far been created.
|
||||||
|
*/
|
||||||
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Structure used to hold the state of the interrupt controller. */
|
||||||
|
static XIntc xInterruptController;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if the task had been
|
||||||
|
* interrupted.
|
||||||
|
*
|
||||||
|
* See the header file portable.h.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Place a known value at the bottom of the stack for debugging. */
|
||||||
|
*pxTopOfStack = 0xDEADBEEF;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* EABI stack frame. */
|
||||||
|
pxTopOfStack -= 20; /* Previous backchain and LR, R31 to R4 inclusive. */
|
||||||
|
|
||||||
|
/* Parameters in R13. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA_BASE_; /* address of the first small data area */
|
||||||
|
pxTopOfStack -= 10;
|
||||||
|
|
||||||
|
/* Parameters in R3. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Parameters in R2. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA2_BASE_; /* address of the second small data area */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* R1 is the stack pointer so is omitted. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x10000001UL;; /* R0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* CR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* XER. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL; /* CTR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler; /* LR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x00000000UL;/* Backchain. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );
|
||||||
|
vPortStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here as the tasks are now running! */
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware initialisation to generate the RTOS tick.
|
||||||
|
*/
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
const unsigned long ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
|
||||||
|
XTime_DECClearInterrupt();
|
||||||
|
XTime_FITClearInterrupt();
|
||||||
|
XTime_WDTClearInterrupt();
|
||||||
|
XTime_WDTDisableInterrupt();
|
||||||
|
XTime_FITDisableInterrupt();
|
||||||
|
|
||||||
|
XExc_RegisterHandler( XEXC_ID_DEC_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );
|
||||||
|
|
||||||
|
XTime_DECEnableAutoReload();
|
||||||
|
XTime_DECSetInterval( ulInterval );
|
||||||
|
XTime_DECEnableInterrupt();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRHandler( void *pvNullDoNotUse )
|
||||||
|
{
|
||||||
|
unsigned long ulInterruptStatus, ulInterruptMask = 1UL;
|
||||||
|
portBASE_TYPE xInterruptNumber;
|
||||||
|
XIntc_Config *pxInterruptController;
|
||||||
|
XIntc_VectorTableEntry *pxTable;
|
||||||
|
|
||||||
|
/* Just to remove compiler warning. */
|
||||||
|
( void ) pvNullDoNotUse;
|
||||||
|
|
||||||
|
/* Get the configuration by using the device ID - in this case it is
|
||||||
|
assumed that only one interrupt controller is being used. */
|
||||||
|
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
||||||
|
|
||||||
|
/* Which interrupts are pending? */
|
||||||
|
ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );
|
||||||
|
|
||||||
|
for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )
|
||||||
|
{
|
||||||
|
if( ulInterruptStatus & 0x01UL )
|
||||||
|
{
|
||||||
|
/* Clear the pending interrupt. */
|
||||||
|
XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );
|
||||||
|
|
||||||
|
/* Call the registered handler. */
|
||||||
|
pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );
|
||||||
|
pxTable->Handler( pxTable->CallBackRef );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the next interrupt. */
|
||||||
|
ulInterruptMask <<= 0x01UL;
|
||||||
|
ulInterruptStatus >>= 0x01UL;
|
||||||
|
|
||||||
|
/* Have we serviced all interrupts? */
|
||||||
|
if( ulInterruptStatus == 0UL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSetupInterruptController( void )
|
||||||
|
{
|
||||||
|
extern void vPortISRWrapper( void );
|
||||||
|
|
||||||
|
/* Perform all library calls necessary to initialise the exception table
|
||||||
|
and interrupt controller. This assumes only one interrupt controller is in
|
||||||
|
use. */
|
||||||
|
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
XExc_Init();
|
||||||
|
|
||||||
|
/* The library functions save the context - we then jump to a wrapper to
|
||||||
|
save the stack into the TCB. The wrapper then calls the handler defined
|
||||||
|
above. */
|
||||||
|
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
||||||
|
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
||||||
|
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn = pdFAIL;
|
||||||
|
|
||||||
|
/* This function is defined here so the scope of xInterruptController can
|
||||||
|
remain within this file. */
|
||||||
|
|
||||||
|
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
||||||
|
{
|
||||||
|
XIntc_Enable( &xInterruptController, ucInterruptID );
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
.extern pxCurrentTCB
|
||||||
|
.extern vTaskSwitchContext
|
||||||
|
.extern vTaskIncrementTick
|
||||||
|
.extern vPortISRHandler
|
||||||
|
|
||||||
|
.global vPortStartFirstTask
|
||||||
|
.global vPortYield
|
||||||
|
.global vPortTickISR
|
||||||
|
.global vPortISRWrapper
|
||||||
|
.global vPortSaveFPURegisters
|
||||||
|
.global vPortRestoreFPURegisters
|
||||||
|
|
||||||
|
.set BChainField, 0
|
||||||
|
.set NextLRField, BChainField + 4
|
||||||
|
.set MSRField, NextLRField + 4
|
||||||
|
.set PCField, MSRField + 4
|
||||||
|
.set LRField, PCField + 4
|
||||||
|
.set CTRField, LRField + 4
|
||||||
|
.set XERField, CTRField + 4
|
||||||
|
.set CRField, XERField + 4
|
||||||
|
.set USPRG0Field, CRField + 4
|
||||||
|
.set r0Field, USPRG0Field + 4
|
||||||
|
.set r2Field, r0Field + 4
|
||||||
|
.set r3r31Field, r2Field + 4
|
||||||
|
.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
|
||||||
|
|
||||||
|
|
||||||
|
.macro portSAVE_STACK_POINTER_AND_LR
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis R2, R0, pxCurrentTCB@ha
|
||||||
|
lwz R2, pxCurrentTCB@l( R2 )
|
||||||
|
|
||||||
|
/* Store the stack pointer into the TCB */
|
||||||
|
stw SP, 0( R2 )
|
||||||
|
|
||||||
|
/* Save the link register */
|
||||||
|
stwu R1, -24( R1 )
|
||||||
|
mflr R0
|
||||||
|
stw R31, 20( R1 )
|
||||||
|
stw R0, 28( R1 )
|
||||||
|
mr R31, r1
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
|
||||||
|
/* Restore the link register */
|
||||||
|
lwz R11, 0( R1 )
|
||||||
|
lwz R0, 4( R11 )
|
||||||
|
mtlr R0
|
||||||
|
lwz R31, -4( R11 )
|
||||||
|
mr R1, R11
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis SP, R0, pxCurrentTCB@ha
|
||||||
|
lwz SP, pxCurrentTCB@l( R1 )
|
||||||
|
|
||||||
|
/* Get the task stack pointer from the TCB. */
|
||||||
|
lwz SP, 0( SP )
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
vPortStartFirstTask:
|
||||||
|
|
||||||
|
/* Get the address of the TCB. */
|
||||||
|
xor R0, R0, R0
|
||||||
|
addis SP, R0, pxCurrentTCB@ha
|
||||||
|
lwz SP, pxCurrentTCB@l( SP )
|
||||||
|
|
||||||
|
/* Get the task stack pointer from the TCB. */
|
||||||
|
lwz SP, 0( SP )
|
||||||
|
|
||||||
|
/* Restore MSR register to SRR1. */
|
||||||
|
lwz R0, MSRField(R1)
|
||||||
|
mtsrr1 R0
|
||||||
|
|
||||||
|
/* Restore current PC location to SRR0. */
|
||||||
|
lwz R0, PCField(R1)
|
||||||
|
mtsrr0 R0
|
||||||
|
|
||||||
|
/* Save USPRG0 register */
|
||||||
|
lwz R0, USPRG0Field(R1)
|
||||||
|
mtspr 0x100,R0
|
||||||
|
|
||||||
|
/* Restore Condition register */
|
||||||
|
lwz R0, CRField(R1)
|
||||||
|
mtcr R0
|
||||||
|
|
||||||
|
/* Restore Fixed Point Exception register */
|
||||||
|
lwz R0, XERField(R1)
|
||||||
|
mtxer R0
|
||||||
|
|
||||||
|
/* Restore Counter register */
|
||||||
|
lwz R0, CTRField(R1)
|
||||||
|
mtctr R0
|
||||||
|
|
||||||
|
/* Restore Link register */
|
||||||
|
lwz R0, LRField(R1)
|
||||||
|
mtlr R0
|
||||||
|
|
||||||
|
/* Restore remaining GPR registers. */
|
||||||
|
lmw R3,r3r31Field(R1)
|
||||||
|
|
||||||
|
/* Restore r0 and r2. */
|
||||||
|
lwz R0, r0Field(R1)
|
||||||
|
lwz R2, r2Field(R1)
|
||||||
|
|
||||||
|
/* Remove frame from stack */
|
||||||
|
addi R1,R1,IFrameSize
|
||||||
|
|
||||||
|
/* Return into the first task */
|
||||||
|
rfi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vPortYield:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
vPortTickISR:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vTaskIncrementTick
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear the interrupt */
|
||||||
|
lis R0, 2048
|
||||||
|
mttsr R0
|
||||||
|
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
vPortISRWrapper:
|
||||||
|
|
||||||
|
portSAVE_STACK_POINTER_AND_LR
|
||||||
|
bl vPortISRHandler
|
||||||
|
portRESTORE_STACK_POINTER_AND_LR
|
||||||
|
blr
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
|
||||||
|
vPortSaveFPURegisters:
|
||||||
|
|
||||||
|
/* Enable APU and mark FPU as present. */
|
||||||
|
mfmsr r0
|
||||||
|
xor r30, r30, r30
|
||||||
|
oris r30, r30, 512
|
||||||
|
ori r30, r30, 8192
|
||||||
|
or r0, r0, r30
|
||||||
|
mtmsr r0
|
||||||
|
|
||||||
|
#ifdef USE_DP_FPU
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Save each flop register into an offset from
|
||||||
|
this buffer address. */
|
||||||
|
stfd f0, 0(r3)
|
||||||
|
stfd f1, 8(r3)
|
||||||
|
stfd f2, 16(r3)
|
||||||
|
stfd f3, 24(r3)
|
||||||
|
stfd f4, 32(r3)
|
||||||
|
stfd f5, 40(r3)
|
||||||
|
stfd f6, 48(r3)
|
||||||
|
stfd f7, 56(r3)
|
||||||
|
stfd f8, 64(r3)
|
||||||
|
stfd f9, 72(r3)
|
||||||
|
stfd f10, 80(r3)
|
||||||
|
stfd f11, 88(r3)
|
||||||
|
stfd f12, 96(r3)
|
||||||
|
stfd f13, 104(r3)
|
||||||
|
stfd f14, 112(r3)
|
||||||
|
stfd f15, 120(r3)
|
||||||
|
stfd f16, 128(r3)
|
||||||
|
stfd f17, 136(r3)
|
||||||
|
stfd f18, 144(r3)
|
||||||
|
stfd f19, 152(r3)
|
||||||
|
stfd f20, 160(r3)
|
||||||
|
stfd f21, 168(r3)
|
||||||
|
stfd f22, 176(r3)
|
||||||
|
stfd f23, 184(r3)
|
||||||
|
stfd f24, 192(r3)
|
||||||
|
stfd f25, 200(r3)
|
||||||
|
stfd f26, 208(r3)
|
||||||
|
stfd f27, 216(r3)
|
||||||
|
stfd f28, 224(r3)
|
||||||
|
stfd f29, 232(r3)
|
||||||
|
stfd f30, 240(r3)
|
||||||
|
stfd f31, 248(r3)
|
||||||
|
|
||||||
|
/* Also save the FPSCR. */
|
||||||
|
mffs f31
|
||||||
|
stfs f31, 256(r3)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Save each flop register into an offset from
|
||||||
|
this buffer address. */
|
||||||
|
stfs f0, 0(r3)
|
||||||
|
stfs f1, 4(r3)
|
||||||
|
stfs f2, 8(r3)
|
||||||
|
stfs f3, 12(r3)
|
||||||
|
stfs f4, 16(r3)
|
||||||
|
stfs f5, 20(r3)
|
||||||
|
stfs f6, 24(r3)
|
||||||
|
stfs f7, 28(r3)
|
||||||
|
stfs f8, 32(r3)
|
||||||
|
stfs f9, 36(r3)
|
||||||
|
stfs f10, 40(r3)
|
||||||
|
stfs f11, 44(r3)
|
||||||
|
stfs f12, 48(r3)
|
||||||
|
stfs f13, 52(r3)
|
||||||
|
stfs f14, 56(r3)
|
||||||
|
stfs f15, 60(r3)
|
||||||
|
stfs f16, 64(r3)
|
||||||
|
stfs f17, 68(r3)
|
||||||
|
stfs f18, 72(r3)
|
||||||
|
stfs f19, 76(r3)
|
||||||
|
stfs f20, 80(r3)
|
||||||
|
stfs f21, 84(r3)
|
||||||
|
stfs f22, 88(r3)
|
||||||
|
stfs f23, 92(r3)
|
||||||
|
stfs f24, 96(r3)
|
||||||
|
stfs f25, 100(r3)
|
||||||
|
stfs f26, 104(r3)
|
||||||
|
stfs f27, 108(r3)
|
||||||
|
stfs f28, 112(r3)
|
||||||
|
stfs f29, 116(r3)
|
||||||
|
stfs f30, 120(r3)
|
||||||
|
stfs f31, 124(r3)
|
||||||
|
|
||||||
|
/* Also save the FPSCR. */
|
||||||
|
mffs f31
|
||||||
|
stfs f31, 128(r3)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
||||||
|
#endif /* configUSE_FPU. */
|
||||||
|
|
||||||
|
|
||||||
|
#if configUSE_FPU == 1
|
||||||
|
|
||||||
|
vPortRestoreFPURegisters:
|
||||||
|
|
||||||
|
/* Enable APU and mark FPU as present. */
|
||||||
|
mfmsr r0
|
||||||
|
xor r30, r30, r30
|
||||||
|
oris r30, r30, 512
|
||||||
|
ori r30, r30, 8192
|
||||||
|
or r0, r0, r30
|
||||||
|
mtmsr r0
|
||||||
|
|
||||||
|
#ifdef USE_DP_FPU
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Restore each flop register from an offset
|
||||||
|
into this buffer.
|
||||||
|
|
||||||
|
First the FPSCR. */
|
||||||
|
lfs f31, 256(r3)
|
||||||
|
mtfsf f31, 7
|
||||||
|
|
||||||
|
lfd f0, 0(r3)
|
||||||
|
lfd f1, 8(r3)
|
||||||
|
lfd f2, 16(r3)
|
||||||
|
lfd f3, 24(r3)
|
||||||
|
lfd f4, 32(r3)
|
||||||
|
lfd f5, 40(r3)
|
||||||
|
lfd f6, 48(r3)
|
||||||
|
lfd f7, 56(r3)
|
||||||
|
lfd f8, 64(r3)
|
||||||
|
lfd f9, 72(r3)
|
||||||
|
lfd f10, 80(r3)
|
||||||
|
lfd f11, 88(r3)
|
||||||
|
lfd f12, 96(r3)
|
||||||
|
lfd f13, 104(r3)
|
||||||
|
lfd f14, 112(r3)
|
||||||
|
lfd f15, 120(r3)
|
||||||
|
lfd f16, 128(r3)
|
||||||
|
lfd f17, 136(r3)
|
||||||
|
lfd f18, 144(r3)
|
||||||
|
lfd f19, 152(r3)
|
||||||
|
lfd f20, 160(r3)
|
||||||
|
lfd f21, 168(r3)
|
||||||
|
lfd f22, 176(r3)
|
||||||
|
lfd f23, 184(r3)
|
||||||
|
lfd f24, 192(r3)
|
||||||
|
lfd f25, 200(r3)
|
||||||
|
lfd f26, 208(r3)
|
||||||
|
lfd f27, 216(r3)
|
||||||
|
lfd f28, 224(r3)
|
||||||
|
lfd f29, 232(r3)
|
||||||
|
lfd f30, 240(r3)
|
||||||
|
lfd f31, 248(r3)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Buffer address is in r3. Restore each flop register from an offset
|
||||||
|
into this buffer.
|
||||||
|
|
||||||
|
First the FPSCR. */
|
||||||
|
lfs f31, 128(r3)
|
||||||
|
mtfsf f31, 7
|
||||||
|
|
||||||
|
lfs f0, 0(r3)
|
||||||
|
lfs f1, 4(r3)
|
||||||
|
lfs f2, 8(r3)
|
||||||
|
lfs f3, 12(r3)
|
||||||
|
lfs f4, 16(r3)
|
||||||
|
lfs f5, 20(r3)
|
||||||
|
lfs f6, 24(r3)
|
||||||
|
lfs f7, 28(r3)
|
||||||
|
lfs f8, 32(r3)
|
||||||
|
lfs f9, 36(r3)
|
||||||
|
lfs f10, 40(r3)
|
||||||
|
lfs f11, 44(r3)
|
||||||
|
lfs f12, 48(r3)
|
||||||
|
lfs f13, 52(r3)
|
||||||
|
lfs f14, 56(r3)
|
||||||
|
lfs f15, 60(r3)
|
||||||
|
lfs f16, 64(r3)
|
||||||
|
lfs f17, 68(r3)
|
||||||
|
lfs f18, 72(r3)
|
||||||
|
lfs f19, 76(r3)
|
||||||
|
lfs f20, 80(r3)
|
||||||
|
lfs f21, 84(r3)
|
||||||
|
lfs f22, 88(r3)
|
||||||
|
lfs f23, 92(r3)
|
||||||
|
lfs f24, 96(r3)
|
||||||
|
lfs f25, 100(r3)
|
||||||
|
lfs f26, 104(r3)
|
||||||
|
lfs f27, 108(r3)
|
||||||
|
lfs f28, 112(r3)
|
||||||
|
lfs f29, 116(r3)
|
||||||
|
lfs f30, 120(r3)
|
||||||
|
lfs f31, 124(r3)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
||||||
|
#endif /* configUSE_FPU. */
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#include "xexception_l.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This port uses the critical nesting count from the TCB rather than
|
||||||
|
maintaining a separate value and then saving this value in the task stack. */
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
|
||||||
|
/* Interrupt control macros. */
|
||||||
|
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section macros. */
|
||||||
|
void vTaskEnterCritical( void );
|
||||||
|
void vTaskExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task utilities. */
|
||||||
|
void vPortYield( void );
|
||||||
|
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
||||||
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
|
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
||||||
|
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
/* Port specific interrupt handling functions. */
|
||||||
|
void vPortSetupInterruptController( void );
|
||||||
|
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the SH2A port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Library includes. */
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#include "iodefine.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
|
||||||
|
PSW is set with U and I set, and PM and IPL clear. */
|
||||||
|
#define portINITIAL_PSW ( ( portSTACK_TYPE ) 0x00030000 )
|
||||||
|
#define portINITIAL_FPSW ( ( portSTACK_TYPE ) 0x00000100 )
|
||||||
|
|
||||||
|
/* These macros allow a critical section to be added around the call to
|
||||||
|
vTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
||||||
|
priority - ie a known priority. Therefore these local macros are a slight
|
||||||
|
optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
||||||
|
which would require the old IPL to be read first and stored in a local variable. */
|
||||||
|
#define portDISABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
|
#define portENABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configKERNEL_INTERRUPT_PRIORITY) )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to start the first task executing - written in asm code as direct
|
||||||
|
* access to registers is required.
|
||||||
|
*/
|
||||||
|
static void prvStartFirstTask( void ) __attribute__((naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Software interrupt handler. Performs the actual context switch (saving and
|
||||||
|
* restoring of registers). Written in asm code as direct register access is
|
||||||
|
* required.
|
||||||
|
*/
|
||||||
|
void vSoftwareInterruptISR( void ) __attribute__((naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tick interrupt handler.
|
||||||
|
*/
|
||||||
|
void vTickISR( void ) __attribute__((interrupt));
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
/* R0 is not included as it is the stack pointer. */
|
||||||
|
|
||||||
|
*pxTopOfStack = 0x00;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_PSW;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
|
||||||
|
|
||||||
|
/* When debugging it can be useful if every register is set to a known
|
||||||
|
value. Otherwise code space can be saved by just setting the registers
|
||||||
|
that need to be set. */
|
||||||
|
#ifdef USE_FULL_REGISTER_INITIALISATION
|
||||||
|
{
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xffffffff; /* r15. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xeeeeeeee;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xdddddddd;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xcccccccc;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xbbbbbbbb;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0xaaaaaaaa;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x99999999;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x88888888;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x77777777;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x66666666;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x55555555;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x44444444;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x33333333;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x22222222;
|
||||||
|
pxTopOfStack--;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
pxTopOfStack -= 15;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = portINITIAL_FPSW;
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x12345678; /* Accumulator. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = 0x87654321; /* Accumulator. */
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/* Use pxCurrentTCB just so it does not get optimised away. */
|
||||||
|
if( pxCurrentTCB != NULL )
|
||||||
|
{
|
||||||
|
/* Call an application function to set up the timer that will generate the
|
||||||
|
tick interrupt. This way the application can decide which peripheral to
|
||||||
|
use. A demo application is provided to show a suitable example. */
|
||||||
|
vApplicationSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Enable the software interrupt. */
|
||||||
|
_IEN( _ICU_SWINT ) = 1;
|
||||||
|
|
||||||
|
/* Ensure the software interrupt is clear. */
|
||||||
|
_IR( _ICU_SWINT ) = 0;
|
||||||
|
|
||||||
|
/* Ensure the software interrupt is set to the kernel priority. */
|
||||||
|
_IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
prvStartFirstTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should not get here. */
|
||||||
|
return pdFAIL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* Not implemented as there is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvStartFirstTask( void )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
/* When starting the scheduler there is nothing that needs moving to the
|
||||||
|
interrupt stack because the function is not called from an interrupt.
|
||||||
|
Just ensure the current stack is the user stack. */
|
||||||
|
"SETPSW U \n" \
|
||||||
|
|
||||||
|
/* Obtain the location of the stack associated with which ever task
|
||||||
|
pxCurrentTCB is currently pointing to. */
|
||||||
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
|
"MOV.L [R15], R15 \n" \
|
||||||
|
"MOV.L [R15], R0 \n" \
|
||||||
|
|
||||||
|
/* Restore the registers from the stack of the task pointed to by
|
||||||
|
pxCurrentTCB. */
|
||||||
|
"POP R15 \n" \
|
||||||
|
|
||||||
|
/* Accumulator low 32 bits. */
|
||||||
|
"MVTACLO R15 \n" \
|
||||||
|
"POP R15 \n" \
|
||||||
|
|
||||||
|
/* Accumulator high 32 bits. */
|
||||||
|
"MVTACHI R15 \n" \
|
||||||
|
"POP R15 \n" \
|
||||||
|
|
||||||
|
/* Floating point status word. */
|
||||||
|
"MVTC R15, FPSW \n" \
|
||||||
|
|
||||||
|
/* R1 to R15 - R0 is not included as it is the SP. */
|
||||||
|
"POPM R1-R15 \n" \
|
||||||
|
|
||||||
|
/* This pops the remaining registers. */
|
||||||
|
"RTE \n" \
|
||||||
|
"NOP \n" \
|
||||||
|
"NOP \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vSoftwareInterruptISR( void )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
/* Re-enable interrupts. */
|
||||||
|
"SETPSW I \n" \
|
||||||
|
|
||||||
|
/* Move the data that was automatically pushed onto the interrupt stack when
|
||||||
|
the interrupt occurred from the interrupt stack to the user stack.
|
||||||
|
|
||||||
|
R15 is saved before it is clobbered. */
|
||||||
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
|
/* Read the user stack pointer. */
|
||||||
|
"MVFC USP, R15 \n" \
|
||||||
|
|
||||||
|
/* Move the address down to the data being moved. */
|
||||||
|
"SUB #12, R15 \n" \
|
||||||
|
"MVTC R15, USP \n" \
|
||||||
|
|
||||||
|
/* Copy the data across, R15, then PC, then PSW. */
|
||||||
|
"MOV.L [ R0 ], [ R15 ] \n" \
|
||||||
|
"MOV.L 4[ R0 ], 4[ R15 ] \n" \
|
||||||
|
"MOV.L 8[ R0 ], 8[ R15 ] \n" \
|
||||||
|
|
||||||
|
/* Move the interrupt stack pointer to its new correct position. */
|
||||||
|
"ADD #12, R0 \n" \
|
||||||
|
|
||||||
|
/* All the rest of the registers are saved directly to the user stack. */
|
||||||
|
"SETPSW U \n" \
|
||||||
|
|
||||||
|
/* Save the rest of the general registers (R15 has been saved already). */
|
||||||
|
"PUSHM R1-R14 \n" \
|
||||||
|
|
||||||
|
/* Save the FPSW and accumulator. */
|
||||||
|
"MVFC FPSW, R15 \n" \
|
||||||
|
"PUSH.L R15 \n" \
|
||||||
|
"MVFACHI R15 \n" \
|
||||||
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
|
/* Middle word. */
|
||||||
|
"MVFACMI R15 \n" \
|
||||||
|
|
||||||
|
/* Shifted left as it is restored to the low order word. */
|
||||||
|
"SHLL #16, R15 \n" \
|
||||||
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
|
/* Save the stack pointer to the TCB. */
|
||||||
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
|
"MOV.L R0, [ R15 ] \n" \
|
||||||
|
|
||||||
|
/* Ensure the interrupt mask is set to the syscall priority while the kernel
|
||||||
|
structures are being accessed. */
|
||||||
|
"MVTIPL %0 \n" \
|
||||||
|
|
||||||
|
/* Select the next task to run. */
|
||||||
|
"BSR.A _vTaskSwitchContext \n" \
|
||||||
|
|
||||||
|
/* Reset the interrupt mask as no more data structure access is required. */
|
||||||
|
"MVTIPL %1 \n" \
|
||||||
|
|
||||||
|
/* Load the stack pointer of the task that is now selected as the Running
|
||||||
|
state task from its TCB. */
|
||||||
|
"MOV.L #_pxCurrentTCB,R15 \n" \
|
||||||
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
|
"MOV.L [ R15 ], R0 \n" \
|
||||||
|
|
||||||
|
/* Restore the context of the new task. The PSW (Program Status Word) and
|
||||||
|
PC will be popped by the RTE instruction. */
|
||||||
|
"POP R15 \n" \
|
||||||
|
"MVTACLO R15 \n" \
|
||||||
|
"POP R15 \n" \
|
||||||
|
"MVTACHI R15 \n" \
|
||||||
|
"POP R15 \n" \
|
||||||
|
"MVTC R15, FPSW \n" \
|
||||||
|
"POPM R1-R15 \n" \
|
||||||
|
"RTE \n" \
|
||||||
|
"NOP \n" \
|
||||||
|
"NOP "
|
||||||
|
:: "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY), "i"(configKERNEL_INTERRUPT_PRIORITY)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vTickISR( void )
|
||||||
|
{
|
||||||
|
/* Re-enabled interrupts. */
|
||||||
|
__asm volatile( "SETPSW I" );
|
||||||
|
|
||||||
|
/* Increment the tick, and perform any processing the new tick value
|
||||||
|
necessitates. Ensure IPL is at the max syscall value first. */
|
||||||
|
portDISABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
||||||
|
{
|
||||||
|
vTaskIncrementTick();
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
||||||
|
|
||||||
|
/* Only select a new task if the preemptive scheduler is being used. */
|
||||||
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned long ulPortGetIPL( void )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
"MVFC PSW, R1 \n" \
|
||||||
|
"SHLR #24, R1 \n" \
|
||||||
|
"RTS "
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This will never get executed, but keeps the compiler from complaining. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSetIPL( unsigned long ulNewIPL )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
"PUSH R5 \n" \
|
||||||
|
"MVFC PSW, R5 \n" \
|
||||||
|
"SHLL #24, R1 \n" \
|
||||||
|
"AND #-0F000001H, R5 \n" \
|
||||||
|
"OR R1, R5 \n" \
|
||||||
|
"MVTC R5, PSW \n" \
|
||||||
|
"POP R5 \n" \
|
||||||
|
"RTS "
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions - these are a bit legacy and not really used now, other than
|
||||||
|
portSTACK_TYPE and portBASE_TYPE. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE unsigned portLONG
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef unsigned portSHORT portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef unsigned portLONG portTickType;
|
||||||
|
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Hardware specifics. */
|
||||||
|
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
|
||||||
|
#define portSTACK_GROWTH -1
|
||||||
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
|
|
||||||
|
/* The location of the software interrupt register. Software interrupts use
|
||||||
|
vector 27. */
|
||||||
|
#define portITU_SWINTR ( ( unsigned char * ) 0x000872E0 )
|
||||||
|
#define portYIELD() *portITU_SWINTR = 0x01; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||||
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) portYIELD()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros should be called directly, but through the taskENTER_CRITICAL()
|
||||||
|
* and taskEXIT_CRITICAL() macros.
|
||||||
|
*/
|
||||||
|
#define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" );
|
||||||
|
#define portDISABLE_INTERRUPTS() __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
|
|
||||||
|
/* Critical nesting counts are stored in the TCB. */
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB ( 1 )
|
||||||
|
|
||||||
|
/* The critical nesting functions defined within tasks.c. */
|
||||||
|
extern void vTaskEnterCritical( void );
|
||||||
|
extern void vTaskExitCritical( void );
|
||||||
|
#define portENTER_CRITICAL() vTaskEnterCritical();
|
||||||
|
#define portEXIT_CRITICAL() vTaskExitCritical();
|
||||||
|
|
||||||
|
/* As this port allows interrupt nesting... */
|
||||||
|
unsigned long ulPortGetIPL( void ) __attribute__((naked));
|
||||||
|
void vPortSetIPL( unsigned long ulNewIPL ) __attribute__((naked));
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortGetIPL(); portDISABLE_INTERRUPTS()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) vPortSetIPL( uxSavedInterruptStatus )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Implementation of functions defined in portable.h for the ST STR75x ARM7
|
||||||
|
* port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Library includes. */
|
||||||
|
#include "75x_tb.h"
|
||||||
|
#include "75x_eic.h"
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to setup the initial stack. */
|
||||||
|
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||||
|
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
|
||||||
|
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
|
||||||
|
/* Prescale used on the timer clock when calculating the tick period. */
|
||||||
|
#define portPRESCALE 20
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Setup the TB to generate the tick interrupts. */
|
||||||
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the stack of a task to look exactly as if a call to
|
||||||
|
* portSAVE_CONTEXT had been called.
|
||||||
|
*
|
||||||
|
* See header file for description.
|
||||||
|
*/
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||||
|
{
|
||||||
|
portSTACK_TYPE *pxOriginalTOS;
|
||||||
|
|
||||||
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
|
is not really required. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
|
/* First on the stack is the return address - which in this case is the
|
||||||
|
start of the task. The offset is added to make the return address appear
|
||||||
|
as it would within an IRQ ISR. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* When the task starts is will expect to find the function parameter in
|
||||||
|
R0. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* The status register is set for system mode, with interrupts enabled. */
|
||||||
|
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||||
|
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
{
|
||||||
|
/* We want the task to start in thumb mode. */
|
||||||
|
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
/* Interrupt flags cannot always be stored on the stack and will
|
||||||
|
instead be stored in a variable, which is then saved as part of the
|
||||||
|
tasks context. */
|
||||||
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
|
|
||||||
|
return pxTopOfStack;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
|
{
|
||||||
|
extern void vPortISRStartFirstTask( void );
|
||||||
|
|
||||||
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
|
here already. */
|
||||||
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
|
/* Start the first task. */
|
||||||
|
vPortISRStartFirstTask();
|
||||||
|
|
||||||
|
/* Should not get here! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEndScheduler( void )
|
||||||
|
{
|
||||||
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
|
is nothing to return to. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
EIC_IRQInitTypeDef EIC_IRQInitStructure;
|
||||||
|
TB_InitTypeDef TB_InitStructure;
|
||||||
|
|
||||||
|
/* Setup the EIC for the TB. */
|
||||||
|
EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE;
|
||||||
|
EIC_IRQInitStructure.EIC_IRQChannel = TB_IRQChannel;
|
||||||
|
EIC_IRQInitStructure.EIC_IRQChannelPriority = 1;
|
||||||
|
EIC_IRQInit(&EIC_IRQInitStructure);
|
||||||
|
|
||||||
|
/* Setup the TB for the generation of the tick interrupt. */
|
||||||
|
TB_InitStructure.TB_Mode = TB_Mode_Timing;
|
||||||
|
TB_InitStructure.TB_CounterMode = TB_CounterMode_Down;
|
||||||
|
TB_InitStructure.TB_Prescaler = portPRESCALE - 1;
|
||||||
|
TB_InitStructure.TB_AutoReload = ( ( configCPU_CLOCK_HZ / portPRESCALE ) / configTICK_RATE_HZ );
|
||||||
|
TB_Init(&TB_InitStructure);
|
||||||
|
|
||||||
|
/* Enable TB Update interrupt */
|
||||||
|
TB_ITConfig(TB_IT_Update, ENABLE);
|
||||||
|
|
||||||
|
/* Clear TB Update interrupt pending bit */
|
||||||
|
TB_ClearITPendingBit(TB_IT_Update);
|
||||||
|
|
||||||
|
/* Enable TB */
|
||||||
|
TB_Cmd(ENABLE);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
|
* to ARM mode, are contained in this file.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Constants required to handle critical sections. */
|
||||||
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
|
|
||||||
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
* function here.
|
||||||
|
*/
|
||||||
|
void vPortISRStartFirstTask( void );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortISRStartFirstTask( void )
|
||||||
|
{
|
||||||
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
|
called from ARM mode. */
|
||||||
|
asm volatile ( \
|
||||||
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
|
"LDR R0, [R0] \n\t" \
|
||||||
|
"LDR LR, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
|
"STR R1, [R0] \n\t" \
|
||||||
|
\
|
||||||
|
/* Get the SPSR from the stack. */ \
|
||||||
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
|
"MSR SPSR, R0 \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore all system mode registers for the task. */ \
|
||||||
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
|
"NOP \n\t" \
|
||||||
|
\
|
||||||
|
/* Restore the return address. */ \
|
||||||
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
|
\
|
||||||
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
|
/* correct address. */ \
|
||||||
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortTickISR( void )
|
||||||
|
{
|
||||||
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
|
task that is ready to run. */
|
||||||
|
vTaskIncrementTick();
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 1
|
||||||
|
vTaskSwitchContext();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ready for the next interrupt. */
|
||||||
|
TB_ClearITPendingBit( TB_IT_Update );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interrupt management utilities can only be called from ARM mode. When
|
||||||
|
* THUMB_INTERWORK is defined the utilities are defined as functions here to
|
||||||
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
|
*/
|
||||||
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
|
"BX R14" ); /* Return back to thumb. */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* THUMB_INTERWORK */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortEnterCritical( void )
|
||||||
|
{
|
||||||
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
portENTER_CRITICAL() has been called. */
|
||||||
|
ulCriticalNesting++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortExitCritical( void )
|
||||||
|
{
|
||||||
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Decrement the nesting count as we are leaving a critical section. */
|
||||||
|
ulCriticalNesting--;
|
||||||
|
|
||||||
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
|
re-enabled. */
|
||||||
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
|
{
|
||||||
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
|
asm volatile (
|
||||||
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user