mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
upgrade freertos to v10
This commit is contained in:
parent
9a2924fb36
commit
52ed2547cd
@ -238,6 +238,7 @@
|
|||||||
<option id="gnu.c.compiler.option.misc.other.2122594924" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
|
<option id="gnu.c.compiler.option.misc.other.2122594924" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
|
||||||
<option id="gnu.c.compiler.option.include.paths.1913705177" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
<option id="gnu.c.compiler.option.include.paths.1913705177" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/mcu/lpc43xx/CMSIS_LPC43xx_DriverLib/inc}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/mcu/lpc43xx/CMSIS_LPC43xx_DriverLib/inc}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freertos/freertos/Source/portable/GCC/ARM_CM4F}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/boards}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/boards}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/tinyusb}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/tinyusb}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/>
|
||||||
|
@ -70,7 +70,7 @@ typedef void* osal_task_t;
|
|||||||
static inline osal_task_t osal_task_create(osal_func_t code, const char* name, uint32_t stack_size, void* param, uint32_t prio)
|
static inline osal_task_t osal_task_create(osal_func_t code, const char* name, uint32_t stack_size, void* param, uint32_t prio)
|
||||||
{
|
{
|
||||||
osal_task_t task_hdl;
|
osal_task_t task_hdl;
|
||||||
xTaskCreate(code, (const signed char*) name, stack_size, param, prio, &task_hdl);
|
xTaskCreate(code, (const char*) name, stack_size, param, prio, &task_hdl);
|
||||||
return task_hdl;
|
return task_hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
vendor/freertos/FreeRTOSConfig.h
vendored
36
vendor/freertos/FreeRTOSConfig.h
vendored
@ -1,11 +1,8 @@
|
|||||||
#ifndef __FREERTOS_CONFIG__H
|
#ifndef __FREERTOS_CONFIG__H
|
||||||
#define __FREERTOS_CONFIG__H
|
#define __FREERTOS_CONFIG__H
|
||||||
|
|
||||||
#ifndef __IASMARM__
|
|
||||||
// IAR assembler "compile" portarm.s need to include this file but cannot understand many other headers.
|
|
||||||
#include "hal/hal.h"
|
#include "hal/hal.h"
|
||||||
#include "common/assertion.h"
|
#include "common/assertion.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// See http://www.freertos.org/a00110.html.
|
// See http://www.freertos.org/a00110.html.
|
||||||
@ -18,8 +15,8 @@
|
|||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 )
|
#define configMAX_PRIORITIES (8 )
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
|
#define configMINIMAL_STACK_SIZE (128 )
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16*1024 ) )
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16*1024 ) )
|
||||||
#define configMAX_TASK_NAME_LEN 32
|
#define configMAX_TASK_NAME_LEN 32
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
@ -104,33 +101,4 @@ to all Cortex-M ports, and do not rely on any particular library functions. */
|
|||||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// portmacro.h include path
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
#ifndef __IASMARM__ // avoid messing up with IAR
|
|
||||||
|
|
||||||
#if defined __CC_ARM
|
|
||||||
#define TOOL_DIR RVDS
|
|
||||||
#elif defined __GNUC__
|
|
||||||
#define TOOL_DIR GCC
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
#define TOOL_DIR IAR
|
|
||||||
#else
|
|
||||||
#error "not yet supported toolchain"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __CORTEX_M == 4
|
|
||||||
#define ARCH_DIR ARM_CM4F
|
|
||||||
#elif __CORTEX_M == 3
|
|
||||||
#define ARCH_DIR ARM_CM3
|
|
||||||
#elif __CORTEX_M == 0
|
|
||||||
#define ARCH_DIR ARM_CM0
|
|
||||||
#else
|
|
||||||
#error "not yet supported MCU"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include XSTRING_(freertos/Source/portable/TOOL_DIR/ARCH_DIR/portmacro.h)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __FREERTOS_CONFIG__H */
|
#endif /* __FREERTOS_CONFIG__H */
|
||||||
|
430
vendor/freertos/freertos/License/license.txt
vendored
430
vendor/freertos/freertos/License/license.txt
vendored
@ -1,394 +1,38 @@
|
|||||||
The FreeRTOS source code is licensed by a *modified* GNU General Public
|
The FreeRTOS kernel is released under the MIT open source license, the text of
|
||||||
License (GPL). The modification is provided in the form of an exception.
|
which is provided below.
|
||||||
|
|
||||||
NOTE: The modification to the GPL is included to allow you to distribute a
|
This license covers the FreeRTOS kernel source files, which are located in the
|
||||||
combined work that includes FreeRTOS without being obliged to provide the source
|
/FreeRTOS/Source directory of the official FreeRTOS kernel download. It also
|
||||||
code for proprietary components outside of the FreeRTOS kernel.
|
covers most of the source files in the demo application projects, which are
|
||||||
|
located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The
|
||||||
|
demo projects may also include third party software that is not part of FreeRTOS
|
||||||
|
and is licensed separately to FreeRTOS. Examples of third party software
|
||||||
----------------------------------------------------------------------------
|
includes header files provided by chip or tools vendors, linker scripts,
|
||||||
|
peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS
|
||||||
The FreeRTOS GPL Exception Text:
|
directory is either open source or distributed with permission, and is free for
|
||||||
|
use. For the avoidance of doubt, refer to the comments at the top of each
|
||||||
Any FreeRTOS source code, whether modified or in it's original release form,
|
source file.
|
||||||
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.
|
License text:
|
||||||
|
-------------
|
||||||
Clause 1:
|
|
||||||
|
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
Linking FreeRTOS statically or dynamically with other modules is making a
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
combined work based on FreeRTOS. Thus, the terms and conditions of the GNU
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
General Public License cover the whole combination.
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
As a special exception, the copyright holder of FreeRTOS gives you permission
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
to link FreeRTOS with independent modules that communicate with FreeRTOS
|
subject to the following conditions:
|
||||||
solely through the FreeRTOS API interface, regardless of the license terms of
|
|
||||||
these independent modules, and to copy and distribute the resulting combined
|
The above copyright notice and this permission notice shall be included in all
|
||||||
work under terms of your choice, provided that
|
copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
+ 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
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
to provide the FreeRTOS source code (including any modifications you may have
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
made) should the recipient request it.
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+ 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).
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
|
|
||||||
The standard GPL exception text:
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
168
vendor/freertos/freertos/Source/croutine.c
vendored
168
vendor/freertos/freertos/Source/croutine.c
vendored
@ -1,72 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "croutine.h"
|
#include "croutine.h"
|
||||||
|
|
||||||
|
/* Remove the whole file is co-routines are not being used. */
|
||||||
|
#if( configUSE_CO_ROUTINES != 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
@ -77,17 +43,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Lists for ready and blocked co-routines. --------------------*/
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
static List_t 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 List_t 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 List_t * 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 List_t * 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. */
|
static List_t 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. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
corCRCB * pxCurrentCoRoutine = NULL;
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
|
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||||
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
/* The initial state of the co-routine when it is created. */
|
/* The initial state of the co-routine when it is created. */
|
||||||
#define corINITIAL_STATE ( 0 )
|
#define corINITIAL_STATE ( 0 )
|
||||||
@ -105,7 +71,7 @@ static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks =
|
|||||||
{ \
|
{ \
|
||||||
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
} \
|
} \
|
||||||
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -134,13 +100,13 @@ static void prvCheckDelayedList( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
BaseType_t xReturn;
|
||||||
corCRCB *pxCoRoutine;
|
CRCB_t *pxCoRoutine;
|
||||||
|
|
||||||
/* Allocate the memory that will store the co-routine control block. */
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
|
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||||
if( pxCoRoutine )
|
if( pxCoRoutine )
|
||||||
{
|
{
|
||||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
@ -167,14 +133,14 @@ corCRCB *pxCoRoutine;
|
|||||||
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
/* Set the co-routine control block as a link back from the xListItem.
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
This is so we can get back to the containing CRCB from a generic item
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
in a list. */
|
in a list. */
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
/* Event lists are always in priority order. */
|
/* Event lists are always in priority order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||||
|
|
||||||
/* Now the co-routine has been initialised it can be added to the ready
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
list at the correct priority. */
|
list at the correct priority. */
|
||||||
@ -191,9 +157,9 @@ corCRCB *pxCoRoutine;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
||||||
{
|
{
|
||||||
portTickType xTimeToWake;
|
TickType_t xTimeToWake;
|
||||||
|
|
||||||
/* Calculate the time to wake - this may overflow but this is
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
not a problem. */
|
not a problem. */
|
||||||
@ -202,7 +168,7 @@ portTickType xTimeToWake;
|
|||||||
/* We must remove ourselves from the ready list before adding
|
/* We must remove ourselves from the ready list before adding
|
||||||
ourselves to the blocked list as the same list item is used for
|
ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
both lists. */
|
||||||
( void ) uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
/* The list item will be inserted in wake time order. */
|
/* The list item will be inserted in wake time order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||||
@ -211,13 +177,13 @@ portTickType xTimeToWake;
|
|||||||
{
|
{
|
||||||
/* Wake time has overflowed. Place this item in the
|
/* Wake time has overflowed. Place this item in the
|
||||||
overflow list. */
|
overflow list. */
|
||||||
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The wake time has not overflowed, so we can use the
|
/* The wake time has not overflowed, so we can use the
|
||||||
current block list. */
|
current block list. */
|
||||||
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxEventList )
|
if( pxEventList )
|
||||||
@ -236,12 +202,12 @@ static void prvCheckPendingReadyList( void )
|
|||||||
the ready lists itself. */
|
the ready lists itself. */
|
||||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
corCRCB *pxUnblockedCRCB;
|
CRCB_t *pxUnblockedCRCB;
|
||||||
|
|
||||||
/* The pending ready list can be accessed by an ISR. */
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
@ -254,7 +220,7 @@ static void prvCheckPendingReadyList( void )
|
|||||||
|
|
||||||
static void prvCheckDelayedList( void )
|
static void prvCheckDelayedList( void )
|
||||||
{
|
{
|
||||||
corCRCB *pxCRCB;
|
CRCB_t *pxCRCB;
|
||||||
|
|
||||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
while( xPassedTicks )
|
while( xPassedTicks )
|
||||||
@ -265,7 +231,7 @@ corCRCB *pxCRCB;
|
|||||||
/* If the tick count has overflowed we need to swap the ready lists. */
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
if( xCoRoutineTickCount == 0 )
|
if( xCoRoutineTickCount == 0 )
|
||||||
{
|
{
|
||||||
xList * pxTemp;
|
List_t * pxTemp;
|
||||||
|
|
||||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
/* 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! */
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
@ -277,7 +243,7 @@ corCRCB *pxCRCB;
|
|||||||
/* See if this tick has made a timeout expire. */
|
/* See if this tick has made a timeout expire. */
|
||||||
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||||
|
|
||||||
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||||
{
|
{
|
||||||
@ -292,7 +258,7 @@ corCRCB *pxCRCB;
|
|||||||
have been moved to the pending ready list and the following
|
have been moved to the pending ready list and the following
|
||||||
line is still valid. Also the pvContainer parameter will have
|
line is still valid. Also the pvContainer parameter will have
|
||||||
been set to NULL so the following lines are also valid. */
|
been set to NULL so the following lines are also valid. */
|
||||||
uxListRemove( &( pxCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
/* Is the co-routine waiting on an event also? */
|
/* Is the co-routine waiting on an event also? */
|
||||||
if( pxCRCB->xEventListItem.pvContainer )
|
if( pxCRCB->xEventListItem.pvContainer )
|
||||||
@ -342,16 +308,16 @@ void vCoRoutineSchedule( void )
|
|||||||
|
|
||||||
static void prvInitialiseCoRoutineLists( void )
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
{
|
{
|
||||||
unsigned portBASE_TYPE uxPriority;
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
{
|
{
|
||||||
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
|
||||||
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
|
||||||
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
|
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
pxOverflowDelayedCoRoutineList using list2. */
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
@ -360,17 +326,17 @@ unsigned portBASE_TYPE uxPriority;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
||||||
{
|
{
|
||||||
corCRCB *pxUnblockedCRCB;
|
CRCB_t *pxUnblockedCRCB;
|
||||||
signed portBASE_TYPE xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* This function is called from within an interrupt. It can only access
|
/* This function is called from within an interrupt. It can only access
|
||||||
event lists and the pending ready list. This function assumes that a
|
event lists and the pending ready list. This function assumes that a
|
||||||
check has already been made to ensure pxEventList is not empty. */
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
||||||
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||||
{
|
{
|
||||||
@ -384,3 +350,5 @@ signed portBASE_TYPE xReturn;
|
|||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||||
|
|
||||||
|
739
vendor/freertos/freertos/Source/event_groups.c
vendored
Normal file
739
vendor/freertos/freertos/Source/event_groups.c
vendored
Normal file
@ -0,0 +1,739 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
all the API functions to use the MPU wrappers. That should only be done when
|
||||||
|
task.h is included from an application file. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
|
||||||
|
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
||||||
|
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
||||||
|
header files above, but not in this file, in order to generate the correct
|
||||||
|
privileged Vs unprivileged linkage and placement. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||||
|
|
||||||
|
/* The following bit fields convey control information in a task's event list
|
||||||
|
item value. It is important they don't clash with the
|
||||||
|
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||||
|
#if configUSE_16_BIT_TICKS == 1
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
||||||
|
#else
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct xEventGroupDefinition
|
||||||
|
{
|
||||||
|
EventBits_t uxEventBits;
|
||||||
|
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||||
|
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t uxEventGroupNumber;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
|
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||||
|
#endif
|
||||||
|
} EventGroup_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||||
|
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||||
|
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||||
|
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||||
|
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||||
|
* in uxCurrentEventBits.
|
||||||
|
*/
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits;
|
||||||
|
|
||||||
|
/* A StaticEventGroup_t object must be provided. */
|
||||||
|
configASSERT( pxEventGroupBuffer );
|
||||||
|
|
||||||
|
#if( configASSERT_DEFINED == 1 )
|
||||||
|
{
|
||||||
|
/* Sanity check that the size of the structure used to declare a
|
||||||
|
variable of type StaticEventGroup_t equals the size of the real
|
||||||
|
event group structure. */
|
||||||
|
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||||
|
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||||
|
}
|
||||||
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
/* The user has provided a statically allocated event group - use it. */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||||
|
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note that
|
||||||
|
this event group was created statically in case the event group
|
||||||
|
is later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( EventGroupHandle_t ) pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits;
|
||||||
|
|
||||||
|
/* Allocate the event group. */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
||||||
|
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note this
|
||||||
|
event group was allocated statically in case the event group is
|
||||||
|
later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( EventGroupHandle_t ) pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventBits_t uxOriginalBitValue, uxReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
/* All the rendezvous bits are now set - no need to block. */
|
||||||
|
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||||
|
|
||||||
|
/* Rendezvous always clear the bits. They will have been cleared
|
||||||
|
already unless this is the only task in the rendezvous. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
|
||||||
|
xTicksToWait = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This assignment is obsolete as uxReturn will get set after
|
||||||
|
the task unblocks, but some compilers mistakenly generate a
|
||||||
|
warning about uxReturn being returned without being set if the
|
||||||
|
assignment is omitted. */
|
||||||
|
uxReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The rendezvous bits were not set, but no block time was
|
||||||
|
specified - just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Although the task got here because it timed out before the
|
||||||
|
bits it was waiting for were set, it is possible that since it
|
||||||
|
unblocked another task has set the bits. If this is the case
|
||||||
|
then it needs to clear the bits before exiting. */
|
||||||
|
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Control bits might be set as the task had blocked should not be
|
||||||
|
returned. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xTimeoutOccurred;
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn, uxControlBits = 0;
|
||||||
|
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
|
itself, and that at least one bit is being requested. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Check to see if the wait condition is already met or not. */
|
||||||
|
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
|
||||||
|
|
||||||
|
if( xWaitConditionMet != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The wait condition has already been met so there is no need to
|
||||||
|
block. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
xTicksToWait = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Clear the wait bits if requested to do so. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The wait condition has not been met, but no block time was
|
||||||
|
specified, so just return the current value. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task is going to block to wait for its required bits to be
|
||||||
|
set. uxControlBits are used to remember the specified behaviour of
|
||||||
|
this call to xEventGroupWaitBits() - for use when the event bits
|
||||||
|
unblock the task. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWaitForAllBits != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventWAIT_FOR_ALL_BITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This is obsolete as it will get set after the task unblocks, but
|
||||||
|
some compilers mistakenly generate a warning about the variable
|
||||||
|
being returned without being set if it is not done. */
|
||||||
|
uxReturn = 0;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* It is possible that the event bits were updated between this
|
||||||
|
task leaving the Blocked state and running again. */
|
||||||
|
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||||
|
{
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked so control bits may have been set. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xTimeoutOccurred;
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
|
/* The value returned is the event group value prior to the bits being
|
||||||
|
cleared. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Clear the bits. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||||
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
||||||
|
{
|
||||||
|
ListItem_t *pxListItem, *pxNext;
|
||||||
|
ListItem_t const *pxListEnd;
|
||||||
|
List_t *pxList;
|
||||||
|
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
pxListItem = listGET_HEAD_ENTRY( pxList );
|
||||||
|
|
||||||
|
/* Set the bits. */
|
||||||
|
pxEventBits->uxEventBits |= uxBitsToSet;
|
||||||
|
|
||||||
|
/* See if the new bit value should unblock any tasks. */
|
||||||
|
while( pxListItem != pxListEnd )
|
||||||
|
{
|
||||||
|
pxNext = listGET_NEXT( pxListItem );
|
||||||
|
uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
|
||||||
|
xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Split the bits waited for from the control bits. */
|
||||||
|
uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
|
||||||
|
if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Just looking for single bit being set. */
|
||||||
|
if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
|
||||||
|
{
|
||||||
|
/* All bits are set. */
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Need all bits to be set, but not all the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xMatchFound != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The bits match. Should the bits be cleared on exit? */
|
||||||
|
if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
uxBitsToClear |= uxBitsWaitedFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the actual event flag value in the task's event list
|
||||||
|
item before removing the task from the event list. The
|
||||||
|
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||||
|
that is was unblocked due to its required bits matching, rather
|
||||||
|
than because it timed out. */
|
||||||
|
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||||
|
used here as the list item may have been removed from the event list
|
||||||
|
and inserted into the ready/pending reading list. */
|
||||||
|
pxListItem = pxNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||||
|
bit was set in the control word. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
return pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||||
|
|
||||||
|
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Unblock the task, returning 0 as the event list is being deleted
|
||||||
|
and cannot therefore have any bits set. */
|
||||||
|
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||||
|
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||||
|
{
|
||||||
|
/* The event group can only have been allocated dynamically - free
|
||||||
|
it again. */
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
|
{
|
||||||
|
/* The event group could have been allocated statically or
|
||||||
|
dynamically, so check before attempting to free the memory. */
|
||||||
|
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||||
|
{
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For internal use only - execute a 'set bits' command that was pended from
|
||||||
|
an interrupt. */
|
||||||
|
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||||
|
{
|
||||||
|
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||||
|
an interrupt. */
|
||||||
|
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
||||||
|
{
|
||||||
|
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
||||||
|
{
|
||||||
|
BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
|
if( xWaitForAllBits == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||||
|
set. Is one already set? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||||
|
Are they set already? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xWaitConditionMet;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||||
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (configUSE_TRACE_FACILITY == 1)
|
||||||
|
|
||||||
|
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
||||||
|
{
|
||||||
|
UBaseType_t xReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
|
||||||
|
if( xEventGroup == NULL )
|
||||||
|
{
|
||||||
|
xReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pxEventBits->uxEventGroupNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
|
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
||||||
|
{
|
||||||
|
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
846
vendor/freertos/freertos/Source/include/FreeRTOS.h
vendored
846
vendor/freertos/freertos/Source/include/FreeRTOS.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1,71 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STACK_MACROS_H
|
#ifndef STACK_MACROS_H
|
||||||
#define STACK_MACROS_H
|
#define STACK_MACROS_H
|
||||||
|
|
||||||
|
#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */
|
||||||
|
#warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released.
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call the stack overflow hook function if the stack of the task being swapped
|
* 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
|
* out is currently overflowed, or looks like it might have overflowed in the
|
||||||
@ -82,49 +49,31 @@
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 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. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,20 +82,18 @@
|
|||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
\
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||||
\
|
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||||
\
|
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||||
/* Has the extremity of the task stack ever been written over? */ \
|
{ \
|
||||||
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
{ \
|
} \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
@ -154,27 +101,34 @@
|
|||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
|
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
static const uint8_t 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, \
|
||||||
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 ); \
|
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||||
\
|
\
|
||||||
/* Has the extremity of the task stack ever been written over? */ \
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Remove stack overflow macro if not being used. */
|
||||||
|
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* STACK_MACROS_H */
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
||||||
|
207
vendor/freertos/freertos/Source/include/croutine.h
vendored
207
vendor/freertos/freertos/Source/include/croutine.h
vendored
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CO_ROUTINE_H
|
#ifndef CO_ROUTINE_H
|
||||||
#define CO_ROUTINE_H
|
#define CO_ROUTINE_H
|
||||||
@ -79,28 +42,28 @@ extern "C" {
|
|||||||
/* Used to hide the implementation of the co-routine control block. The
|
/* 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
|
control block structure however has to be included in the header due to
|
||||||
the macro implementation of the co-routine functionality. */
|
the macro implementation of the co-routine functionality. */
|
||||||
typedef void * xCoRoutineHandle;
|
typedef void * CoRoutineHandle_t;
|
||||||
|
|
||||||
/* Defines the prototype to which co-routine functions must conform. */
|
/* Defines the prototype to which co-routine functions must conform. */
|
||||||
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
|
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
|
||||||
|
|
||||||
typedef struct corCoRoutineControlBlock
|
typedef struct corCoRoutineControlBlock
|
||||||
{
|
{
|
||||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||||
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
ListItem_t 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. */
|
ListItem_t 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. */
|
UBaseType_t 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. */
|
UBaseType_t 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. */
|
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
||||||
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
|
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
portBASE_TYPE xCoRoutineCreate(
|
BaseType_t xCoRoutineCreate(
|
||||||
crCOROUTINE_CODE pxCoRoutineCode,
|
crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
unsigned portBASE_TYPE uxPriority,
|
UBaseType_t uxPriority,
|
||||||
unsigned portBASE_TYPE uxIndex
|
UBaseType_t uxIndex
|
||||||
);</pre>
|
);</pre>
|
||||||
*
|
*
|
||||||
* Create a new co-routine and add it to the list of co-routines that are
|
* Create a new co-routine and add it to the list of co-routines that are
|
||||||
@ -123,12 +86,12 @@ typedef struct corCoRoutineControlBlock
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// 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.
|
// This may not be necessary for const variables.
|
||||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||||
static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
|
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -138,7 +101,7 @@ typedef struct corCoRoutineControlBlock
|
|||||||
// This co-routine just delays for a fixed period, then toggles
|
// This co-routine just delays for a fixed period, then toggles
|
||||||
// an LED. Two co-routines are created using this function, so
|
// an LED. Two co-routines are created using this function, so
|
||||||
// the uxIndex parameter is used to tell the co-routine which
|
// the uxIndex parameter is used to tell the co-routine which
|
||||||
// LED to flash and how long to delay. This assumes xQueue has
|
// LED to flash and how int32_t to delay. This assumes xQueue has
|
||||||
// already been created.
|
// already been created.
|
||||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||||
@ -151,9 +114,9 @@ typedef struct corCoRoutineControlBlock
|
|||||||
// Function that creates two co-routines.
|
// Function that creates two co-routines.
|
||||||
void vOtherFunction( void )
|
void vOtherFunction( void )
|
||||||
{
|
{
|
||||||
unsigned char ucParameterToPass;
|
uint8_t ucParameterToPass;
|
||||||
xTaskHandle xHandle;
|
TaskHandle_t xHandle;
|
||||||
|
|
||||||
// Create two co-routines at priority 0. The first is given index 0
|
// 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
|
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||||
@ -166,7 +129,7 @@ typedef struct corCoRoutineControlBlock
|
|||||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,17 +176,17 @@ void vCoRoutineSchedule( void );
|
|||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crSTART( xCoRoutineHandle xHandle );</pre>
|
crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||||
*
|
*
|
||||||
* This macro MUST always be called at the start of a co-routine function.
|
* This macro MUST always be called at the start of a co-routine function.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static long ulAVariable;
|
static int32_t ulAVariable;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -239,7 +202,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* \defgroup crSTART crSTART
|
* \defgroup crSTART crSTART
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:
|
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
@ -251,10 +214,10 @@ void vCoRoutineSchedule( void );
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static long ulAVariable;
|
static int32_t ulAVariable;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -276,13 +239,13 @@ void vCoRoutineSchedule( void );
|
|||||||
* These macros are intended for internal use by the co-routine implementation
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
* only. The macros should not be used directly by application writers.
|
* 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_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||||
#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
|
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||||
*
|
*
|
||||||
* Delay a co-routine for a fixed period of time.
|
* Delay a co-routine for a fixed period of time.
|
||||||
*
|
*
|
||||||
@ -295,18 +258,18 @@ void vCoRoutineSchedule( void );
|
|||||||
*
|
*
|
||||||
* @param xTickToDelay The number of ticks that the co-routine should delay
|
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||||
* for. The actual amount of time this equates to is defined by
|
* for. The actual amount of time this equates to is defined by
|
||||||
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
|
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS
|
||||||
* can be used to convert ticks to milliseconds.
|
* can be used to convert ticks to milliseconds.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// 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.
|
// This may not be necessary for const variables.
|
||||||
// We are to delay for 200ms.
|
// We are to delay for 200ms.
|
||||||
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
|
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -335,11 +298,11 @@ void vCoRoutineSchedule( void );
|
|||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND(
|
crQUEUE_SEND(
|
||||||
xCoRoutineHandle xHandle,
|
CoRoutineHandle_t xHandle,
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
void *pvItemToQueue,
|
||||||
portTickType xTicksToWait,
|
TickType_t xTicksToWait,
|
||||||
portBASE_TYPE *pxResult
|
BaseType_t *pxResult
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
@ -372,7 +335,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* to wait for space to become available on the queue, should space not be
|
* 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
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
|
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
|
||||||
* below).
|
* below).
|
||||||
*
|
*
|
||||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
@ -383,11 +346,11 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||||
// a queue.
|
// a queue.
|
||||||
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static portBASE_TYPE xNumberToPost = 0;
|
static BaseType_t xNumberToPost = 0;
|
||||||
static portBASE_TYPE xResult;
|
static BaseType_t xResult;
|
||||||
|
|
||||||
// Co-routines must begin with a call to crSTART().
|
// Co-routines must begin with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -434,11 +397,11 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_RECEIVE(
|
crQUEUE_RECEIVE(
|
||||||
xCoRoutineHandle xHandle,
|
CoRoutineHandle_t xHandle,
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
void *pvBuffer,
|
||||||
portTickType xTicksToWait,
|
TickType_t xTicksToWait,
|
||||||
portBASE_TYPE *pxResult
|
BaseType_t *pxResult
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
@ -470,7 +433,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* to wait for data to become available from the queue, should data not be
|
* 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
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
|
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
|
||||||
* crQUEUE_SEND example).
|
* crQUEUE_SEND example).
|
||||||
*
|
*
|
||||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
@ -481,11 +444,11 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// A co-routine receives the number of an LED to flash from a queue. It
|
// A co-routine receives the number of an LED to flash from a queue. It
|
||||||
// blocks on the queue until the number is received.
|
// blocks on the queue until the number is received.
|
||||||
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static portBASE_TYPE xResult;
|
static BaseType_t xResult;
|
||||||
static unsigned portBASE_TYPE uxLEDToFlash;
|
static UBaseType_t uxLEDToFlash;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -526,9 +489,9 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
crQUEUE_SEND_FROM_ISR(
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
void *pvItemToQueue,
|
||||||
portBASE_TYPE xCoRoutinePreviouslyWoken
|
BaseType_t xCoRoutinePreviouslyWoken
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
@ -566,10 +529,10 @@ void vCoRoutineSchedule( void );
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||||
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
char cRxedChar;
|
char cRxedChar;
|
||||||
portBASE_TYPE xResult;
|
BaseType_t xResult;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -596,7 +559,7 @@ void vCoRoutineSchedule( void );
|
|||||||
void vUART_ISR( void )
|
void vUART_ISR( void )
|
||||||
{
|
{
|
||||||
char cRxedChar;
|
char cRxedChar;
|
||||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
// We loop around reading characters until there are none left in the UART.
|
// We loop around reading characters until there are none left in the UART.
|
||||||
while( UART_RX_REG_NOT_EMPTY() )
|
while( UART_RX_REG_NOT_EMPTY() )
|
||||||
@ -623,9 +586,9 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
crQUEUE_SEND_FROM_ISR(
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
void *pvBuffer,
|
||||||
portBASE_TYPE * pxCoRoutineWoken
|
BaseType_t * pxCoRoutineWoken
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
@ -664,12 +627,12 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||||
// period. The character is incremented each time.
|
// period. The character is incremented each time.
|
||||||
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// cChar holds its value while this co-routine is blocked and must therefore
|
// cChar holds its value while this co-routine is blocked and must therefore
|
||||||
// be declared static.
|
// be declared static.
|
||||||
static char cCharToTx = 'a';
|
static char cCharToTx = 'a';
|
||||||
portBASE_TYPE xResult;
|
BaseType_t xResult;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -712,7 +675,7 @@ void vCoRoutineSchedule( void );
|
|||||||
void vUART_ISR( void )
|
void vUART_ISR( void )
|
||||||
{
|
{
|
||||||
char cCharToTx;
|
char cCharToTx;
|
||||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
while( UART_TX_REG_EMPTY() )
|
while( UART_TX_REG_EMPTY() )
|
||||||
{
|
{
|
||||||
@ -740,7 +703,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* Removes the current co-routine from its ready list and places it in the
|
* Removes the current co-routine from its ready list and places it in the
|
||||||
* appropriate delayed list.
|
* appropriate delayed list.
|
||||||
*/
|
*/
|
||||||
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended for internal use by the queue implementation only.
|
* This function is intended for internal use by the queue implementation only.
|
||||||
@ -749,7 +712,7 @@ void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList
|
|||||||
* Removes the highest priority co-routine from the event list and places it in
|
* Removes the highest priority co-routine from the event list and places it in
|
||||||
* the pending ready list.
|
* the pending ready list.
|
||||||
*/
|
*/
|
||||||
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
280
vendor/freertos/freertos/Source/include/deprecated_definitions.h
vendored
Normal file
280
vendor/freertos/freertos/Source/include/deprecated_definitions.h
vendored
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DEPRECATED_DEFINITIONS_H
|
||||||
|
#define DEPRECATED_DEFINITIONS_H
|
||||||
|
|
||||||
|
|
||||||
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
|
pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
|
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
|
of setting the compiler's include path such that it found the correct
|
||||||
|
portmacro.h file - removing the need for the constant and allowing the
|
||||||
|
portmacro.h file to be located anywhere in relation to the port being used. The
|
||||||
|
definitions below remain in the code for backward compatibility only. New
|
||||||
|
projects should not use them. */
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||||
|
|
757
vendor/freertos/freertos/Source/include/event_groups.h
vendored
Normal file
757
vendor/freertos/freertos/Source/include/event_groups.h
vendored
Normal file
@ -0,0 +1,757 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENT_GROUPS_H
|
||||||
|
#define EVENT_GROUPS_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event group is a collection of bits to which an application can assign a
|
||||||
|
* meaning. For example, an application may create an event group to convey
|
||||||
|
* the status of various CAN bus related events in which bit 0 might mean "A CAN
|
||||||
|
* message has been received and is ready for processing", bit 1 might mean "The
|
||||||
|
* application has queued a message that is ready for sending onto the CAN
|
||||||
|
* network", and bit 2 might mean "It is time to send a SYNC message onto the
|
||||||
|
* CAN network" etc. A task can then test the bit values to see which events
|
||||||
|
* are active, and optionally enter the Blocked state to wait for a specified
|
||||||
|
* bit or a group of specified bits to be active. To continue the CAN bus
|
||||||
|
* example, a CAN controlling task can enter the Blocked state (and therefore
|
||||||
|
* not consume any processing time) until either bit 0, bit 1 or bit 2 are
|
||||||
|
* active, at which time the bit that was actually active would inform the task
|
||||||
|
* which action it had to take (process a received message, send a message, or
|
||||||
|
* send a SYNC).
|
||||||
|
*
|
||||||
|
* The event groups implementation contains intelligence to avoid race
|
||||||
|
* conditions that would otherwise occur were an application to use a simple
|
||||||
|
* variable for the same purpose. This is particularly important with respect
|
||||||
|
* to when a bit within an event group is to be cleared, and when bits have to
|
||||||
|
* be set and then tested atomically - as is the case where event groups are
|
||||||
|
* used to create a synchronisation point between multiple tasks (a
|
||||||
|
* 'rendezvous').
|
||||||
|
*
|
||||||
|
* \defgroup EventGroup
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*
|
||||||
|
* Type by which event groups are referenced. For example, a call to
|
||||||
|
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
|
||||||
|
* be used as a parameter to other event group functions.
|
||||||
|
*
|
||||||
|
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
typedef void * EventGroupHandle_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type that holds event bits always matches TickType_t - therefore the
|
||||||
|
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
|
||||||
|
* 32 bits if set to 0.
|
||||||
|
*
|
||||||
|
* \defgroup EventBits_t EventBits_t
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
typedef TickType_t EventBits_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Create a new event group.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||||
|
* block of memory, in which the event group's structure is stored. If an event
|
||||||
|
* groups is created using xEventGropuCreate() then the required memory is
|
||||||
|
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||||
|
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||||
|
* using xEventGropuCreateStatic() then the application writer must instead
|
||||||
|
* provide the memory that will get used by the event group.
|
||||||
|
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||||
|
* without using any dynamic memory allocation.
|
||||||
|
*
|
||||||
|
* Although event groups are not related to ticks, for internal implementation
|
||||||
|
* reasons the number of bits available for use in an event group is dependent
|
||||||
|
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||||
|
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||||
|
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||||
|
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||||
|
* event bits within an event group.
|
||||||
|
*
|
||||||
|
* @return If the event group was created then a handle to the event group is
|
||||||
|
* returned. If there was insufficient FreeRTOS heap available to create the
|
||||||
|
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Declare a variable to hold the created event group.
|
||||||
|
EventGroupHandle_t xCreatedEventGroup;
|
||||||
|
|
||||||
|
// Attempt to create the event group.
|
||||||
|
xCreatedEventGroup = xEventGroupCreate();
|
||||||
|
|
||||||
|
// Was the event group created successfully?
|
||||||
|
if( xCreatedEventGroup == NULL )
|
||||||
|
{
|
||||||
|
// The event group was not created because there was insufficient
|
||||||
|
// FreeRTOS heap available.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The event group was created.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Create a new event group.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||||
|
* block of memory, in which the event group's structure is stored. If an event
|
||||||
|
* groups is created using xEventGropuCreate() then the required memory is
|
||||||
|
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||||
|
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||||
|
* using xEventGropuCreateStatic() then the application writer must instead
|
||||||
|
* provide the memory that will get used by the event group.
|
||||||
|
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||||
|
* without using any dynamic memory allocation.
|
||||||
|
*
|
||||||
|
* Although event groups are not related to ticks, for internal implementation
|
||||||
|
* reasons the number of bits available for use in an event group is dependent
|
||||||
|
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||||
|
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||||
|
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||||
|
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||||
|
* event bits within an event group.
|
||||||
|
*
|
||||||
|
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
|
||||||
|
* StaticEventGroup_t, which will be then be used to hold the event group's data
|
||||||
|
* structures, removing the need for the memory to be allocated dynamically.
|
||||||
|
*
|
||||||
|
* @return If the event group was created then a handle to the event group is
|
||||||
|
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// StaticEventGroup_t is a publicly accessible structure that has the same
|
||||||
|
// size and alignment requirements as the real event group structure. It is
|
||||||
|
// provided as a mechanism for applications to know the size of the event
|
||||||
|
// group (which is dependent on the architecture and configuration file
|
||||||
|
// settings) without breaking the strict data hiding policy by exposing the
|
||||||
|
// real event group internals. This StaticEventGroup_t variable is passed
|
||||||
|
// into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
||||||
|
// the event group's data structures
|
||||||
|
StaticEventGroup_t xEventGroupBuffer;
|
||||||
|
|
||||||
|
// Create the event group without dynamically allocating any memory.
|
||||||
|
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||||
|
</pre>
|
||||||
|
*/
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xClearOnExit,
|
||||||
|
const BaseType_t xWaitForAllBits,
|
||||||
|
const TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* [Potentially] block to wait for one or more bits to be set within a
|
||||||
|
* previously created event group.
|
||||||
|
*
|
||||||
|
* This function cannot be called from an interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are being tested. The
|
||||||
|
* event group must have previously been created using a call to
|
||||||
|
* xEventGroupCreate().
|
||||||
|
*
|
||||||
|
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group. For example, to wait for bit 0 and/or bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x07. Etc.
|
||||||
|
*
|
||||||
|
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
|
||||||
|
* uxBitsToWaitFor that are set within the event group will be cleared before
|
||||||
|
* xEventGroupWaitBits() returns if the wait condition was met (if the function
|
||||||
|
* returns for a reason other than a timeout). If xClearOnExit is set to
|
||||||
|
* pdFALSE then the bits set in the event group are not altered when the call to
|
||||||
|
* xEventGroupWaitBits() returns.
|
||||||
|
*
|
||||||
|
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
|
||||||
|
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
|
||||||
|
* are set or the specified block time expires. If xWaitForAllBits is set to
|
||||||
|
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
|
||||||
|
* in uxBitsToWaitFor is set or the specified block time expires. The block
|
||||||
|
* time is specified by the xTicksToWait parameter.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||||
|
* for one/all (depending on the xWaitForAllBits value) of the bits specified by
|
||||||
|
* uxBitsToWaitFor to become set.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time either the bits being waited
|
||||||
|
* for became set, or the block time expired. Test the return value to know
|
||||||
|
* which bits were set. If xEventGroupWaitBits() returned because its timeout
|
||||||
|
* expired then not all the bits being waited for will be set. If
|
||||||
|
* xEventGroupWaitBits() returned because the bits it was waiting for were set
|
||||||
|
* then the returned value is the event group value before any bits were
|
||||||
|
* automatically cleared in the case that xClearOnExit parameter was set to
|
||||||
|
* pdTRUE.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||||
|
// the event group. Clear the bits before exiting.
|
||||||
|
uxBits = xEventGroupWaitBits(
|
||||||
|
xEventGroup, // The event group being tested.
|
||||||
|
BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||||
|
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||||
|
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||||
|
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because both bits were set.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||||
|
// without either BIT_0 or BIT_4 becoming set.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Clear bits within an event group. This function cannot be called from an
|
||||||
|
* interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||||
|
*
|
||||||
|
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
|
||||||
|
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to
|
||||||
|
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
|
||||||
|
*
|
||||||
|
* @return The value of the event group before the specified bits were cleared.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
|
||||||
|
// Clear bit 0 and bit 4 in xEventGroup.
|
||||||
|
uxBits = xEventGroupClearBits(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 );// The bits being cleared.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||||
|
// called. Both will now be clear (not set).
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||||
|
// now be clear.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||||
|
// now be clear.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Neither bit 0 nor bit 4 were set in the first place.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group is not a deterministic operation because there
|
||||||
|
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||||
|
* set. FreeRTOS does not allow nondeterministic operations to be performed
|
||||||
|
* while interrupts are disabled, so protects event groups that are accessed
|
||||||
|
* from tasks by suspending the scheduler rather than disabling interrupts. As
|
||||||
|
* a result event groups cannot be accessed directly from an interrupt service
|
||||||
|
* routine. Therefore xEventGroupClearBitsFromISR() sends a message to the
|
||||||
|
* timer task to have the clear operation performed in the context of the timer
|
||||||
|
* task.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||||
|
*
|
||||||
|
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
|
||||||
|
* For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3
|
||||||
|
* and bit 0 set uxBitsToClear to 0x09.
|
||||||
|
*
|
||||||
|
* @return If the request to execute the function was posted successfully then
|
||||||
|
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||||
|
* if the timer service queue was full.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
// An event group which it is assumed has already been created by a call to
|
||||||
|
// xEventGroupCreate().
|
||||||
|
EventGroupHandle_t xEventGroup;
|
||||||
|
|
||||||
|
void anInterruptHandler( void )
|
||||||
|
{
|
||||||
|
// Clear bit 0 and bit 4 in xEventGroup.
|
||||||
|
xResult = xEventGroupClearBitsFromISR(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 ); // The bits being set.
|
||||||
|
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// The message was posted successfully.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Set bits within an event group.
|
||||||
|
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||||
|
* is a version that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group will automatically unblock tasks that are
|
||||||
|
* blocked waiting for the bits.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||||
|
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||||
|
* and bit 0 set uxBitsToSet to 0x09.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time the call to
|
||||||
|
* xEventGroupSetBits() returns. There are two reasons why the returned value
|
||||||
|
* might have the bits specified by the uxBitsToSet parameter cleared. First,
|
||||||
|
* if setting a bit results in a task that was waiting for the bit leaving the
|
||||||
|
* blocked state then it is possible the bit will be cleared automatically
|
||||||
|
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
|
||||||
|
* unblocked (or otherwise Ready state) task that has a priority above that of
|
||||||
|
* the task that called xEventGroupSetBits() will execute and may change the
|
||||||
|
* event group value before the call to xEventGroupSetBits() returns.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
|
||||||
|
// Set bit 0 and bit 4 in xEventGroup.
|
||||||
|
uxBits = xEventGroupSetBits(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 );// The bits being set.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// Both bit 0 and bit 4 remained set when the function returned.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 0 remained set when the function returned, but bit 4 was
|
||||||
|
// cleared. It might be that bit 4 was cleared automatically as a
|
||||||
|
// task that was waiting for bit 4 was removed from the Blocked
|
||||||
|
// state.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 4 remained set when the function returned, but bit 0 was
|
||||||
|
// cleared. It might be that bit 0 was cleared automatically as a
|
||||||
|
// task that was waiting for bit 0 was removed from the Blocked
|
||||||
|
// state.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||||
|
// was waiting for both of the bits to be set, and the bits were
|
||||||
|
// cleared as the task left the Blocked state.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group is not a deterministic operation because there
|
||||||
|
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||||
|
* set. FreeRTOS does not allow nondeterministic operations to be performed in
|
||||||
|
* interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
|
||||||
|
* sends a message to the timer task to have the set operation performed in the
|
||||||
|
* context of the timer task - where a scheduler lock is used in place of a
|
||||||
|
* critical section.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||||
|
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||||
|
* and bit 0 set uxBitsToSet to 0x09.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||||
|
* will result in a message being sent to the timer daemon task. If the
|
||||||
|
* priority of the timer daemon task is higher than the priority of the
|
||||||
|
* currently running task (the task the interrupt interrupted) then
|
||||||
|
* *pxHigherPriorityTaskWoken will be set to pdTRUE by
|
||||||
|
* xEventGroupSetBitsFromISR(), indicating that a context switch should be
|
||||||
|
* requested before the interrupt exits. For that reason
|
||||||
|
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||||
|
* example code below.
|
||||||
|
*
|
||||||
|
* @return If the request to execute the function was posted successfully then
|
||||||
|
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||||
|
* if the timer service queue was full.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
// An event group which it is assumed has already been created by a call to
|
||||||
|
// xEventGroupCreate().
|
||||||
|
EventGroupHandle_t xEventGroup;
|
||||||
|
|
||||||
|
void anInterruptHandler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||||
|
|
||||||
|
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||||
|
xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
|
// Set bit 0 and bit 4 in xEventGroup.
|
||||||
|
xResult = xEventGroupSetBitsFromISR(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 // The bits being set.
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
// Was the message posted successfully?
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
// switch should be requested. The macro used is port specific and
|
||||||
|
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
|
// refer to the documentation page for the port being used.
|
||||||
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Atomically set bits within an event group, then wait for a combination of
|
||||||
|
* bits to be set within the same event group. This functionality is typically
|
||||||
|
* used to synchronise multiple tasks, where each task has to wait for the other
|
||||||
|
* tasks to reach a synchronisation point before proceeding.
|
||||||
|
*
|
||||||
|
* This function cannot be used from an interrupt.
|
||||||
|
*
|
||||||
|
* The function will return before its block time expires if the bits specified
|
||||||
|
* by the uxBitsToWait parameter are set, or become set within that time. In
|
||||||
|
* this case all the bits specified by uxBitsToWait will be automatically
|
||||||
|
* cleared before the function returns.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are being tested. The
|
||||||
|
* event group must have previously been created using a call to
|
||||||
|
* xEventGroupCreate().
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet The bits to set in the event group before determining
|
||||||
|
* if, and possibly waiting for, all the bits specified by the uxBitsToWait
|
||||||
|
* parameter are set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group. For example, to wait for bit 0 and bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x07. Etc.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||||
|
* for all of the bits specified by uxBitsToWaitFor to become set.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time either the bits being waited
|
||||||
|
* for became set, or the block time expired. Test the return value to know
|
||||||
|
* which bits were set. If xEventGroupSync() returned because its timeout
|
||||||
|
* expired then not all the bits being waited for will be set. If
|
||||||
|
* xEventGroupSync() returned because all the bits it was waiting for were
|
||||||
|
* set then the returned value is the event group value before any bits were
|
||||||
|
* automatically cleared.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Bits used by the three tasks.
|
||||||
|
#define TASK_0_BIT ( 1 << 0 )
|
||||||
|
#define TASK_1_BIT ( 1 << 1 )
|
||||||
|
#define TASK_2_BIT ( 1 << 2 )
|
||||||
|
|
||||||
|
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||||
|
|
||||||
|
// Use an event group to synchronise three tasks. It is assumed this event
|
||||||
|
// group has already been created elsewhere.
|
||||||
|
EventGroupHandle_t xEventBits;
|
||||||
|
|
||||||
|
void vTask0( void *pvParameters )
|
||||||
|
{
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 0 in the event flag to note this task has reached the
|
||||||
|
// sync point. The other two tasks will set the other two bits defined
|
||||||
|
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||||
|
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||||
|
// for this to happen.
|
||||||
|
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||||
|
|
||||||
|
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||||
|
{
|
||||||
|
// All three tasks reached the synchronisation point before the call
|
||||||
|
// to xEventGroupSync() timed out.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTask1( void *pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 1 in the event flag to note this task has reached the
|
||||||
|
// synchronisation point. The other two tasks will set the other two
|
||||||
|
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
|
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
|
// indefinitely for this to happen.
|
||||||
|
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
|
||||||
|
// xEventGroupSync() was called with an indefinite block time, so
|
||||||
|
// this task will only reach here if the syncrhonisation was made by all
|
||||||
|
// three tasks, so there is no need to test the return value.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTask2( void *pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 2 in the event flag to note this task has reached the
|
||||||
|
// synchronisation point. The other two tasks will set the other two
|
||||||
|
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
|
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
|
// indefinitely for this to happen.
|
||||||
|
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
|
||||||
|
// xEventGroupSync() was called with an indefinite block time, so
|
||||||
|
// this task will only reach here if the syncrhonisation was made by all
|
||||||
|
// three tasks, so there is no need to test the return value.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSync xEventGroupSync
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Returns the current value of the bits in an event group. This function
|
||||||
|
* cannot be used from an interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being queried.
|
||||||
|
*
|
||||||
|
* @return The event group bits at the time xEventGroupGetBits() was called.
|
||||||
|
*
|
||||||
|
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being queried.
|
||||||
|
*
|
||||||
|
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
|
||||||
|
*
|
||||||
|
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Delete an event group that was previously created by a call to
|
||||||
|
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||||
|
* unblocked and obtain 0 as the event group's value.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being deleted.
|
||||||
|
*/
|
||||||
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* For internal use only. */
|
||||||
|
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
|
#if (configUSE_TRACE_FACILITY == 1)
|
||||||
|
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EVENT_GROUPS_H */
|
||||||
|
|
||||||
|
|
237
vendor/freertos/freertos/Source/include/list.h
vendored
237
vendor/freertos/freertos/Source/include/list.h
vendored
@ -1,74 +1,37 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the list implementation used by the scheduler. While it is tailored
|
* 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
|
* heavily for the schedulers needs, it is also available for use by
|
||||||
* application code.
|
* application code.
|
||||||
*
|
*
|
||||||
* xLists can only store pointers to xListItems. Each xListItem contains a
|
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
* descending item value order.
|
* descending item value order.
|
||||||
*
|
*
|
||||||
@ -91,6 +54,9 @@
|
|||||||
* \ingroup FreeRTOSIntro
|
* \ingroup FreeRTOSIntro
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error FreeRTOS.h must be included before list.h
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
@ -115,8 +81,8 @@
|
|||||||
* complete and obvious failure of the scheduler. If this is ever experienced
|
* complete and obvious failure of the scheduler. If this is ever experienced
|
||||||
* then the volatile qualifier can be inserted in the relevant places within the
|
* then the volatile qualifier can be inserted in the relevant places within the
|
||||||
* list structures by simply defining configLIST_VOLATILE to volatile in
|
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||||
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||||
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||||
* will simply #define configLIST_VOLATILE away completely.
|
* will simply #define configLIST_VOLATILE away completely.
|
||||||
*
|
*
|
||||||
* To use volatile list structure members then add the following line to
|
* To use volatile list structure members then add the following line to
|
||||||
@ -130,36 +96,79 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Macros that can be used to place known values within the list structures,
|
||||||
|
then check that the known values do not get corrupted during the execution of
|
||||||
|
the application. These may catch the list data structures being overwritten in
|
||||||
|
memory. They will not catch data errors caused by incorrect configuration or
|
||||||
|
use of FreeRTOS.*/
|
||||||
|
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||||
|
/* Define the macros to do nothing. */
|
||||||
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
|
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE
|
||||||
|
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE
|
||||||
|
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||||
|
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||||
|
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
|
||||||
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||||
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||||
|
#define listTEST_LIST_INTEGRITY( pxList )
|
||||||
|
#else
|
||||||
|
/* Define macros that add new members into the list structures. */
|
||||||
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||||
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||||
|
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||||
|
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||||
|
|
||||||
|
/* Define macros that set the new structure members to known values. */
|
||||||
|
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
|
||||||
|
/* Define macros that will assert if one of the structure members does not
|
||||||
|
contain its expected value. */
|
||||||
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
|
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
|
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the only type of object that a list can contain.
|
* Definition of the only type of object that a list can contain.
|
||||||
*/
|
*/
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
configLIST_VOLATILE portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next xListItem in the list. */
|
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t 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. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||||
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
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 * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
|
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
struct xMINI_LIST_ITEM
|
||||||
{
|
{
|
||||||
configLIST_VOLATILE portTickType xItemValue;
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
|
configLIST_VOLATILE TickType_t xItemValue;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
};
|
};
|
||||||
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the type of queue used by the scheduler.
|
* Definition of the type of queue used by the scheduler.
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
configLIST_VOLATILE unsigned portBASE_TYPE uxNumberOfItems;
|
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
xListItem * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
volatile UBaseType_t uxNumberOfItems;
|
||||||
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. */
|
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||||
} xList;
|
MiniListItem_t 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. */
|
||||||
|
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
|
} List_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the owner of a list item. The owner of a list item
|
* Access macro to set the owner of a list item. The owner of a list item
|
||||||
@ -177,7 +186,7 @@ typedef struct xLIST
|
|||||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( pxListItem )->pvOwner
|
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the value of the list item. In most cases the value is
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
@ -186,26 +195,50 @@ typedef struct xLIST
|
|||||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to retrieve the value of the list item. The value can
|
* 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
|
* represent anything - for example the priority of a task, or the time at
|
||||||
* which a task should be unblocked.
|
* which a task should be unblocked.
|
||||||
*
|
*
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro the retrieve the value of the list item at the head of a given
|
* Access macro to retrieve the value of the list item at the head of a given
|
||||||
* list.
|
* list.
|
||||||
*
|
*
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )
|
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item at the head of the list.
|
||||||
|
*
|
||||||
|
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item at the head of the list.
|
||||||
|
*
|
||||||
|
* \page listGET_NEXT listGET_NEXT
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item that marks the end of the list
|
||||||
|
*
|
||||||
|
* \page listGET_END_MARKER listGET_END_MARKER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to determine if a list contains any items. The macro will
|
* Access macro to determine if a list contains any items. The macro will
|
||||||
@ -214,19 +247,19 @@ typedef struct xLIST
|
|||||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listLIST_IS_EMPTY( pxList ) ( ( portBASE_TYPE ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) )
|
#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to return the number of items in the list.
|
* Access macro to return the number of items in the list.
|
||||||
*/
|
*/
|
||||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access function to obtain the owner of the next entry in a list.
|
* 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
|
* 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
|
* 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
|
* and returns that entry's pxOwner parameter. Using multiple calls to this
|
||||||
* function it is therefore possible to move through every item contained in
|
* function it is therefore possible to move through every item contained in
|
||||||
* a list.
|
* a list.
|
||||||
*
|
*
|
||||||
@ -235,6 +268,7 @@ typedef struct xLIST
|
|||||||
* The pxOwner parameter effectively creates a two way link between the list
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
* item and its owner.
|
* item and its owner.
|
||||||
*
|
*
|
||||||
|
* @param pxTCB pxTCB is set to the address of the owner of the next list item.
|
||||||
* @param pxList The list from which the next item owner is to be returned.
|
* @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
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
@ -242,7 +276,7 @@ typedef struct xLIST
|
|||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
{ \
|
{ \
|
||||||
xList * const pxConstList = ( pxList ); \
|
List_t * const pxConstList = ( pxList ); \
|
||||||
/* Increment the index to the next item and return the item, ensuring */ \
|
/* 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. */ \
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
@ -279,16 +313,15 @@ xList * const pxConstList = ( pxList ); \
|
|||||||
*
|
*
|
||||||
* @param pxList The list we want to know if the list item is within.
|
* @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.
|
* @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.
|
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||||
* pointer against
|
|
||||||
*/
|
*/
|
||||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( portBASE_TYPE ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list a list item is contained within (referenced from).
|
* Return the list a list item is contained within (referenced from).
|
||||||
*
|
*
|
||||||
* @param pxListItem The list item being queried.
|
* @param pxListItem The list item being queried.
|
||||||
* @return A pointer to the xList object that references the pxListItem
|
* @return A pointer to the List_t object that references the pxListItem
|
||||||
*/
|
*/
|
||||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
||||||
|
|
||||||
@ -309,7 +342,7 @@ xList * const pxConstList = ( pxList ); \
|
|||||||
* \page vListInitialise vListInitialise
|
* \page vListInitialise vListInitialise
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialise( xList * const pxList );
|
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list item is used. This sets the list container to
|
* Must be called before a list item is used. This sets the list container to
|
||||||
@ -320,7 +353,7 @@ void vListInitialise( xList * const pxList );
|
|||||||
* \page vListInitialiseItem vListInitialiseItem
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialiseItem( xListItem * const pxItem );
|
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
@ -328,24 +361,24 @@ void vListInitialiseItem( xListItem * const pxItem );
|
|||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @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.
|
* @param pxNewListItem The item that is to be placed in the list.
|
||||||
*
|
*
|
||||||
* \page vListInsert vListInsert
|
* \page vListInsert vListInsert
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsert( xList * const pxList, xListItem * const pxNewListItem );
|
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted in a position
|
* 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
|
* such that it will be the last item within the list returned by multiple
|
||||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||||
*
|
*
|
||||||
* The list member pvIndex is used to walk through a list. Calling
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
* 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
|
* in the list position pointed to by pxIndex. This means that every other
|
||||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||||
* the pvIndex parameter again points to the item being inserted.
|
* the pxIndex parameter again points to the item being inserted.
|
||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @param pxList The list into which the item is to be inserted.
|
||||||
*
|
*
|
||||||
@ -354,7 +387,7 @@ void vListInsert( xList * const pxList, xListItem * const pxNewListItem );
|
|||||||
* \page vListInsertEnd vListInsertEnd
|
* \page vListInsertEnd vListInsertEnd
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem );
|
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove an item from a list. The list item has a pointer to the list that
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
@ -369,7 +402,7 @@ void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem );
|
|||||||
* \page uxListRemove uxListRemove
|
* \page uxListRemove uxListRemove
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove );
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
780
vendor/freertos/freertos/Source/include/message_buffer.h
vendored
Normal file
780
vendor/freertos/freertos/Source/include/message_buffer.h
vendored
Normal file
@ -0,0 +1,780 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Message buffers build functionality on top of FreeRTOS stream buffers.
|
||||||
|
* Whereas stream buffers are used to send a continuous stream of data from one
|
||||||
|
* task or interrupt to another, message buffers are used to send variable
|
||||||
|
* length discrete messages from one task or interrupt to another. Their
|
||||||
|
* implementation is light weight, making them particularly suited for interrupt
|
||||||
|
* to task and core to core communication scenarios.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* timeout to 0.
|
||||||
|
*
|
||||||
|
* Message buffers hold variable length messages. To enable that, when a
|
||||||
|
* message is written to the message buffer an additional sizeof( size_t ) bytes
|
||||||
|
* are also written to store the message's length (that happens internally, with
|
||||||
|
* the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so writing a 10 byte message to a message buffer on a 32-bit
|
||||||
|
* architecture will actually reduce the available space in the message buffer
|
||||||
|
* by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
|
||||||
|
* of the message).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||||
|
#define FREERTOS_MESSAGE_BUFFER_H
|
||||||
|
|
||||||
|
/* Message buffers are built onto of stream buffers. */
|
||||||
|
#include "stream_buffer.h"
|
||||||
|
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type by which message buffers are referenced. For example, a call to
|
||||||
|
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
|
||||||
|
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||||
|
* etc.
|
||||||
|
*/
|
||||||
|
typedef void * MessageBufferHandle_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Creates a new message buffer using dynamically allocated memory. See
|
||||||
|
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||||
|
* memory (memory that is allocated at compile time).
|
||||||
|
*
|
||||||
|
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||||
|
* FreeRTOSConfig.h for xMessageBufferCreate() to be available.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The total number of bytes (not messages) the message
|
||||||
|
* buffer will be able to hold at any one time. When a message is written to
|
||||||
|
* the message buffer an additional sizeof( size_t ) bytes are also written to
|
||||||
|
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||||
|
* take up 14 bytes of message buffer space.
|
||||||
|
*
|
||||||
|
* @return If NULL is returned, then the message buffer cannot be created
|
||||||
|
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||||
|
* the message buffer data structures and storage area. A non-NULL value being
|
||||||
|
* returned indicates that the message buffer has been created successfully -
|
||||||
|
* the returned value should be stored as the handle to the created message
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
void vAFunction( void )
|
||||||
|
{
|
||||||
|
MessageBufferHandle_t xMessageBuffer;
|
||||||
|
const size_t xMessageBufferSizeBytes = 100;
|
||||||
|
|
||||||
|
// Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||||
|
// both the message buffer structure and the messages themselves is allocated
|
||||||
|
// dynamically. Each message added to the buffer consumes an additional 4
|
||||||
|
// bytes which are used to hold the lengh of the message.
|
||||||
|
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||||
|
|
||||||
|
if( xMessageBuffer == NULL )
|
||||||
|
{
|
||||||
|
// There was not enough heap memory space available to create the
|
||||||
|
// message buffer.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The message buffer was created successfully and can now be used.
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
uint8_t *pucMessageBufferStorageArea,
|
||||||
|
StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||||
|
</pre>
|
||||||
|
* Creates a new message buffer using statically allocated memory. See
|
||||||
|
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||||
|
* pucMessageBufferStorageArea parameter. When a message is written to the
|
||||||
|
* message buffer an additional sizeof( size_t ) bytes are also written to store
|
||||||
|
* the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so on most 32-bit architecture a 10 byte message will take up
|
||||||
|
* 14 bytes of message buffer space. The maximum number of bytes that can be
|
||||||
|
* stored in the message buffer is actually (xBufferSizeBytes - 1).
|
||||||
|
*
|
||||||
|
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
|
||||||
|
* least xBufferSizeBytes + 1 big. This is the array to which messages are
|
||||||
|
* copied when they are written to the message buffer.
|
||||||
|
*
|
||||||
|
* @param pxStaticMessageBuffer Must point to a variable of type
|
||||||
|
* StaticMessageBuffer_t, which will be used to hold the message buffer's data
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* @return If the message buffer is created successfully then a handle to the
|
||||||
|
* created message buffer is returned. If either pucMessageBufferStorageArea or
|
||||||
|
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
// Used to dimension the array used to hold the messages. The available space
|
||||||
|
// will actually be one less than this, so 999.
|
||||||
|
#define STORAGE_SIZE_BYTES 1000
|
||||||
|
|
||||||
|
// Defines the memory that will actually hold the messages within the message
|
||||||
|
// buffer.
|
||||||
|
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||||
|
|
||||||
|
// The variable used to hold the message buffer structure.
|
||||||
|
StaticMessageBuffer_t xMessageBufferStruct;
|
||||||
|
|
||||||
|
void MyFunction( void )
|
||||||
|
{
|
||||||
|
MessageBufferHandle_t xMessageBuffer;
|
||||||
|
|
||||||
|
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||||
|
ucBufferStorage,
|
||||||
|
&xMessageBufferStruct );
|
||||||
|
|
||||||
|
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||||
|
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||||
|
// reference the created message buffer in other message buffer API calls.
|
||||||
|
|
||||||
|
// Other code that uses the message buffer can go here.
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
<pre>
|
||||||
|
*
|
||||||
|
* Sends a discrete message to the message buffer. The message can be any
|
||||||
|
* length that fits within the buffer's free space, and is copied into the
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||||
|
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the message that is to be copied into the
|
||||||
|
* message buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||||
|
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||||
|
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||||
|
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||||
|
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||||
|
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||||
|
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the calling task should remain
|
||||||
|
* in the Blocked state to wait for enough space to become available in the
|
||||||
|
* message buffer, should the message buffer have insufficient space when
|
||||||
|
* xMessageBufferSend() is called. The calling task will never block if
|
||||||
|
* xTicksToWait is zero. The block time is specified in tick periods, so the
|
||||||
|
* absolute time it represents is dependent on the tick frequency. The macro
|
||||||
|
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
|
||||||
|
* a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause
|
||||||
|
* the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
*
|
||||||
|
* @return The number of bytes written to the message buffer. If the call to
|
||||||
|
* xMessageBufferSend() times out before there was enough space to write the
|
||||||
|
* message into the message buffer then zero is returned. If the call did not
|
||||||
|
* time out then xDataLengthBytes is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||||
|
{
|
||||||
|
size_t xBytesSent;
|
||||||
|
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||||
|
char *pcStringToSend = "String to send";
|
||||||
|
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||||
|
|
||||||
|
// Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||||
|
// wait for enough space to be available in the message buffer.
|
||||||
|
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||||
|
|
||||||
|
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||||
|
{
|
||||||
|
// The call to xMessageBufferSend() times out before there was enough
|
||||||
|
// space in the buffer for the data to be written.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the string to the message buffer. Return immediately if there is
|
||||||
|
// not enough space in the buffer.
|
||||||
|
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||||
|
|
||||||
|
if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
{
|
||||||
|
// The string could not be added to the message buffer because there was
|
||||||
|
// not enough free space in the buffer.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
<pre>
|
||||||
|
*
|
||||||
|
* Interrupt safe version of the API function that sends a discrete message to
|
||||||
|
* the message buffer. The message can be any length that fits within the
|
||||||
|
* buffer's free space, and is copied into the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||||
|
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the message that is to be copied into the
|
||||||
|
* message buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||||
|
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||||
|
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||||
|
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||||
|
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||||
|
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||||
|
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for data. Calling
|
||||||
|
* xMessageBufferSendFromISR() can make data available, and so cause a task that
|
||||||
|
* was waiting for data to leave the Blocked state. If calling
|
||||||
|
* xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority higher than the currently executing task (the
|
||||||
|
* task that was interrupted), then, internally, xMessageBufferSendFromISR()
|
||||||
|
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||||
|
* xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. This will
|
||||||
|
* ensure that the interrupt returns directly to the highest priority Ready
|
||||||
|
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||||
|
* is passed into the function. See the code example below for an example.
|
||||||
|
*
|
||||||
|
* @return The number of bytes actually written to the message buffer. If the
|
||||||
|
* message buffer didn't have enough free space for the message to be stored
|
||||||
|
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
// A message buffer that has already been created.
|
||||||
|
MessageBufferHandle_t xMessageBuffer;
|
||||||
|
|
||||||
|
void vAnInterruptServiceRoutine( void )
|
||||||
|
{
|
||||||
|
size_t xBytesSent;
|
||||||
|
char *pcStringToSend = "String to send";
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
|
||||||
|
// Attempt to send the string to the message buffer.
|
||||||
|
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||||
|
( void * ) pcStringToSend,
|
||||||
|
strlen( pcStringToSend ),
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
{
|
||||||
|
// The string could not be added to the message buffer because there was
|
||||||
|
// not enough free space in the buffer.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
// xMessageBufferSendFromISR() then a task that has a priority above the
|
||||||
|
// priority of the currently executing task was unblocked and a context
|
||||||
|
// switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
// task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
|
// variables value, and perform the context switch if necessary. Check the
|
||||||
|
// documentation for the port in use for port specific instructions.
|
||||||
|
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Receives a discrete message from a message buffer. Messages can be of
|
||||||
|
* variable length and are copied out of the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||||
|
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||||
|
* is being received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received message is
|
||||||
|
* to be copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||||
|
* parameter. This sets the maximum length of the message that can be received.
|
||||||
|
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||||
|
* will be left in the message buffer and 0 will be returned.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for a message, should the message buffer be empty.
|
||||||
|
* xMessageBufferReceive() will return immediately if xTicksToWait is zero and
|
||||||
|
* the message buffer is empty. The block time is specified in tick periods, so
|
||||||
|
* the absolute time it represents is dependent on the tick frequency. The
|
||||||
|
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||||
|
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||||
|
* cause the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
*
|
||||||
|
* @return The length, in bytes, of the message read from the message buffer, if
|
||||||
|
* any. If xMessageBufferReceive() times out before a message became available
|
||||||
|
* then zero is returned. If the length of the message is greater than
|
||||||
|
* xBufferLengthBytes then the message will be left in the message buffer and
|
||||||
|
* zero is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||||
|
{
|
||||||
|
uint8_t ucRxData[ 20 ];
|
||||||
|
size_t xReceivedBytes;
|
||||||
|
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||||
|
|
||||||
|
// Receive the next message from the message buffer. Wait in the Blocked
|
||||||
|
// state (so not using any CPU processing time) for a maximum of 100ms for
|
||||||
|
// a message to become available.
|
||||||
|
xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||||
|
( void * ) ucRxData,
|
||||||
|
sizeof( ucRxData ),
|
||||||
|
xBlockTime );
|
||||||
|
|
||||||
|
if( xReceivedBytes > 0 )
|
||||||
|
{
|
||||||
|
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
|
// the message here....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* An interrupt safe version of the API function that receives a discrete
|
||||||
|
* message from a message buffer. Messages can be of variable length and are
|
||||||
|
* copied out of the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||||
|
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||||
|
* is being received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received message is
|
||||||
|
* to be copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||||
|
* parameter. This sets the maximum length of the message that can be received.
|
||||||
|
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||||
|
* will be left in the message buffer and 0 will be returned.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for space to become available. Calling
|
||||||
|
* xMessageBufferReceiveFromISR() can make space available, and so cause a task
|
||||||
|
* that is waiting for space to leave the Blocked state. If calling
|
||||||
|
* xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||||
|
* the unblocked task has a priority higher than the currently executing task
|
||||||
|
* (the task that was interrupted), then, internally,
|
||||||
|
* xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||||
|
* If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. That will
|
||||||
|
* ensure the interrupt returns directly to the highest priority Ready state
|
||||||
|
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||||
|
* passed into the function. See the code example below for an example.
|
||||||
|
*
|
||||||
|
* @return The length, in bytes, of the message read from the message buffer, if
|
||||||
|
* any.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
// A message buffer that has already been created.
|
||||||
|
MessageBuffer_t xMessageBuffer;
|
||||||
|
|
||||||
|
void vAnInterruptServiceRoutine( void )
|
||||||
|
{
|
||||||
|
uint8_t ucRxData[ 20 ];
|
||||||
|
size_t xReceivedBytes;
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
|
||||||
|
// Receive the next message from the message buffer.
|
||||||
|
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||||
|
( void * ) ucRxData,
|
||||||
|
sizeof( ucRxData ),
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
if( xReceivedBytes > 0 )
|
||||||
|
{
|
||||||
|
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
|
// the message here....
|
||||||
|
}
|
||||||
|
|
||||||
|
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
// xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||||
|
// priority of the currently executing task was unblocked and a context
|
||||||
|
// switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
// task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
|
// variables value, and perform the context switch if necessary. Check the
|
||||||
|
// documentation for the port in use for port specific instructions.
|
||||||
|
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Deletes a message buffer that was previously created using a call to
|
||||||
|
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||||
|
* buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
|
||||||
|
* then the allocated memory is freed.
|
||||||
|
*
|
||||||
|
* A message buffer handle must not be used after the message buffer has been
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
<pre>
|
||||||
|
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||||
|
* cannot accept any more messages, of any size, until space is made available
|
||||||
|
* by a message being removed from the message buffer.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||||
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
|
*/
|
||||||
|
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
<pre>
|
||||||
|
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the message buffer referenced by xMessageBuffer is empty then
|
||||||
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
<pre>
|
||||||
|
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Resets a message buffer to its initial empty state, discarding any message it
|
||||||
|
* contained.
|
||||||
|
*
|
||||||
|
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||||
|
*
|
||||||
|
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||||
|
* message buffer could not be reset because either there was a task blocked on
|
||||||
|
* the message queue to wait for space to become available, or to wait for a
|
||||||
|
* a message to be available, then pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
|
</pre>
|
||||||
|
* Returns the number of bytes of free space in the message buffer.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that can be written to the message buffer before
|
||||||
|
* the message buffer would be full. When a message is written to the message
|
||||||
|
* buffer an additional sizeof( size_t ) bytes are also written to store the
|
||||||
|
* message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
|
||||||
|
* of the largest message that can be written to the message buffer is 6 bytes.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||||
|
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||||
|
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||||
|
* from the Blocked state. xMessageBufferSendCompletedFromISR() does the same
|
||||||
|
* thing. It is provided to enable application writers to implement their own
|
||||||
|
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||||
|
* written.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xMessageBufferSendCompletedFromISR(). If calling
|
||||||
|
* xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is read out of a message buffer or stream buffer. If there was a task
|
||||||
|
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||||
|
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||||
|
* remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR()
|
||||||
|
* does the same thing. It is provided to enable application writers to
|
||||||
|
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||||
|
* ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||||
|
* read.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xMessageBufferReceiveCompletedFromISR(). If calling
|
||||||
|
* xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
156
vendor/freertos/freertos/Source/include/mpu_prototypes.h
vendored
Normal file
156
vendor/freertos/freertos/Source/include/mpu_prototypes.h
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the MPU is used the standard (non MPU) API functions are mapped to
|
||||||
|
* equivalents that start "MPU_", the prototypes for which are defined in this
|
||||||
|
* header files. This will cause the application code to call the MPU_ version
|
||||||
|
* which wraps the non-MPU version with privilege promoting then demoting code,
|
||||||
|
* so the kernel code always runs will full privileges.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MPU_PROTOTYPES_H
|
||||||
|
#define MPU_PROTOTYPES_H
|
||||||
|
|
||||||
|
/* MPU versions of tasks.h API functions. */
|
||||||
|
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask );
|
||||||
|
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer );
|
||||||
|
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||||
|
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||||
|
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
|
||||||
|
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete );
|
||||||
|
void MPU_vTaskDelay( const TickType_t xTicksToDelay );
|
||||||
|
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
|
||||||
|
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask );
|
||||||
|
UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t xTask );
|
||||||
|
eTaskState MPU_eTaskGetState( TaskHandle_t xTask );
|
||||||
|
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
|
||||||
|
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
|
||||||
|
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend );
|
||||||
|
void MPU_vTaskResume( TaskHandle_t xTaskToResume );
|
||||||
|
void MPU_vTaskStartScheduler( void );
|
||||||
|
void MPU_vTaskSuspendAll( void );
|
||||||
|
BaseType_t MPU_xTaskResumeAll( void );
|
||||||
|
TickType_t MPU_xTaskGetTickCount( void );
|
||||||
|
UBaseType_t MPU_uxTaskGetNumberOfTasks( void );
|
||||||
|
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery );
|
||||||
|
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery );
|
||||||
|
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
|
||||||
|
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
|
||||||
|
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask );
|
||||||
|
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue );
|
||||||
|
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex );
|
||||||
|
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
|
||||||
|
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void );
|
||||||
|
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime );
|
||||||
|
void MPU_vTaskList( char * pcWriteBuffer );
|
||||||
|
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer );
|
||||||
|
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue );
|
||||||
|
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
|
||||||
|
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
|
||||||
|
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask );
|
||||||
|
BaseType_t MPU_xTaskIncrementTick( void );
|
||||||
|
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void );
|
||||||
|
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut );
|
||||||
|
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait );
|
||||||
|
void MPU_vTaskMissedYield( void );
|
||||||
|
BaseType_t MPU_xTaskGetSchedulerState( void );
|
||||||
|
|
||||||
|
/* MPU versions of queue.h API functions. */
|
||||||
|
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition );
|
||||||
|
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );
|
||||||
|
BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait );
|
||||||
|
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait );
|
||||||
|
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue );
|
||||||
|
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue );
|
||||||
|
void MPU_vQueueDelete( QueueHandle_t xQueue );
|
||||||
|
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType );
|
||||||
|
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue );
|
||||||
|
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount );
|
||||||
|
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue );
|
||||||
|
void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore );
|
||||||
|
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait );
|
||||||
|
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex );
|
||||||
|
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName );
|
||||||
|
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue );
|
||||||
|
const char * MPU_pcQueueGetName( QueueHandle_t xQueue );
|
||||||
|
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType );
|
||||||
|
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType );
|
||||||
|
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength );
|
||||||
|
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||||
|
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||||
|
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait );
|
||||||
|
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue );
|
||||||
|
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber );
|
||||||
|
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue );
|
||||||
|
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue );
|
||||||
|
|
||||||
|
/* MPU versions of timers.h API functions. */
|
||||||
|
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction );
|
||||||
|
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer );
|
||||||
|
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer );
|
||||||
|
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
||||||
|
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||||
|
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
|
||||||
|
const char * MPU_pcTimerGetName( TimerHandle_t xTimer );
|
||||||
|
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer );
|
||||||
|
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||||
|
BaseType_t MPU_xTimerCreateTimerTask( void );
|
||||||
|
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait );
|
||||||
|
|
||||||
|
/* MPU versions of event_group.h API functions. */
|
||||||
|
EventGroupHandle_t MPU_xEventGroupCreate( void );
|
||||||
|
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer );
|
||||||
|
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );
|
||||||
|
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||||
|
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
|
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait );
|
||||||
|
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||||
|
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup );
|
||||||
|
|
||||||
|
/* MPU versions of message/stream_buffer.h API functions. */
|
||||||
|
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait );
|
||||||
|
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
||||||
|
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait );
|
||||||
|
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
||||||
|
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||||
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer );
|
||||||
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MPU_PROTOTYPES_H */
|
||||||
|
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MPU_WRAPPERS_H
|
#ifndef MPU_WRAPPERS_H
|
||||||
#define MPU_WRAPPERS_H
|
#define MPU_WRAPPERS_H
|
||||||
@ -75,62 +38,128 @@ only for ports that are using the MPU. */
|
|||||||
those files. */
|
those files. */
|
||||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#define xTaskGenericCreate MPU_xTaskGenericCreate
|
/*
|
||||||
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
* Map standard (non MPU) API functions to equivalents that start
|
||||||
#define vTaskDelete MPU_vTaskDelete
|
* "MPU_". This will cause the application code to call the MPU_
|
||||||
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
* version, which wraps the non-MPU version with privilege promoting
|
||||||
#define vTaskDelay MPU_vTaskDelay
|
* then demoting code, so the kernel code always runs will full
|
||||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
* privileges.
|
||||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
*/
|
||||||
#define eTaskGetState MPU_eTaskGetState
|
|
||||||
#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 xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
|
||||||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
|
||||||
|
|
||||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
/* Map standard tasks.h API functions to the MPU equivalents. */
|
||||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
#define xTaskCreate MPU_xTaskCreate
|
||||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||||
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
#define vTaskDelete MPU_vTaskDelete
|
||||||
#define xQueueAltGenericSend MPU_xQueueAltGenericSend
|
#define vTaskDelay MPU_vTaskDelay
|
||||||
#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
|
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
#define xTaskAbortDelay MPU_xTaskAbortDelay
|
||||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||||
#define vQueueDelete MPU_vQueueDelete
|
#define eTaskGetState MPU_eTaskGetState
|
||||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
#define vTaskGetInfo MPU_vTaskGetInfo
|
||||||
#define xQueueCreateSet MPU_xQueueCreateSet
|
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
#define vTaskSuspend MPU_vTaskSuspend
|
||||||
#define xQueueAddToSet MPU_xQueueAddToSet
|
#define vTaskResume MPU_vTaskResume
|
||||||
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||||
#define xQueuePeekFromISR MPU_xQueuePeekFromISR
|
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||||
|
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||||
|
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||||
|
#define pcTaskGetName MPU_pcTaskGetName
|
||||||
|
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||||
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
|
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||||
|
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||||
|
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||||
|
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
|
||||||
|
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||||
|
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||||
|
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||||
|
#define vTaskList MPU_vTaskList
|
||||||
|
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||||
|
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||||
|
#define xTaskNotifyWait MPU_xTaskNotifyWait
|
||||||
|
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
|
||||||
|
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear
|
||||||
|
|
||||||
#define pvPortMalloc MPU_pvPortMalloc
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
#define vPortFree MPU_vPortFree
|
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
|
||||||
#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize
|
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||||
#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
|
||||||
#if configQUEUE_REGISTRY_SIZE > 0
|
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
#define xQueueReceive MPU_xQueueReceive
|
||||||
|
#define xQueuePeek MPU_xQueuePeek
|
||||||
|
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
|
||||||
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
|
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||||
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
|
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
|
||||||
|
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||||
|
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
|
||||||
|
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
||||||
|
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||||
|
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||||
|
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||||
|
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
|
||||||
|
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||||
|
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||||
|
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||||
|
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||||
|
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||||
|
|
||||||
|
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||||
|
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||||
|
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||||
|
#define pcQueueGetName MPU_pcQueueGetName
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove the privileged function macro. */
|
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||||
|
#define xTimerCreate MPU_xTimerCreate
|
||||||
|
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
||||||
|
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||||
|
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
||||||
|
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
||||||
|
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||||
|
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
|
||||||
|
#define pcTimerGetName MPU_pcTimerGetName
|
||||||
|
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||||
|
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||||
|
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||||
|
|
||||||
|
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||||
|
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||||
|
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||||
|
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||||
|
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
||||||
|
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
||||||
|
#define xEventGroupSync MPU_xEventGroupSync
|
||||||
|
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||||
|
|
||||||
|
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||||
|
equivalents. */
|
||||||
|
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||||
|
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
|
||||||
|
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||||
|
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
|
||||||
|
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||||
|
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||||
|
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
|
||||||
|
#define xStreamBufferReset MPU_xStreamBufferReset
|
||||||
|
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
|
||||||
|
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
|
||||||
|
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
|
||||||
|
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
|
||||||
|
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||||
|
macro so applications can place data in privileged access sections
|
||||||
|
(useful when using statically allocated objects). */
|
||||||
#define PRIVILEGED_FUNCTION
|
#define PRIVILEGED_FUNCTION
|
||||||
|
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||||
|
|
||||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
568
vendor/freertos/freertos/Source/include/portable.h
vendored
568
vendor/freertos/freertos/Source/include/portable.h
vendored
@ -1,402 +1,166 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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.
|
* Portable layer API. Each function must be defined for each port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
#ifndef PORTABLE_H
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
#define PORTABLE_H
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
1 tab == 4 spaces!
|
pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
|
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
***************************************************************************
|
of setting the compiler's include path such that it found the correct
|
||||||
* *
|
portmacro.h file - removing the need for the constant and allowing the
|
||||||
* Having a problem? Start by reading the FAQ "My application does *
|
portmacro.h file to be located anywhere in relation to the port being used.
|
||||||
* not run, what could be wrong?" *
|
Purely for reasons of backward compatibility the old method is still valid, but
|
||||||
* *
|
to make it clear that new projects should not use it, support for the port
|
||||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
specific constants has been moved into the deprecated_definitions.h header
|
||||||
* *
|
file. */
|
||||||
***************************************************************************
|
#include "deprecated_definitions.h"
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||||
license and Real Time Engineers Ltd. contact details.
|
did not result in a portmacro.h header file being included - and it should be
|
||||||
|
included here. In this case the path to the correct portmacro.h header file
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
must be set in the compiler's include path. */
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
#ifndef portENTER_CRITICAL
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
#if portBYTE_ALIGNMENT == 32
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||||
|
#endif
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
#if portBYTE_ALIGNMENT == 16
|
||||||
mission critical applications that require provable dependability.
|
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||||
|
#endif
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
#if portBYTE_ALIGNMENT == 8
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
/*-----------------------------------------------------------
|
#endif
|
||||||
* Portable layer API. Each function must be defined for each port.
|
|
||||||
*----------------------------------------------------------*/
|
#if portBYTE_ALIGNMENT == 4
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||||
#ifndef PORTABLE_H
|
#endif
|
||||||
#define PORTABLE_H
|
|
||||||
|
#if portBYTE_ALIGNMENT == 2
|
||||||
/* Include the macro file relevant to the port being used. */
|
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||||
|
#endif
|
||||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
#if portBYTE_ALIGNMENT == 1
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
#ifndef portBYTE_ALIGNMENT_MASK
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
#endif
|
||||||
#endif
|
|
||||||
|
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||||
#ifdef GCC_MEGA_AVR
|
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
#endif
|
||||||
#endif
|
|
||||||
|
#ifdef __cplusplus
|
||||||
#ifdef IAR_MEGA_AVR
|
extern "C" {
|
||||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
#endif
|
||||||
#endif
|
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
#ifdef MPLAB_PIC24_PORT
|
|
||||||
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
/*
|
||||||
#endif
|
* 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
|
||||||
#ifdef MPLAB_DSPIC_PORT
|
* the order that the port expects to find them.
|
||||||
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
*
|
||||||
#endif
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
#ifdef MPLAB_PIC18F_PORT
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
|
#else
|
||||||
#endif
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
#ifdef MPLAB_PIC32MX_PORT
|
|
||||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
/* Used by heap_5.c. */
|
||||||
#endif
|
typedef struct HeapRegion
|
||||||
|
{
|
||||||
#ifdef _FEDPICC
|
uint8_t *pucStartAddress;
|
||||||
#include "libFreeRTOS/Include/portmacro.h"
|
size_t xSizeInBytes;
|
||||||
#endif
|
} HeapRegion_t;
|
||||||
|
|
||||||
#ifdef SDCC_CYGNAL
|
/*
|
||||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||||
#endif
|
* must be called before any calls to pvPortMalloc() - not creating a task,
|
||||||
|
* queue, semaphore, mutex, software timer, event group, etc. will result in
|
||||||
#ifdef GCC_ARM7
|
* pvPortMalloc being called.
|
||||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
*
|
||||||
#endif
|
* pxHeapRegions passes in an array of HeapRegion_t structures - each of which
|
||||||
|
* defines a region of memory that can be used as the heap. The array is
|
||||||
#ifdef GCC_ARM7_ECLIPSE
|
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||||
#include "portmacro.h"
|
* with the lowest start address must appear first in the array.
|
||||||
#endif
|
*/
|
||||||
|
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||||
#ifdef ROWLEY_LPC23xx
|
|
||||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
|
||||||
#endif
|
/*
|
||||||
|
* Map to the memory management routines required for the port.
|
||||||
#ifdef IAR_MSP430
|
*/
|
||||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
#ifdef GCC_MSP430
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
|
||||||
|
/*
|
||||||
#ifdef ROWLEY_MSP430
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
#endif
|
*/
|
||||||
|
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
|
||||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
/*
|
||||||
#endif
|
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||||
|
* the hardware is left in its original condition after the scheduler stops
|
||||||
#ifdef SAM7_GCC
|
* executing.
|
||||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
*/
|
||||||
#endif
|
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#ifdef SAM7_IAR
|
/*
|
||||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
* The structures and methods of manipulating the MPU are contained within the
|
||||||
#endif
|
* port layer.
|
||||||
|
*
|
||||||
#ifdef SAM9XE_IAR
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
* contained in xRegions.
|
||||||
#endif
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
#ifdef LPC2000_IAR
|
struct xMEMORY_REGION;
|
||||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STR71X_IAR
|
#ifdef __cplusplus
|
||||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STR75X_IAR
|
#endif /* PORTABLE_H */
|
||||||
#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 ) PRIVILEGED_FUNCTION;
|
|
||||||
#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 */
|
|
||||||
|
|
||||||
|
182
vendor/freertos/freertos/Source/include/projdefs.h
vendored
182
vendor/freertos/freertos/Source/include/projdefs.h
vendored
@ -1,88 +1,124 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROJDEFS_H
|
#ifndef PROJDEFS_H
|
||||||
#define PROJDEFS_H
|
#define PROJDEFS_H
|
||||||
|
|
||||||
/* Defines the prototype to which task functions must conform. */
|
/*
|
||||||
typedef void (*pdTASK_CODE)( void * );
|
* Defines the prototype to which task functions must conform. Defined in this
|
||||||
|
* file to ensure the type is known before portable.h is included.
|
||||||
|
*/
|
||||||
|
typedef void (*TaskFunction_t)( void * );
|
||||||
|
|
||||||
#define pdFALSE ( ( portBASE_TYPE ) 0 )
|
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||||
#define pdTRUE ( ( portBASE_TYPE ) 1 )
|
overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||||
|
definition here is not suitable for your application. */
|
||||||
|
#ifndef pdMS_TO_TICKS
|
||||||
|
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
#define pdPASS ( pdTRUE )
|
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||||
#define pdFAIL ( pdFALSE )
|
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||||
#define errQUEUE_EMPTY ( ( portBASE_TYPE ) 0 )
|
|
||||||
#define errQUEUE_FULL ( ( portBASE_TYPE ) 0 )
|
|
||||||
|
|
||||||
/* Error definitions. */
|
#define pdPASS ( pdTRUE )
|
||||||
|
#define pdFAIL ( pdFALSE )
|
||||||
|
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||||
|
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||||
|
|
||||||
|
/* FreeRTOS error definitions. */
|
||||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||||
#define errNO_TASK_TO_RUN ( -2 )
|
|
||||||
#define errQUEUE_BLOCKED ( -4 )
|
#define errQUEUE_BLOCKED ( -4 )
|
||||||
#define errQUEUE_YIELD ( -5 )
|
#define errQUEUE_YIELD ( -5 )
|
||||||
|
|
||||||
|
/* Macros used for basic data corruption checks. */
|
||||||
|
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
|
||||||
|
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||||
|
#else
|
||||||
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
|
itself. */
|
||||||
|
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||||
|
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||||
|
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||||
|
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||||
|
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||||
|
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
|
||||||
|
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
|
||||||
|
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
|
||||||
|
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
|
||||||
|
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
|
||||||
|
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
|
||||||
|
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
|
||||||
|
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
|
||||||
|
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
|
||||||
|
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
|
||||||
|
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
|
||||||
|
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
|
||||||
|
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
|
||||||
|
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
|
||||||
|
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
|
||||||
|
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||||
|
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
||||||
|
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||||
|
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||||
|
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
|
||||||
|
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
|
||||||
|
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
|
||||||
|
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
|
||||||
|
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
|
||||||
|
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
|
||||||
|
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
|
||||||
|
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||||
|
|
||||||
|
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
|
itself. */
|
||||||
|
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||||
|
#define pdFREERTOS_BIG_ENDIAN 1
|
||||||
|
|
||||||
|
/* Re-defining endian values for generic naming. */
|
||||||
|
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
|
||||||
|
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
#endif /* PROJDEFS_H */
|
#endif /* PROJDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
717
vendor/freertos/freertos/Source/include/queue.h
vendored
717
vendor/freertos/freertos/Source/include/queue.h
vendored
File diff suppressed because it is too large
Load Diff
697
vendor/freertos/freertos/Source/include/semphr.h
vendored
697
vendor/freertos/freertos/Source/include/semphr.h
vendored
File diff suppressed because it is too large
Load Diff
130
vendor/freertos/freertos/Source/include/stack_macros.h
vendored
Normal file
130
vendor/freertos/freertos/Source/include/stack_macros.h
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||||
|
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||||
|
\
|
||||||
|
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
|
static const uint8_t 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( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Remove stack overflow macro if not being used. */
|
||||||
|
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
27
vendor/freertos/freertos/Source/include/stdint.readme
vendored
Normal file
27
vendor/freertos/freertos/Source/include/stdint.readme
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#ifndef FREERTOS_STDINT
|
||||||
|
#define FREERTOS_STDINT
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions
|
||||||
|
* necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be
|
||||||
|
* built using compilers that do not provide their own stdint.h definition.
|
||||||
|
*
|
||||||
|
* To use this file:
|
||||||
|
*
|
||||||
|
* 1) Copy this file into the directory that contains your FreeRTOSConfig.h
|
||||||
|
* header file, as that directory will already be in the compilers include
|
||||||
|
* path.
|
||||||
|
*
|
||||||
|
* 2) Rename the copied file stdint.h.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef long int32_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
|
||||||
|
#endif /* FREERTOS_STDINT */
|
849
vendor/freertos/freertos/Source/include/stream_buffer.h
vendored
Normal file
849
vendor/freertos/freertos/Source/include/stream_buffer.h
vendored
Normal file
@ -0,0 +1,849 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stream buffers are used to send a continuous stream of data from one task or
|
||||||
|
* interrupt to another. Their implementation is light weight, making them
|
||||||
|
* particularly suited for interrupt to task and core to core communication
|
||||||
|
* scenarios.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xStreamBufferRead()) inside a critical section section and set the
|
||||||
|
* receive block time to 0.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STREAM_BUFFER_H
|
||||||
|
#define STREAM_BUFFER_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type by which stream buffers are referenced. For example, a call to
|
||||||
|
* xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
|
||||||
|
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
||||||
|
* etc.
|
||||||
|
*/
|
||||||
|
typedef void * StreamBufferHandle_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Creates a new stream buffer using dynamically allocated memory. See
|
||||||
|
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
||||||
|
* memory (memory that is allocated at compile time).
|
||||||
|
*
|
||||||
|
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||||
|
* FreeRTOSConfig.h for xStreamBufferCreate() to be available.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The total number of bytes the stream buffer will be
|
||||||
|
* able to hold at any one time.
|
||||||
|
*
|
||||||
|
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||||
|
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||||
|
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||||
|
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||||
|
* unblocked when a single byte is written to the buffer or the task's block
|
||||||
|
* time expires. As another example, if a task is blocked on a read of an empty
|
||||||
|
* stream buffer that has a trigger level of 10 then the task will not be
|
||||||
|
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||||
|
* block time expires. If a reading task's block time expires before the
|
||||||
|
* trigger level is reached then the task will still receive however many bytes
|
||||||
|
* are actually available. Setting a trigger level of 0 will result in a
|
||||||
|
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||||
|
* that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* @return If NULL is returned, then the stream buffer cannot be created
|
||||||
|
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||||
|
* the stream buffer data structures and storage area. A non-NULL value being
|
||||||
|
* returned indicates that the stream buffer has been created successfully -
|
||||||
|
* the returned value should be stored as the handle to the created stream
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
void vAFunction( void )
|
||||||
|
{
|
||||||
|
StreamBufferHandle_t xStreamBuffer;
|
||||||
|
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||||
|
|
||||||
|
// Create a stream buffer that can hold 100 bytes. The memory used to hold
|
||||||
|
// both the stream buffer structure and the data in the stream buffer is
|
||||||
|
// allocated dynamically.
|
||||||
|
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
||||||
|
|
||||||
|
if( xStreamBuffer == NULL )
|
||||||
|
{
|
||||||
|
// There was not enough heap memory space available to create the
|
||||||
|
// stream buffer.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The stream buffer was created successfully and can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
uint8_t *pucStreamBufferStorageArea,
|
||||||
|
StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
* Creates a new stream buffer using statically allocated memory. See
|
||||||
|
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
||||||
|
*
|
||||||
|
* configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
|
||||||
|
* xStreamBufferCreateStatic() to be available.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||||
|
* pucStreamBufferStorageArea parameter.
|
||||||
|
*
|
||||||
|
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||||
|
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||||
|
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||||
|
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||||
|
* unblocked when a single byte is written to the buffer or the task's block
|
||||||
|
* time expires. As another example, if a task is blocked on a read of an empty
|
||||||
|
* stream buffer that has a trigger level of 10 then the task will not be
|
||||||
|
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||||
|
* block time expires. If a reading task's block time expires before the
|
||||||
|
* trigger level is reached then the task will still receive however many bytes
|
||||||
|
* are actually available. Setting a trigger level of 0 will result in a
|
||||||
|
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||||
|
* that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
|
||||||
|
* least xBufferSizeBytes + 1 big. This is the array to which streams are
|
||||||
|
* copied when they are written to the stream buffer.
|
||||||
|
*
|
||||||
|
* @param pxStaticStreamBuffer Must point to a variable of type
|
||||||
|
* StaticStreamBuffer_t, which will be used to hold the stream buffer's data
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* @return If the stream buffer is created successfully then a handle to the
|
||||||
|
* created stream buffer is returned. If either pucStreamBufferStorageArea or
|
||||||
|
* pxStaticstreamBuffer are NULL then NULL is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
// Used to dimension the array used to hold the streams. The available space
|
||||||
|
// will actually be one less than this, so 999.
|
||||||
|
#define STORAGE_SIZE_BYTES 1000
|
||||||
|
|
||||||
|
// Defines the memory that will actually hold the streams within the stream
|
||||||
|
// buffer.
|
||||||
|
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||||
|
|
||||||
|
// The variable used to hold the stream buffer structure.
|
||||||
|
StaticStreamBuffer_t xStreamBufferStruct;
|
||||||
|
|
||||||
|
void MyFunction( void )
|
||||||
|
{
|
||||||
|
StreamBufferHandle_t xStreamBuffer;
|
||||||
|
const size_t xTriggerLevel = 1;
|
||||||
|
|
||||||
|
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||||
|
xTriggerLevel,
|
||||||
|
ucBufferStorage,
|
||||||
|
&xStreamBufferStruct );
|
||||||
|
|
||||||
|
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
||||||
|
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
||||||
|
// reference the created stream buffer in other stream buffer API calls.
|
||||||
|
|
||||||
|
// Other code that uses the stream buffer can go here.
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
<pre>
|
||||||
|
*
|
||||||
|
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||||
|
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the buffer that holds the bytes to be copied
|
||||||
|
* into the stream buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||||
|
* into the stream buffer.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for enough space to become available in the stream
|
||||||
|
* buffer, should the stream buffer contain too little space to hold the
|
||||||
|
* another xDataLengthBytes bytes. The block time is specified in tick periods,
|
||||||
|
* so the absolute time it represents is dependent on the tick frequency. The
|
||||||
|
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||||
|
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||||
|
* cause the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||||
|
* before it can write all xDataLengthBytes into the buffer it will still write
|
||||||
|
* as many bytes as possible. A task does not use any CPU time when it is in
|
||||||
|
* the blocked state.
|
||||||
|
*
|
||||||
|
* @return The number of bytes written to the stream buffer. If a task times
|
||||||
|
* out before it can write all xDataLengthBytes into the buffer it will still
|
||||||
|
* write as many bytes as possible.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
||||||
|
{
|
||||||
|
size_t xBytesSent;
|
||||||
|
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||||
|
char *pcStringToSend = "String to send";
|
||||||
|
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||||
|
|
||||||
|
// Send an array to the stream buffer, blocking for a maximum of 100ms to
|
||||||
|
// wait for enough space to be available in the stream buffer.
|
||||||
|
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||||
|
|
||||||
|
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||||
|
{
|
||||||
|
// The call to xStreamBufferSend() times out before there was enough
|
||||||
|
// space in the buffer for the data to be written, but it did
|
||||||
|
// successfully write xBytesSent bytes.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the string to the stream buffer. Return immediately if there is not
|
||||||
|
// enough space in the buffer.
|
||||||
|
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||||
|
|
||||||
|
if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
{
|
||||||
|
// The entire string could not be added to the stream buffer because
|
||||||
|
// there was not enough free space in the buffer, but xBytesSent bytes
|
||||||
|
// were sent. Could try again to send the remaining bytes.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferSend xStreamBufferSend
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
<pre>
|
||||||
|
*
|
||||||
|
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||||
|
* the stream buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||||
|
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the data that is to be copied into the stream
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||||
|
* into the stream buffer.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||||
|
* have a task blocked on it waiting for data. Calling
|
||||||
|
* xStreamBufferSendFromISR() can make data available, and so cause a task that
|
||||||
|
* was waiting for data to leave the Blocked state. If calling
|
||||||
|
* xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority higher than the currently executing task (the
|
||||||
|
* task that was interrupted), then, internally, xStreamBufferSendFromISR()
|
||||||
|
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||||
|
* xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. This will
|
||||||
|
* ensure that the interrupt returns directly to the highest priority Ready
|
||||||
|
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||||
|
* is passed into the function. See the example code below for an example.
|
||||||
|
*
|
||||||
|
* @return The number of bytes actually written to the stream buffer, which will
|
||||||
|
* be less than xDataLengthBytes if the stream buffer didn't have enough free
|
||||||
|
* space for all the bytes to be written.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
// A stream buffer that has already been created.
|
||||||
|
StreamBufferHandle_t xStreamBuffer;
|
||||||
|
|
||||||
|
void vAnInterruptServiceRoutine( void )
|
||||||
|
{
|
||||||
|
size_t xBytesSent;
|
||||||
|
char *pcStringToSend = "String to send";
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
|
||||||
|
// Attempt to send the string to the stream buffer.
|
||||||
|
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
||||||
|
( void * ) pcStringToSend,
|
||||||
|
strlen( pcStringToSend ),
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
{
|
||||||
|
// There was not enough free space in the stream buffer for the entire
|
||||||
|
// string to be written, ut xBytesSent bytes were written.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
// xStreamBufferSendFromISR() then a task that has a priority above the
|
||||||
|
// priority of the currently executing task was unblocked and a context
|
||||||
|
// switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
// task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
|
// variables value, and perform the context switch if necessary. Check the
|
||||||
|
// documentation for the port in use for port specific instructions.
|
||||||
|
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void *pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Receives bytes from a stream buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xStreamBufferReceive() to read from a stream buffer from a task. Use
|
||||||
|
* xStreamBufferReceiveFromISR() to read from a stream buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer from which bytes are to
|
||||||
|
* be received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received bytes will be
|
||||||
|
* copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||||
|
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||||
|
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||||
|
* maximum set by xBufferLengthBytes.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for data to become available if the stream buffer is
|
||||||
|
* empty. xStreamBufferReceive() will return immediately if xTicksToWait is
|
||||||
|
* zero. The block time is specified in tick periods, so the absolute time it
|
||||||
|
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can
|
||||||
|
* be used to convert a time specified in milliseconds into a time specified in
|
||||||
|
* ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait
|
||||||
|
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
|
||||||
|
* in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||||
|
* Blocked state.
|
||||||
|
*
|
||||||
|
* @return The number of bytes actually read from the stream buffer, which will
|
||||||
|
* be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
|
||||||
|
* out before xBufferLengthBytes were available.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
void vAFunction( StreamBuffer_t xStreamBuffer )
|
||||||
|
{
|
||||||
|
uint8_t ucRxData[ 20 ];
|
||||||
|
size_t xReceivedBytes;
|
||||||
|
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||||
|
|
||||||
|
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
||||||
|
// Wait in the Blocked state (so not using any CPU processing time) for a
|
||||||
|
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
||||||
|
// available.
|
||||||
|
xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
||||||
|
( void * ) ucRxData,
|
||||||
|
sizeof( ucRxData ),
|
||||||
|
xBlockTime );
|
||||||
|
|
||||||
|
if( xReceivedBytes > 0 )
|
||||||
|
{
|
||||||
|
// A ucRxData contains another xRecievedBytes bytes of data, which can
|
||||||
|
// be processed here....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* An interrupt safe version of the API function that receives bytes from a
|
||||||
|
* stream buffer.
|
||||||
|
*
|
||||||
|
* Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
|
||||||
|
* Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer from which a stream
|
||||||
|
* is being received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received bytes are
|
||||||
|
* copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||||
|
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||||
|
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||||
|
* maximum set by xBufferLengthBytes.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||||
|
* have a task blocked on it waiting for space to become available. Calling
|
||||||
|
* xStreamBufferReceiveFromISR() can make space available, and so cause a task
|
||||||
|
* that is waiting for space to leave the Blocked state. If calling
|
||||||
|
* xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||||
|
* the unblocked task has a priority higher than the currently executing task
|
||||||
|
* (the task that was interrupted), then, internally,
|
||||||
|
* xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||||
|
* If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. That will
|
||||||
|
* ensure the interrupt returns directly to the highest priority Ready state
|
||||||
|
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||||
|
* passed into the function. See the code example below for an example.
|
||||||
|
*
|
||||||
|
* @return The number of bytes read from the stream buffer, if any.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
<pre>
|
||||||
|
// A stream buffer that has already been created.
|
||||||
|
StreamBuffer_t xStreamBuffer;
|
||||||
|
|
||||||
|
void vAnInterruptServiceRoutine( void )
|
||||||
|
{
|
||||||
|
uint8_t ucRxData[ 20 ];
|
||||||
|
size_t xReceivedBytes;
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
|
||||||
|
// Receive the next stream from the stream buffer.
|
||||||
|
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
||||||
|
( void * ) ucRxData,
|
||||||
|
sizeof( ucRxData ),
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
if( xReceivedBytes > 0 )
|
||||||
|
{
|
||||||
|
// ucRxData contains xReceivedBytes read from the stream buffer.
|
||||||
|
// Process the stream here....
|
||||||
|
}
|
||||||
|
|
||||||
|
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
// xStreamBufferReceiveFromISR() then a task that has a priority above the
|
||||||
|
// priority of the currently executing task was unblocked and a context
|
||||||
|
// switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
// task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
|
// variables value, and perform the context switch if necessary. Check the
|
||||||
|
// documentation for the port in use for port specific instructions.
|
||||||
|
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void *pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Deletes a stream buffer that was previously created using a call to
|
||||||
|
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
||||||
|
* buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
|
||||||
|
* then the allocated memory is freed.
|
||||||
|
*
|
||||||
|
* A stream buffer handle must not be used after the stream buffer has been
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer to be deleted.
|
||||||
|
*
|
||||||
|
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||||
|
* does not have any free space, and therefore cannot accept any more data.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the stream buffer is full then pdTRUE is returned. Otherwise
|
||||||
|
* pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||||
|
* it does not contain any data.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the stream buffer is empty then pdTRUE is returned. Otherwise
|
||||||
|
* pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||||
|
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||||
|
* are no tasks blocked waiting to either send to or receive from the stream
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being reset.
|
||||||
|
*
|
||||||
|
* @return If the stream buffer is reset then pdPASS is returned. If there was
|
||||||
|
* a task blocked waiting to send to or read from the stream buffer then the
|
||||||
|
* stream buffer is not reset and pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferReset xStreamBufferReset
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see how much free space it contains, which is
|
||||||
|
* equal to the amount of data that can be sent to the stream buffer before it
|
||||||
|
* is full.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that can be written to the stream buffer before
|
||||||
|
* the stream buffer would be full.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see how much data it contains, which is equal to
|
||||||
|
* the number of bytes that can be read from the stream buffer before the stream
|
||||||
|
* buffer would be empty.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that can be read from the stream buffer before
|
||||||
|
* the stream buffer would be empty.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||||
|
* stream buffer before a task that is blocked on the stream buffer to
|
||||||
|
* wait for data is moved out of the blocked state. For example, if a task is
|
||||||
|
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||||
|
* then the task will be unblocked when a single byte is written to the buffer
|
||||||
|
* or the task's block time expires. As another example, if a task is blocked
|
||||||
|
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||||
|
* task will not be unblocked until the stream buffer contains at least 10 bytes
|
||||||
|
* or the task's block time expires. If a reading task's block time expires
|
||||||
|
* before the trigger level is reached then the task will still receive however
|
||||||
|
* many bytes are actually available. Setting a trigger level of 0 will result
|
||||||
|
* in a trigger level of 1 being used. It is not valid to specify a trigger
|
||||||
|
* level that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* A trigger level is set when the stream buffer is created, and can be modified
|
||||||
|
* using xStreamBufferSetTriggerLevel().
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer being updated.
|
||||||
|
*
|
||||||
|
* @param xTriggerLevel The new trigger level for the stream buffer.
|
||||||
|
*
|
||||||
|
* @return If xTriggerLevel was less than or equal to the stream buffer's length
|
||||||
|
* then the trigger level will be updated and pdTRUE is returned. Otherwise
|
||||||
|
* pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||||
|
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||||
|
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||||
|
* from the Blocked state. xStreamBufferSendCompletedFromISR() does the same
|
||||||
|
* thing. It is provided to enable application writers to implement their own
|
||||||
|
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||||
|
* written.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xStreamBufferSendCompletedFromISR(). If calling
|
||||||
|
* xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stream_buffer.h
|
||||||
|
*
|
||||||
|
<pre>
|
||||||
|
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is read out of a message buffer or stream buffer. If there was a task
|
||||||
|
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||||
|
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||||
|
* remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR()
|
||||||
|
* does the same thing. It is provided to enable application writers to
|
||||||
|
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||||
|
* ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||||
|
* read.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xStreamBufferReceiveCompletedFromISR(). If calling
|
||||||
|
* xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* Functions below here are not part of the public API. */
|
||||||
|
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xIsMessageBuffer,
|
||||||
|
uint8_t * const pucStreamBufferStorageArea,
|
||||||
|
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !defined( STREAM_BUFFER_H ) */
|
1339
vendor/freertos/freertos/Source/include/task.h
vendored
1339
vendor/freertos/freertos/Source/include/task.h
vendored
File diff suppressed because it is too large
Load Diff
714
vendor/freertos/freertos/Source/include/timers.h
vendored
714
vendor/freertos/freertos/Source/include/timers.h
vendored
File diff suppressed because it is too large
Load Diff
193
vendor/freertos/freertos/Source/list.c
vendored
193
vendor/freertos/freertos/Source/list.c
vendored
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -72,12 +35,12 @@
|
|||||||
* PUBLIC LIST API documented in list.h
|
* PUBLIC LIST API documented in list.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( xList * const pxList )
|
void vListInitialise( List_t * const pxList )
|
||||||
{
|
{
|
||||||
/* The list structure contains a list item which is used to mark the
|
/* 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
|
end of the list. To initialise the list the list end is inserted
|
||||||
as the only list entry. */
|
as the only list entry. */
|
||||||
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
ensure it remains at the end of the list. */
|
ensure it remains at the end of the list. */
|
||||||
@ -85,31 +48,49 @@ void vListInitialise( xList * const pxList )
|
|||||||
|
|
||||||
/* The list end next and previous pointers point to itself so we know
|
/* The list end next and previous pointers point to itself so we know
|
||||||
when the list is empty. */
|
when the list is empty. */
|
||||||
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
|
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||||
|
|
||||||
|
/* Write known values into the list if
|
||||||
|
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
|
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||||
|
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialiseItem( xListItem * const pxItem )
|
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
{
|
{
|
||||||
/* Make sure the list item is not recorded as being on a list. */
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
pxItem->pvContainer = NULL;
|
pxItem->pvContainer = NULL;
|
||||||
|
|
||||||
|
/* Write known values into the list item if
|
||||||
|
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem )
|
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
xListItem * pxIndex;
|
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
|
the list data structures being overwritten in memory. They will not catch
|
||||||
|
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* 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
|
makes the new list item the last item to be removed by a call to
|
||||||
pvListGetOwnerOfNextEntry. */
|
listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||||
pxIndex = pxList->pxIndex;
|
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIndex;
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
|
|
||||||
|
/* Only used during decision coverage testing. */
|
||||||
|
mtCOVERAGE_TEST_DELAY();
|
||||||
|
|
||||||
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||||
pxIndex->pxPrevious = pxNewListItem;
|
pxIndex->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
@ -120,21 +101,25 @@ xListItem * pxIndex;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( xList * const pxList, xListItem * const pxNewListItem )
|
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
xListItem *pxIterator;
|
ListItem_t *pxIterator;
|
||||||
portTickType xValueOfInsertion;
|
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in ulListItem order. */
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
xValueOfInsertion = pxNewListItem->xItemValue;
|
the list data structures being overwritten in memory. They will not catch
|
||||||
|
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* If the list already contains a list item with the same item value then
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
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)
|
If the list already contains a list item with the same item value then the
|
||||||
get an equal share of the CPU. However, if the xItemValue is the same as
|
new list item should be placed after it. This ensures that TCB's which are
|
||||||
the back marker the iteration loop below will not end. This means we need
|
stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
to guard against this by checking the value first and modifying the
|
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
algorithm slightly if necessary. */
|
the iteration loop below will not end. Therefore the value is checked
|
||||||
|
first, and the algorithm slightly modified if necessary. */
|
||||||
if( xValueOfInsertion == portMAX_DELAY )
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
{
|
{
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
@ -142,26 +127,31 @@ portTickType xValueOfInsertion;
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* *** NOTE ***********************************************************
|
/* *** NOTE ***********************************************************
|
||||||
If you find your application is crashing here then likely causes are:
|
If you find your application is crashing here then likely causes are
|
||||||
|
listed below. In addition see http://www.freertos.org/FAQHelp.html for
|
||||||
|
more tips, and ensure configASSERT() is defined!
|
||||||
|
http://www.freertos.org/a00110.html#configASSERT
|
||||||
|
|
||||||
1) Stack overflow -
|
1) Stack overflow -
|
||||||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||||
parts where numerically high priority values denote low actual
|
parts where numerically high priority values denote low actual
|
||||||
interrupt priories, which can seem counter intuitive. See
|
interrupt priorities, which can seem counter intuitive. See
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||||
|
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||||
|
http://www.freertos.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended, or calling an API function that does
|
the scheduler is suspended, or calling an API function that does
|
||||||
not end in "FromISR" from an interrupt.
|
not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
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 ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, we are just iterating to the
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
wanted insertion position. */
|
insertion position. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,22 +168,27 @@ portTickType xValueOfInsertion;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove )
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
{
|
{
|
||||||
xList * pxList;
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
|
item. */
|
||||||
|
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
/* Only used during decision coverage testing. */
|
||||||
item. */
|
mtCOVERAGE_TEST_DELAY();
|
||||||
pxList = ( xList * ) pxItemToRemove->pvContainer;
|
|
||||||
|
|
||||||
/* Make sure the index is left pointing to a valid item. */
|
/* Make sure the index is left pointing to a valid item. */
|
||||||
if( pxList->pxIndex == pxItemToRemove )
|
if( pxList->pxIndex == pxItemToRemove )
|
||||||
{
|
{
|
||||||
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
pxItemToRemove->pvContainer = NULL;
|
pxItemToRemove->pvContainer = NULL;
|
||||||
( pxList->uxNumberOfItems )--;
|
( pxList->uxNumberOfItems )--;
|
||||||
|
1291
vendor/freertos/freertos/Source/portable/Common/mpu_wrappers.c
vendored
Normal file
1291
vendor/freertos/freertos/Source/portable/Common/mpu_wrappers.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,253 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* 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 xTaskIncrementTick \t\n" \
|
|
||||||
" cmp r0, #0 \t\n" \
|
|
||||||
" beq SkipContextSwitch \t\n" \
|
|
||||||
" bl vTaskSwitchContext \t\n" \
|
|
||||||
"SkipContextSwitch: \t\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,260 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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 */
|
|
||||||
|
|
@ -1,271 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* 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 )
|
|
||||||
{
|
|
||||||
xTaskIncrementTick();
|
|
||||||
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 xTaskIncrementTick \t\n" \
|
|
||||||
" cmp r0, #0 \t\n" \
|
|
||||||
" beq SkipContextSwitch \t\n" \
|
|
||||||
" bl vTaskSwitchContext \t\n" \
|
|
||||||
"SkipContextSwitch: \t\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,283 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 */
|
|
||||||
|
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
||||||
@ -72,23 +35,24 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to manipulate the NVIC. */
|
/* Constants required to manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
|
#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 )
|
||||||
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
|
#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 )
|
||||||
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
|
#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )
|
||||||
#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
|
#define portNVIC_INT_CTRL ( ( volatile uint32_t *) 0xe000ed04 )
|
||||||
#define portNVIC_SYSTICK_CLK 0x00000004
|
#define portNVIC_SYSPRI2 ( ( volatile uint32_t *) 0xe000ed20 )
|
||||||
#define portNVIC_SYSTICK_INT 0x00000002
|
#define portNVIC_SYSTICK_CLK 0x00000004
|
||||||
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
#define portNVIC_SYSTICK_INT 0x00000002
|
||||||
#define portNVIC_PENDSVSET 0x10000000
|
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
||||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
#define portNVIC_PENDSVSET 0x10000000
|
||||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||||
|
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case is messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
@ -96,10 +60,6 @@ debugger. */
|
|||||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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.
|
* Setup the timer to generate the tick interrupts.
|
||||||
*/
|
*/
|
||||||
@ -124,21 +84,27 @@ static void prvTaskExitError( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
interrupt. */
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
*pxTopOfStack = ( StackType_t ) pxCode; /* PC */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) portTASK_RETURN_ADDRESS; /* LR */
|
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack -= 8; /* R11..R4. */
|
pxTopOfStack -= 8; /* R11..R4. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
@ -147,6 +113,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
@ -155,7 +123,16 @@ static void prvTaskExitError( void )
|
|||||||
defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
while( ulDummy == 0 )
|
||||||
|
{
|
||||||
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
|
started to remove a compiler warning about the function being defined
|
||||||
|
but never called. ulDummy is used purely to quieten other warnings
|
||||||
|
about code appearing after this function is called - making ulDummy
|
||||||
|
volatile makes the compiler think the function could return and
|
||||||
|
therefore not output an 'unreachable code' warning for code that appears
|
||||||
|
after it. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -172,20 +149,24 @@ void vPortStartFirstTask( void )
|
|||||||
table offset register that can be used to locate the initial stack value.
|
table offset register that can be used to locate the initial stack value.
|
||||||
Not all M0 parts have the application vector table at address 0. */
|
Not all M0 parts have the application vector table at address 0. */
|
||||||
__asm volatile(
|
__asm volatile(
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
" .syntax unified \n"
|
||||||
" ldr r3, [r2] \n"
|
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
||||||
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r3, [r2] \n"
|
||||||
" add r0, #32 \n" /* Discard everything up to r0. */
|
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
" movs r0, #2 \n" /* Switch to the psp stack. */
|
" movs r0, #2 \n" /* Switch to the psp stack. */
|
||||||
" msr CONTROL, r0 \n"
|
" msr CONTROL, r0 \n"
|
||||||
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
" isb \n"
|
||||||
" mov lr, r5 \n" /* lr is now in r5. */
|
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
||||||
|
" mov lr, r5 \n" /* lr is now in r5. */
|
||||||
|
" pop {r3} \n" /* Return address is now in r3. */
|
||||||
|
" pop {r2} \n" /* Pop and discard XPSR. */
|
||||||
" cpsie i \n" /* The first task has its context and interrupts can be enabled. */
|
" cpsie i \n" /* The first task has its context and interrupts can be enabled. */
|
||||||
" pop {pc} \n" /* Finally, pop the PC to jump to the user defined task code. */
|
" bx r3 \n" /* Finally, jump to the user defined task code. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -193,7 +174,7 @@ void vPortStartFirstTask( void )
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
|
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
|
||||||
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
|
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
|
||||||
@ -208,11 +189,14 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should never get here as the tasks will now be executing! Call the task
|
/* Should never get here as the tasks will now be executing! Call the task
|
||||||
exit error function to prevent compiler warnings about a static function
|
exit error function to prevent compiler warnings about a static function
|
||||||
not being called in the case that the application writer overrides this
|
not being called in the case that the application writer overrides this
|
||||||
functionality by defining configTASK_RETURN_ADDRESS. */
|
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
|
vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
|
symbol. */
|
||||||
|
vTaskSwitchContext();
|
||||||
prvTaskExitError();
|
prvTaskExitError();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
@ -222,8 +206,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the CM0 port will require this function as there
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
is nothing to return to. */
|
Artificially force an assert. */
|
||||||
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -234,7 +219,7 @@ void vPortYield( void )
|
|||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
/* Barriers are normally not required but do ensure the code is completely
|
||||||
within the specified behaviour for the architecture. */
|
within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" );
|
__asm volatile( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -243,13 +228,14 @@ void vPortEnterCritical( void )
|
|||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__asm volatile( "dsb" );
|
__asm volatile( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
@ -258,28 +244,38 @@ void vPortExitCritical( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
unsigned long ulSetInterruptMaskFromISR( void )
|
uint32_t ulSetInterruptMaskFromISR( void )
|
||||||
{
|
{
|
||||||
__asm volatile(
|
__asm volatile(
|
||||||
" mrs r0, PRIMASK \n"
|
" mrs r0, PRIMASK \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bx lr "
|
" bx lr "
|
||||||
|
::: "memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
/* To avoid compiler warnings. This line will never be reached. */
|
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
/* To avoid compiler warnings. The return statement will nevere be reached,
|
||||||
|
but some compilers warn if it is not included, while others won't compile if
|
||||||
|
it is. */
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vClearInterruptMaskFromISR( unsigned long ulMask )
|
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
||||||
{
|
{
|
||||||
__asm volatile(
|
__asm volatile(
|
||||||
" msr PRIMASK, r0 \n"
|
" msr PRIMASK, r0 \n"
|
||||||
" bx lr "
|
" bx lr "
|
||||||
|
::: "memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Just to avoid compiler warning. */
|
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
/* Just to avoid compiler warning. ulMask is used from the asm code but
|
||||||
|
the compiler can't see that. Some compilers generate warnings without the
|
||||||
|
following line, while others generate warnings if the line is included. */
|
||||||
( void ) ulMask;
|
( void ) ulMask;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -289,19 +285,20 @@ void xPortPendSVHandler( void )
|
|||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
" \n"
|
" \n"
|
||||||
" sub r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
" subs r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
||||||
" str r0, [r2] \n" /* Save the new top of stack. */
|
" str r0, [r2] \n" /* Save the new top of stack. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* Store the high registers. */
|
" mov r4, r8 \n" /* Store the high registers. */
|
||||||
" mov r5, r9 \n"
|
" mov r5, r9 \n"
|
||||||
" mov r6, r10 \n"
|
" mov r6, r10 \n"
|
||||||
" mov r7, r11 \n"
|
" mov r7, r11 \n"
|
||||||
" stmia r0!, {r4-r7} \n"
|
" stmia r0!, {r4-r7} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" push {r3, r14} \n"
|
" push {r3, r14} \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
@ -311,7 +308,7 @@ void xPortPendSVHandler( void )
|
|||||||
" \n"
|
" \n"
|
||||||
" ldr r1, [r2] \n"
|
" ldr r1, [r2] \n"
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" 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. */
|
" adds r0, r0, #16 \n" /* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
||||||
" mov r8, r4 \n"
|
" mov r8, r4 \n"
|
||||||
" mov r9, r5 \n"
|
" mov r9, r5 \n"
|
||||||
@ -320,12 +317,12 @@ void xPortPendSVHandler( void )
|
|||||||
" \n"
|
" \n"
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
" \n"
|
" \n"
|
||||||
" sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
" subs r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB "
|
"pxCurrentTCBConst: .word pxCurrentTCB "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -333,7 +330,7 @@ void xPortPendSVHandler( void )
|
|||||||
|
|
||||||
void xPortSysTickHandler( void )
|
void xPortSysTickHandler( void )
|
||||||
{
|
{
|
||||||
unsigned long ulPreviousMask;
|
uint32_t ulPreviousMask;
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
@ -354,6 +351,10 @@ unsigned long ulPreviousMask;
|
|||||||
*/
|
*/
|
||||||
void prvSetupTimerInterrupt( void )
|
void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
|
/* Stop and reset the SysTick. */
|
||||||
|
*(portNVIC_SYSTICK_CTRL) = 0UL;
|
||||||
|
*(portNVIC_SYSTICK_CURRENT_VALUE) = 0UL;
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||||
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
|
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
|
||||||
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
@ -87,28 +50,36 @@ extern "C" {
|
|||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE unsigned portLONG
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef unsigned portSHORT portTickType;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef unsigned portLONG portTickType;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
@ -119,13 +90,13 @@ extern void vPortYield( void );
|
|||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern unsigned long ulSetInterruptMaskFromISR( void ) __attribute__((naked));
|
extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__((naked));
|
||||||
extern void vClearInterruptMaskFromISR( unsigned long ulMask ) __attribute__((naked));
|
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__((naked));
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
||||||
@ -80,34 +43,42 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
|||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
#else
|
||||||
|
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||||
|
as the core. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||||
|
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
/* Constants required to check the validity of an interrupt priority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000UL )
|
#define portINITIAL_XPSR ( 0x01000000UL )
|
||||||
|
|
||||||
@ -119,8 +90,12 @@ occurred while the SysTick counter is stopped during tickless idle
|
|||||||
calculations. */
|
calculations. */
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
|
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case is messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
@ -128,10 +103,6 @@ debugger. */
|
|||||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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
|
* 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
|
* file is weak to allow application writers to change the timer used to
|
||||||
@ -158,27 +129,31 @@ static void prvTaskExitError( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of SysTick increments that make up one tick period.
|
* The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The maximum number of tick periods that can be suppressed is limited by the
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
* 24 bit resolution of the SysTick timer.
|
* 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
* power functionality only.
|
* power functionality only.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long ulStoppedTimerCompensation = 0;
|
static uint32_t ulStoppedTimerCompensation = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -186,10 +161,10 @@ static void prvTaskExitError( void );
|
|||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static uint8_t ucMaxSysCallPriority = 0;
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -197,18 +172,18 @@ static void prvTaskExitError( void );
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
interrupt. */
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) portTASK_RETURN_ADDRESS; /* LR */
|
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
@ -217,6 +192,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
@ -225,7 +202,16 @@ static void prvTaskExitError( void )
|
|||||||
defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
while( ulDummy == 0 )
|
||||||
|
{
|
||||||
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
|
started to remove a compiler warning about the function being defined
|
||||||
|
but never called. ulDummy is used purely to quieten other warnings
|
||||||
|
about code appearing after this function is called - making ulDummy
|
||||||
|
volatile makes the compiler think the function could return and
|
||||||
|
therefore not output an 'unreachable code' warning for code that appears
|
||||||
|
after it. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -237,12 +223,13 @@ void vPortSVCHandler( void )
|
|||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" 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. */
|
" 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. */
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" orr r14, #0xd \n"
|
" orr r14, #0xd \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -256,6 +243,9 @@ static void prvPortStartFirstTask( void )
|
|||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
);
|
);
|
||||||
@ -265,7 +255,7 @@ static void prvPortStartFirstTask( void )
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
@ -273,9 +263,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
@ -283,14 +273,14 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
ensure interrupt entry is as fast and simple as possible.
|
ensure interrupt entry is as fast and simple as possible.
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
/* Determine the number of priority bits available. First write to all
|
||||||
possible bits. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
/* Use the same mask on the maximum system call priority. */
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
@ -301,9 +291,27 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulMaxPRIGROUPValue--;
|
ulMaxPRIGROUPValue--;
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __NVIC_PRIO_BITS
|
||||||
|
{
|
||||||
|
/* Check the CMSIS configuration that defines the number of
|
||||||
|
priority bits matches the number of priority bits actually queried
|
||||||
|
from the hardware. */
|
||||||
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef configPRIO_BITS
|
||||||
|
{
|
||||||
|
/* Check the FreeRTOS configuration that defines the number of
|
||||||
|
priority bits matches the number of priority bits actually queried
|
||||||
|
from the hardware. */
|
||||||
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
/* Shift the priority group value back to its position within the AIRCR
|
||||||
register. */
|
register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
@ -311,7 +319,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
||||||
@ -332,7 +340,10 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
/* Should never get here as the tasks will now be executing! Call the task
|
/* Should never get here as the tasks will now be executing! Call the task
|
||||||
exit error function to prevent compiler warnings about a static function
|
exit error function to prevent compiler warnings about a static function
|
||||||
not being called in the case that the application writer overrides this
|
not being called in the case that the application writer overrides this
|
||||||
functionality by defining configTASK_RETURN_ADDRESS. */
|
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
|
vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
|
symbol. */
|
||||||
|
vTaskSwitchContext();
|
||||||
prvTaskExitError();
|
prvTaskExitError();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
@ -342,20 +353,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the CM3 port will require this function as there
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
is nothing to return to. */
|
Artificially force an assert. */
|
||||||
}
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -363,13 +363,22 @@ void vPortEnterCritical( void )
|
|||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
|
assert() if it is being called from an interrupt context. Only API
|
||||||
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
|
assert function also uses a critical section. */
|
||||||
|
if( uxCriticalNesting == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
@ -378,37 +387,6 @@ void vPortExitCritical( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__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 )
|
void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
/* This is a naked function. */
|
/* This is a naked function. */
|
||||||
@ -416,6 +394,7 @@ void xPortPendSVHandler( void )
|
|||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
|
" isb \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
@ -430,14 +409,15 @@ void xPortPendSVHandler( void )
|
|||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" ldmia sp!, {r3, r14} \n"
|
" ldmia sp!, {r3, r14} \n"
|
||||||
" \n" /* Restore the context, including the critical nesting count. */
|
" \n" /* Restore the context, including the critical nesting count. */
|
||||||
" ldr r1, [r3] \n"
|
" ldr r1, [r3] \n"
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||||
" msr psp, r0 \n"
|
" msr psp, r0 \n"
|
||||||
|
" isb \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
@ -450,7 +430,7 @@ void xPortSysTickHandler( void )
|
|||||||
executes all interrupts must be unmasked. There is therefore no need to
|
executes all interrupts must be unmasked. There is therefore no need to
|
||||||
save and then restore the interrupt mask value as its value is already
|
save and then restore the interrupt mask value as its value is already
|
||||||
known. */
|
known. */
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
@ -460,16 +440,16 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
portTickType xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||||
@ -481,7 +461,7 @@ void xPortSysTickHandler( void )
|
|||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
@ -494,7 +474,9 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" );
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
to be unsuspended then abandon the low power entry. */
|
||||||
@ -505,7 +487,7 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
@ -513,7 +495,7 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__asm volatile( "cpsie i" );
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -525,7 +507,7 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
@ -536,28 +518,47 @@ void xPortSysTickHandler( void )
|
|||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" );
|
__asm volatile( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile( "isb" );
|
||||||
}
|
}
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Stop SysTick. Again, the time the SysTick is stopped for is
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
accounted for as best it can be, but using the tickless mode will
|
out of sleep mode to execute immediately. see comments above
|
||||||
inevitably result in some tiny drift of the time maintained by the
|
__disable_interrupt() call above. */
|
||||||
kernel with respect to calendar time. */
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
above. */
|
and interrupts that execute while the clock is stopped will increase
|
||||||
__asm volatile( "cpsie i" );
|
any slippage between the time maintained by the RTOS and calendar
|
||||||
|
time. */
|
||||||
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
|
/* Disable the SysTick clock without reading the
|
||||||
|
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
|
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. 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 );
|
||||||
|
|
||||||
|
/* Determine if the SysTick clock has already counted to zero and
|
||||||
|
been set back to the current reload value (the reload back being
|
||||||
|
correct for the entire expected idle time) or if the SysTick is yet
|
||||||
|
to count to zero (in which case an interrupt other than the SysTick
|
||||||
|
must have brought the system out of sleep mode). */
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
uint32_t ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
/* The tick interrupt is already pending, and the SysTick count
|
||||||
count reloaded with ulReloadValue. Reset the
|
reloaded with ulReloadValue. Reset the
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||||
period. */
|
period. */
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
@ -572,11 +573,9 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt handler will already have pended the tick
|
/* As the pending tick will be processed as soon as this
|
||||||
processing in the kernel. As the pending tick will be
|
function exits, the tick value maintained by the tick is stepped
|
||||||
processed as soon as this function exits, the tick value
|
forward by one less than the time spent waiting. */
|
||||||
maintained by the tick is stepped forward by one less than the
|
|
||||||
time spent waiting. */
|
|
||||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -593,26 +592,23 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
period remains. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
value. The critical section is used to ensure the tick interrupt
|
value. */
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
{
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
/* Exit with interrpts enabled. */
|
||||||
}
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -622,7 +618,7 @@ void xPortSysTickHandler( void )
|
|||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
@ -630,9 +626,13 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/* Stop and clear the SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -640,11 +640,11 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
unsigned long ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
unsigned char ucCurrentPriority;
|
uint8_t ucCurrentPriority;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
/* Is the interrupt number a user defined interrupt? */
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||||
@ -690,7 +690,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
scheduler. Note however that some vendor specific peripheral libraries
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
assume a non-zero priority group setting, in which cases using a value
|
||||||
of zero will result in unpredicable behaviour. */
|
of zero will result in unpredictable behaviour. */
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
@ -87,45 +50,60 @@ extern "C" {
|
|||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE unsigned portLONG
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef unsigned portSHORT portTickType;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef unsigned portLONG portTickType;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
#define portYIELD() \
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
{ \
|
||||||
|
/* Set a PendSV to request a context switch. */ \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
\
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely \
|
||||||
|
within the specified behaviour for the architecture. */ \
|
||||||
|
__asm volatile( "dsb" ::: "memory" ); \
|
||||||
|
__asm volatile( "isb" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMaskValue );
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
@ -137,20 +115,24 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline unsigned char ucPortCountLeadingZeros( unsigned long ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
unsigned char ucReturn;
|
uint8_t ucReturn;
|
||||||
|
|
||||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
return ucReturn;
|
return ucReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +147,7 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
@ -179,6 +161,80 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
|
#define portINLINE __inline
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrentInterrupt;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
|
if( ulCurrentInterrupt == 0 )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mov %0, %1 \n" \
|
||||||
|
" msr basepri, %0 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n" \
|
||||||
|
" mov %1, %2 \n" \
|
||||||
|
" msr basepri, %1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||||
@ -77,52 +40,70 @@
|
|||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
|
#else
|
||||||
|
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||||
|
as the core. */
|
||||||
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||||
|
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
r0p1 port. */
|
||||||
|
#define portCPUID ( * ( ( volatile uint32_t * ) 0xE000ed00 ) )
|
||||||
|
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
|
||||||
|
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
|
||||||
|
|
||||||
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
/* Constants required to check the validity of an interrupt priority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
#define portINITIAL_EXEC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
/* The systick is a 24-bit counter. */
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
|
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
occurred while the SysTick counter is stopped during tickless idle
|
||||||
calculations. */
|
calculations. */
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case is messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
@ -130,10 +111,6 @@ debugger. */
|
|||||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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
|
* 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
|
* file is weak to allow application writers to change the timer used to
|
||||||
@ -156,7 +133,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
|||||||
/*
|
/*
|
||||||
* Function to enable the VFP.
|
* Function to enable the VFP.
|
||||||
*/
|
*/
|
||||||
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
* Used to catch tasks that attempt to return from their implementing function.
|
||||||
@ -165,27 +142,31 @@ static void prvTaskExitError( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
|
variable. */
|
||||||
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of SysTick increments that make up one tick period.
|
* The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The maximum number of tick periods that can be suppressed is limited by the
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
* 24 bit resolution of the SysTick timer.
|
* 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
* power functionality only.
|
* power functionality only.
|
||||||
*/
|
*/
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static unsigned long ulStoppedTimerCompensation = 0;
|
static uint32_t ulStoppedTimerCompensation = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -193,10 +174,10 @@ static void prvTaskExitError( void );
|
|||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static uint8_t ucMaxSysCallPriority = 0;
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -204,7 +185,7 @@ static void prvTaskExitError( void );
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
interrupt. */
|
||||||
@ -215,18 +196,18 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||||||
|
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) portTASK_RETURN_ADDRESS; /* LR */
|
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||||
|
|
||||||
/* Save code space by skipping register initialisation. */
|
/* Save code space by skipping register initialisation. */
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
|
|
||||||
/* A save method is being used that requires each task to maintain its
|
/* A save method is being used that requires each task to maintain its
|
||||||
own exec return value. */
|
own exec return value. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_EXEC_RETURN;
|
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||||
|
|
||||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||||
|
|
||||||
@ -236,6 +217,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
|
volatile uint32_t ulDummy = 0;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
@ -244,7 +227,16 @@ static void prvTaskExitError( void )
|
|||||||
defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
while( ulDummy == 0 )
|
||||||
|
{
|
||||||
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
|
started to remove a compiler warning about the function being defined
|
||||||
|
but never called. ulDummy is used purely to quieten other warnings
|
||||||
|
about code appearing after this function is called - making ulDummy
|
||||||
|
volatile makes the compiler think the function could return and
|
||||||
|
therefore not output an 'unreachable code' warning for code that appears
|
||||||
|
after it. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -256,11 +248,12 @@ void vPortSVCHandler( void )
|
|||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" 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. */
|
" 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. */
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -268,12 +261,21 @@ void vPortSVCHandler( void )
|
|||||||
|
|
||||||
static void prvPortStartFirstTask( void )
|
static void prvPortStartFirstTask( void )
|
||||||
{
|
{
|
||||||
|
/* Start the first task. This also clears the bit that indicates the FPU is
|
||||||
|
in use in case the FPU was used before the scheduler was started - which
|
||||||
|
would otherwise result in the unnecessary leaving of space in the SVC stack
|
||||||
|
for lazy saving of FPU registers. */
|
||||||
__asm volatile(
|
__asm volatile(
|
||||||
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
|
" mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
|
||||||
|
" msr control, r0 \n"
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
);
|
);
|
||||||
@ -283,17 +285,23 @@ static void prvPortStartFirstTask( void )
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
/* This port can be used on all revisions of the Cortex-M7 core other than
|
||||||
|
the r0p1 parts. r0p1 parts should use the port from the
|
||||||
|
/source/portable/GCC/ARM_CM7/r0p1 directory. */
|
||||||
|
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||||
|
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
@ -301,14 +309,14 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
ensure interrupt entry is as fast and simple as possible.
|
ensure interrupt entry is as fast and simple as possible.
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
/* Determine the number of priority bits available. First write to all
|
||||||
possible bits. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
/* Use the same mask on the maximum system call priority. */
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
@ -319,9 +327,27 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulMaxPRIGROUPValue--;
|
ulMaxPRIGROUPValue--;
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __NVIC_PRIO_BITS
|
||||||
|
{
|
||||||
|
/* Check the CMSIS configuration that defines the number of
|
||||||
|
priority bits matches the number of priority bits actually queried
|
||||||
|
from the hardware. */
|
||||||
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef configPRIO_BITS
|
||||||
|
{
|
||||||
|
/* Check the FreeRTOS configuration that defines the number of
|
||||||
|
priority bits matches the number of priority bits actually queried
|
||||||
|
from the hardware. */
|
||||||
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
/* Shift the priority group value back to its position within the AIRCR
|
||||||
register. */
|
register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
@ -329,7 +355,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
||||||
@ -356,7 +382,10 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
/* Should never get here as the tasks will now be executing! Call the task
|
/* Should never get here as the tasks will now be executing! Call the task
|
||||||
exit error function to prevent compiler warnings about a static function
|
exit error function to prevent compiler warnings about a static function
|
||||||
not being called in the case that the application writer overrides this
|
not being called in the case that the application writer overrides this
|
||||||
functionality by defining configTASK_RETURN_ADDRESS. */
|
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
|
vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
|
symbol. */
|
||||||
|
vTaskSwitchContext();
|
||||||
prvTaskExitError();
|
prvTaskExitError();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
@ -366,20 +395,9 @@ portBASE_TYPE xPortStartScheduler( void )
|
|||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the CM4F port will require this function as there
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
is nothing to return to. */
|
Artificially force an assert. */
|
||||||
}
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -387,13 +405,22 @@ void vPortEnterCritical( void )
|
|||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
|
assert() if it is being called from an interrupt context. Only API
|
||||||
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
|
assert function also uses a critical section. */
|
||||||
|
if( uxCriticalNesting == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
@ -402,37 +429,6 @@ void vPortExitCritical( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__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 )
|
void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
/* This is a naked function. */
|
/* This is a naked function. */
|
||||||
@ -440,6 +436,7 @@ void xPortPendSVHandler( void )
|
|||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
|
" isb \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
@ -449,16 +446,17 @@ void xPortPendSVHandler( void )
|
|||||||
" vstmdbeq r0!, {s16-s31} \n"
|
" vstmdbeq r0!, {s16-s31} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
|
" 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. */
|
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" stmdb sp!, {r3} \n"
|
" stmdb sp!, {r0, r3} \n"
|
||||||
" mov r0, %0 \n"
|
" mov r0, %0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" ldmia sp!, {r3} \n"
|
" ldmia sp!, {r0, r3} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldr r0, [r1] \n"
|
" ldr r0, [r1] \n"
|
||||||
@ -470,6 +468,7 @@ void xPortPendSVHandler( void )
|
|||||||
" vldmiaeq r0!, {s16-s31} \n"
|
" vldmiaeq r0!, {s16-s31} \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr psp, r0 \n"
|
" msr psp, r0 \n"
|
||||||
|
" isb \n"
|
||||||
" \n"
|
" \n"
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
#if WORKAROUND_PMU_CM001 == 1
|
||||||
@ -480,7 +479,7 @@ void xPortPendSVHandler( void )
|
|||||||
" \n"
|
" \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 2 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
@ -493,7 +492,7 @@ void xPortSysTickHandler( void )
|
|||||||
executes all interrupts must be unmasked. There is therefore no need to
|
executes all interrupts must be unmasked. There is therefore no need to
|
||||||
save and then restore the interrupt mask value as its value is already
|
save and then restore the interrupt mask value as its value is already
|
||||||
known. */
|
known. */
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
@ -503,16 +502,16 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
portTickType xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||||
@ -524,7 +523,7 @@ void xPortSysTickHandler( void )
|
|||||||
is accounted for as best it can be, but using the tickless mode will
|
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
|
inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
tick periods. -1 is used because this code will execute part way
|
||||||
@ -537,7 +536,9 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" );
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
to be unsuspended then abandon the low power entry. */
|
||||||
@ -548,7 +549,7 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
periods. */
|
||||||
@ -556,7 +557,7 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__asm volatile( "cpsie i" );
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -568,7 +569,7 @@ void xPortSysTickHandler( void )
|
|||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
set its parameter to 0 to indicate that its implementation contains
|
||||||
@ -579,28 +580,47 @@ void xPortSysTickHandler( void )
|
|||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" );
|
__asm volatile( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile( "isb" );
|
||||||
}
|
}
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Stop SysTick. Again, the time the SysTick is stopped for is
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
accounted for as best it can be, but using the tickless mode will
|
out of sleep mode to execute immediately. see comments above
|
||||||
inevitably result in some tiny drift of the time maintained by the
|
__disable_interrupt() call above. */
|
||||||
kernel with respect to calendar time. */
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
above. */
|
and interrupts that execute while the clock is stopped will increase
|
||||||
__asm volatile( "cpsie i" );
|
any slippage between the time maintained by the RTOS and calendar
|
||||||
|
time. */
|
||||||
|
__asm volatile( "cpsid i" ::: "memory" );
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
|
/* Disable the SysTick clock without reading the
|
||||||
|
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
|
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. 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 );
|
||||||
|
|
||||||
|
/* Determine if the SysTick clock has already counted to zero and
|
||||||
|
been set back to the current reload value (the reload back being
|
||||||
|
correct for the entire expected idle time) or if the SysTick is yet
|
||||||
|
to count to zero (in which case an interrupt other than the SysTick
|
||||||
|
must have brought the system out of sleep mode). */
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
unsigned long ulCalculatedLoadValue;
|
uint32_t ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
/* The tick interrupt is already pending, and the SysTick count
|
||||||
count reloaded with ulReloadValue. Reset the
|
reloaded with ulReloadValue. Reset the
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||||
period. */
|
period. */
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
@ -615,11 +635,9 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt handler will already have pended the tick
|
/* As the pending tick will be processed as soon as this
|
||||||
processing in the kernel. As the pending tick will be
|
function exits, the tick value maintained by the tick is stepped
|
||||||
processed as soon as this function exits, the tick value
|
forward by one less than the time spent waiting. */
|
||||||
maintained by the tick is stepped forward by one less than the
|
|
||||||
time spent waiting. */
|
|
||||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -636,22 +654,19 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
period remains. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
value. The critical section is used to ensure the tick interrupt
|
value. */
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portENTER_CRITICAL();
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
{
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
/* Exit with interrpts enabled. */
|
||||||
}
|
__asm volatile( "cpsie i" ::: "memory" );
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,7 +680,7 @@ void xPortSysTickHandler( void )
|
|||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
@ -673,9 +688,13 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
/* Stop and clear the SysTick. */
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||||
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
|
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;
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -698,11 +717,11 @@ static void vPortEnableVFP( void )
|
|||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
unsigned long ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
unsigned char ucCurrentPriority;
|
uint8_t ucCurrentPriority;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
/* Is the interrupt number a user defined interrupt? */
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||||
@ -748,7 +767,7 @@ static void vPortEnableVFP( void )
|
|||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
scheduler. Note however that some vendor specific peripheral libraries
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
assume a non-zero priority group setting, in which cases using a value
|
||||||
of zero will result in unpredicable behaviour. */
|
of zero will result in unpredictable behaviour. */
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,67 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
@ -87,43 +50,57 @@ extern "C" {
|
|||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE unsigned portLONG
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef unsigned portSHORT portTickType;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef unsigned portLONG portTickType;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
#define portYIELD() \
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
{ \
|
||||||
|
/* Set a PendSV to request a context switch. */ \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
\
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely \
|
||||||
|
within the specified behaviour for the architecture. */ \
|
||||||
|
__asm volatile( "dsb" ::: "memory" ); \
|
||||||
|
__asm volatile( "isb" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMaskValue );
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
@ -138,20 +115,24 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline unsigned char ucPortCountLeadingZeros( unsigned long ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
unsigned char ucReturn;
|
uint8_t ucReturn;
|
||||||
|
|
||||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
return ucReturn;
|
return ucReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +147,7 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
@ -180,6 +161,80 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
|
#define portINLINE __inline
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrentInterrupt;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
|
if( ulCurrentInterrupt == 0 )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mov %0, %1 \n" \
|
||||||
|
" msr basepri, %0 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n" \
|
||||||
|
" mov %1, %2 \n" \
|
||||||
|
" msr basepri, %1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,249 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* IAR includes. */
|
|
||||||
#include "intrinsics.h"
|
|
||||||
|
|
||||||
/* 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_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
|
|
||||||
#define portNVIC_SYSTICK_CLK 0x00000004
|
|
||||||
#define portNVIC_SYSTICK_INT 0x00000002
|
|
||||||
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
|
||||||
#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 )
|
|
||||||
|
|
||||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
|
||||||
defined. The value 255 should also ensure backward compatibility.
|
|
||||||
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
|
|
||||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
static void prvSetupTimerInterrupt( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exception handlers.
|
|
||||||
*/
|
|
||||||
void xPortSysTickHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
extern void vPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* LR */
|
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
|
||||||
pxTopOfStack -= 8; /* R11..R4. */
|
|
||||||
|
|
||||||
return pxTopOfStack;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
||||||
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
|
|
||||||
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
|
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
|
||||||
here already. */
|
|
||||||
prvSetupTimerInterrupt();
|
|
||||||
|
|
||||||
/* 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 vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
unsigned long ulPreviousMask;
|
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* Pend a context switch. */
|
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the systick timer to generate the tick interrupts at the required
|
|
||||||
* frequency.
|
|
||||||
*/
|
|
||||||
static 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <FreeRTOSConfig.h>
|
|
||||||
|
|
||||||
RSEG CODE:CODE(2)
|
|
||||||
thumb
|
|
||||||
|
|
||||||
EXTERN vPortYieldFromISR
|
|
||||||
EXTERN pxCurrentTCB
|
|
||||||
EXTERN vTaskSwitchContext
|
|
||||||
|
|
||||||
PUBLIC vSetMSP
|
|
||||||
PUBLIC xPortPendSVHandler
|
|
||||||
PUBLIC vPortSVCHandler
|
|
||||||
PUBLIC vPortStartFirstTask
|
|
||||||
PUBLIC ulSetInterruptMaskFromISR
|
|
||||||
PUBLIC vClearInterruptMaskFromISR
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vSetMSP
|
|
||||||
msr msp, r0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
xPortPendSVHandler:
|
|
||||||
mrs r0, psp
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
subs r0, r0, #32 /* Make space for the remaining low registers. */
|
|
||||||
str r0, [r2] /* Save the new top of stack. */
|
|
||||||
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
|
|
||||||
mov r4, r8 /* Store the high registers. */
|
|
||||||
mov r5, r9
|
|
||||||
mov r6, r10
|
|
||||||
mov r7, r11
|
|
||||||
stmia r0!, {r4-r7}
|
|
||||||
|
|
||||||
push {r3, r14}
|
|
||||||
cpsid i
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
cpsie i
|
|
||||||
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */
|
|
||||||
|
|
||||||
ldr r1, [r2]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
adds r0, r0, #16 /* Move to the high registers. */
|
|
||||||
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
|
||||||
mov r8, r4
|
|
||||||
mov r9, r5
|
|
||||||
mov r10, r6
|
|
||||||
mov r11, r7
|
|
||||||
|
|
||||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
|
||||||
|
|
||||||
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */
|
|
||||||
ldmia r0!, {r4-r7} /* Pop low registers. */
|
|
||||||
|
|
||||||
bx r3
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortSVCHandler;
|
|
||||||
/* This function is no longer used, but retained for backward
|
|
||||||
compatibility. */
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortStartFirstTask
|
|
||||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
|
||||||
table offset register that can be used to locate the initial stack value.
|
|
||||||
Not all M0 parts have the application vector table at address 0. */
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
adds r0, #32 /* Discard everything up to r0. */
|
|
||||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
|
||||||
movs r0, #2 /* Switch to the psp stack. */
|
|
||||||
msr CONTROL, r0
|
|
||||||
pop {r0-r5} /* Pop the registers that are saved automatically. */
|
|
||||||
mov lr, r5 /* lr is now in r5. */
|
|
||||||
cpsie i /* The first task has its context and interrupts can be enabled. */
|
|
||||||
pop {pc} /* Finally, pop the PC to jump to the user defined task code. */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
ulSetInterruptMaskFromISR
|
|
||||||
mrs r0, PRIMASK
|
|
||||||
cpsid i
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vClearInterruptMaskFromISR
|
|
||||||
msr PRIMASK, r0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
END
|
|
@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
|
|
||||||
#define portNVIC_PENDSVSET 0x10000000
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
extern unsigned long ulSetInterruptMaskFromISR( void );
|
|
||||||
extern void vClearInterruptMaskFromISR( unsigned long ulMask );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile( "cpsid i" )
|
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile( "cpsie i" )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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()
|
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
|
||||||
the source code because to do so would cause other compilers to generate
|
|
||||||
warnings. */
|
|
||||||
#pragma diag_suppress=Pa082
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
|
||||||
|
|
@ -1,605 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* IAR includes. */
|
|
||||||
#include <intrinsics.h>
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
|
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
|
||||||
#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_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_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 check the validity of an interrupt priority. */
|
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
|
||||||
calculations. */
|
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
||||||
|
|
||||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
|
||||||
defined. The value 255 should also ensure backward compatibility.
|
|
||||||
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
|
|
||||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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 xPortSysTickHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
extern void vPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of SysTick increments that make up one tick period.
|
|
||||||
*/
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
*/
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
{
|
|
||||||
volatile unsigned long ulOriginalPriority;
|
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
|
||||||
functions can be called. ISR safe functions are those that end in
|
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
possible bits. */
|
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
|
||||||
of bits read back. */
|
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
||||||
{
|
|
||||||
ulMaxPRIGROUPValue--;
|
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
|
||||||
register. */
|
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
value. */
|
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
|
||||||
}
|
|
||||||
#endif /* conifgASSERT_DEFINED */
|
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
||||||
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. */
|
|
||||||
vPortStartFirstTask();
|
|
||||||
|
|
||||||
/* 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 vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
|
||||||
save and then restore the interrupt mask value as its value is already
|
|
||||||
known. */
|
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* A context switch is required. Context switching is performed in
|
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
|
||||||
{
|
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
|
||||||
portTickType xModifiableIdleTime;
|
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
|
||||||
{
|
|
||||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
|
||||||
{
|
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
|
||||||
__disable_interrupt();
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
|
||||||
to be unsuspended then abandon the low power entry. */
|
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
|
||||||
{
|
|
||||||
/* Restart from whatever is left in the count register to complete
|
|
||||||
this tick period. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* Restart SysTick. */
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
|
||||||
periods. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
|
||||||
call above. */
|
|
||||||
__enable_interrupt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the new reload value. */
|
|
||||||
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() can
|
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
|
||||||
should not be executed again. However, the original expected idle
|
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
|
||||||
if( xModifiableIdleTime > 0 )
|
|
||||||
{
|
|
||||||
__DSB();
|
|
||||||
__WFI();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
|
||||||
call above. */
|
|
||||||
__enable_interrupt();
|
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
|
||||||
{
|
|
||||||
unsigned long ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
|
||||||
count reloaded with ulReloadValue. Reset the
|
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
|
||||||
period. */
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
|
||||||
underflowed because the post sleep hook did something
|
|
||||||
that took too long. */
|
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
|
||||||
{
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
|
||||||
}
|
|
||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* 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 rounded to complete tick
|
|
||||||
periods (not the ulReload value which accounted for part
|
|
||||||
ticks). */
|
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
|
||||||
was waiting? */
|
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
|
||||||
period remains. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
|
||||||
value. The critical section is used to ensure the tick interrupt
|
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the systick timer to generate the tick interrupts at the required
|
|
||||||
* frequency.
|
|
||||||
*/
|
|
||||||
__weak void vPortSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
{
|
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
|
||||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
|
||||||
{
|
|
||||||
unsigned long ulCurrentInterrupt;
|
|
||||||
unsigned char ucCurrentPriority;
|
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
|
||||||
{
|
|
||||||
/* Look up the interrupt's priority. */
|
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
|
||||||
an interrupt that has been assigned a priority above
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
|
||||||
from interrupts that have been assigned a priority at or below
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Numerically low interrupt priority numbers represent logically high
|
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
|
||||||
be set to a value equal to or numerically *higher* than
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
|
||||||
default priority of zero as that is the highest possible priority,
|
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
|
||||||
and therefore also guaranteed to be invalid.
|
|
||||||
|
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
|
||||||
interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
The following links provide detailed information:
|
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
|
||||||
http://www.freertos.org/FAQHelp.html */
|
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
|
||||||
that define each interrupt's priority to be split between bits that
|
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
|
||||||
this is not the case (if some bits represent a sub-priority).
|
|
||||||
|
|
||||||
If the application only uses CMSIS libraries for interrupt
|
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
|
||||||
of zero will result in unpredicable behaviour. */
|
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <FreeRTOSConfig.h>
|
|
||||||
|
|
||||||
RSEG CODE:CODE(2)
|
|
||||||
thumb
|
|
||||||
|
|
||||||
EXTERN pxCurrentTCB
|
|
||||||
EXTERN vTaskSwitchContext
|
|
||||||
|
|
||||||
PUBLIC xPortPendSVHandler
|
|
||||||
PUBLIC ulPortSetInterruptMask
|
|
||||||
PUBLIC vPortClearInterruptMask
|
|
||||||
PUBLIC vPortSVCHandler
|
|
||||||
PUBLIC vPortStartFirstTask
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
xPortPendSVHandler:
|
|
||||||
mrs r0, psp
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
stmdb r0!, {r4-r11} /* Save the remaining registers. */
|
|
||||||
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
|
|
||||||
|
|
||||||
stmdb sp!, {r3, r14}
|
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r0
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
ldmia sp!, {r3, r14}
|
|
||||||
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers. */
|
|
||||||
msr psp, r0
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
ulPortSetInterruptMask:
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortClearInterruptMask:
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortSVCHandler:
|
|
||||||
/* Get the location of the current TCB. */
|
|
||||||
ldr r3, =pxCurrentTCB
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1]
|
|
||||||
/* Pop the core registers. */
|
|
||||||
ldmia r0!, {r4-r11}
|
|
||||||
msr psp, r0
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
orr r14, r14, #13
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortStartFirstTask
|
|
||||||
/* Use the NVIC offset register to locate the stack. */
|
|
||||||
ldr r0, =0xE000ED08
|
|
||||||
ldr r0, [r0]
|
|
||||||
ldr r0, [r0]
|
|
||||||
/* Set the msp back to the start of the stack. */
|
|
||||||
msr msp, r0
|
|
||||||
/* Call SVC to start the first task. */
|
|
||||||
cpsie i
|
|
||||||
svc 0
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 0xffff
|
|
||||||
#else
|
|
||||||
typedef unsigned portLONG portTickType;
|
|
||||||
#define portMAX_DELAY 0xffffffffUL
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Architecture specifics. */
|
|
||||||
#define portSTACK_GROWTH ( -1 )
|
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
|
||||||
#define portBYTE_ALIGNMENT 8
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
|
||||||
extern void vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04UL ) )
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
|
||||||
|
|
||||||
/* 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 ) ) )
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include <intrinsics.h>
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( ( uxReadyPriorities ) ) )
|
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMask );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef configASSERT
|
|
||||||
void vPortValidateInterruptPriority( void );
|
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
|
||||||
#define portNOP()
|
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
|
||||||
the source code because to do so would cause other compilers to generate
|
|
||||||
warnings. */
|
|
||||||
#pragma diag_suppress=Pe191
|
|
||||||
#pragma diag_suppress=Pa082
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
|
||||||
|
|
@ -1,631 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Compiler includes. */
|
|
||||||
#include <intrinsics.h>
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#ifndef __ARMVFP__
|
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
|
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
|
||||||
#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_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_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 check the validity of an interrupt priority. */
|
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
|
||||||
|
|
||||||
/* 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 systick is a 24-bit counter. */
|
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
|
||||||
calculations. */
|
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
||||||
|
|
||||||
|
|
||||||
/* 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 xPortSysTickHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
extern void vPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Turn the VFP on.
|
|
||||||
*/
|
|
||||||
extern void vPortEnableVFP( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of SysTick increments that make up one tick period.
|
|
||||||
*/
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
*/
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
{
|
|
||||||
volatile unsigned long ulOriginalPriority;
|
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
|
||||||
functions can be called. ISR safe functions are those that end in
|
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
possible bits. */
|
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
|
||||||
of bits read back. */
|
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
||||||
{
|
|
||||||
ulMaxPRIGROUPValue--;
|
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
|
||||||
register. */
|
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
value. */
|
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
|
||||||
}
|
|
||||||
#endif /* conifgASSERT_DEFINED */
|
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
||||||
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. */
|
|
||||||
vPortStartFirstTask();
|
|
||||||
|
|
||||||
/* 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 vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
|
||||||
save and then restore the interrupt mask value as its value is already
|
|
||||||
known. */
|
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* A context switch is required. Context switching is performed in
|
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
|
||||||
{
|
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
|
||||||
portTickType xModifiableIdleTime;
|
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
|
||||||
{
|
|
||||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
|
||||||
{
|
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
|
||||||
__disable_interrupt();
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
|
||||||
to be unsuspended then abandon the low power entry. */
|
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
|
||||||
{
|
|
||||||
/* Restart from whatever is left in the count register to complete
|
|
||||||
this tick period. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* Restart SysTick. */
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
|
||||||
periods. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
|
||||||
call above. */
|
|
||||||
__enable_interrupt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the new reload value. */
|
|
||||||
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() can
|
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
|
||||||
should not be executed again. However, the original expected idle
|
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
|
||||||
if( xModifiableIdleTime > 0 )
|
|
||||||
{
|
|
||||||
__DSB();
|
|
||||||
__WFI();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
|
||||||
call above. */
|
|
||||||
__enable_interrupt();
|
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
|
||||||
{
|
|
||||||
unsigned long ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
|
||||||
count reloaded with ulReloadValue. Reset the
|
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
|
||||||
period. */
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
|
||||||
underflowed because the post sleep hook did something
|
|
||||||
that took too long. */
|
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
|
||||||
{
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
|
||||||
}
|
|
||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* 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 rounded to complete tick
|
|
||||||
periods (not the ulReload value which accounted for part
|
|
||||||
ticks). */
|
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
|
||||||
was waiting? */
|
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
|
||||||
period remains. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
|
||||||
value. The critical section is used to ensure the tick interrupt
|
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the systick timer to generate the tick interrupts at the required
|
|
||||||
* frequency.
|
|
||||||
*/
|
|
||||||
__weak void vPortSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
{
|
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
|
||||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
|
||||||
{
|
|
||||||
unsigned long ulCurrentInterrupt;
|
|
||||||
unsigned char ucCurrentPriority;
|
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
|
||||||
{
|
|
||||||
/* Look up the interrupt's priority. */
|
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
|
||||||
an interrupt that has been assigned a priority above
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
|
||||||
from interrupts that have been assigned a priority at or below
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Numerically low interrupt priority numbers represent logically high
|
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
|
||||||
be set to a value equal to or numerically *higher* than
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
|
||||||
default priority of zero as that is the highest possible priority,
|
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
|
||||||
and therefore also guaranteed to be invalid.
|
|
||||||
|
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
|
||||||
interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
The following links provide detailed information:
|
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
|
||||||
http://www.freertos.org/FAQHelp.html */
|
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
|
||||||
that define each interrupt's priority to be split between bits that
|
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
|
||||||
this is not the case (if some bits represent a sub-priority).
|
|
||||||
|
|
||||||
If the application only uses CMSIS libraries for interrupt
|
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
|
||||||
of zero will result in unpredicable behaviour. */
|
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <FreeRTOSConfig.h>
|
|
||||||
|
|
||||||
RSEG CODE:CODE(2)
|
|
||||||
thumb
|
|
||||||
|
|
||||||
EXTERN pxCurrentTCB
|
|
||||||
EXTERN vTaskSwitchContext
|
|
||||||
|
|
||||||
PUBLIC xPortPendSVHandler
|
|
||||||
PUBLIC ulPortSetInterruptMask
|
|
||||||
PUBLIC vPortClearInterruptMask
|
|
||||||
PUBLIC vPortSVCHandler
|
|
||||||
PUBLIC vPortStartFirstTask
|
|
||||||
PUBLIC vPortEnableVFP
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
xPortPendSVHandler:
|
|
||||||
mrs r0, psp
|
|
||||||
|
|
||||||
/* Get the location of the current TCB. */
|
|
||||||
ldr r3, =pxCurrentTCB
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
/* Is the task using the FPU context? If so, push high vfp registers. */
|
|
||||||
tst r14, #0x10
|
|
||||||
it eq
|
|
||||||
vstmdbeq r0!, {s16-s31}
|
|
||||||
|
|
||||||
/* Save the core registers. */
|
|
||||||
stmdb r0!, {r4-r11, r14}
|
|
||||||
|
|
||||||
/* Save the new top of stack into the first member of the TCB. */
|
|
||||||
str r0, [r2]
|
|
||||||
|
|
||||||
stmdb sp!, {r3}
|
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r0
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
ldmia sp!, {r3}
|
|
||||||
|
|
||||||
/* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1]
|
|
||||||
|
|
||||||
/* Pop the core registers. */
|
|
||||||
ldmia r0!, {r4-r11, r14}
|
|
||||||
|
|
||||||
/* Is the task using the FPU context? If so, pop the high vfp registers
|
|
||||||
too. */
|
|
||||||
tst r14, #0x10
|
|
||||||
it eq
|
|
||||||
vldmiaeq r0!, {s16-s31}
|
|
||||||
|
|
||||||
msr psp, r0
|
|
||||||
|
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
|
||||||
push { r14 }
|
|
||||||
pop { pc }
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
ulPortSetInterruptMask:
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortClearInterruptMask:
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortSVCHandler:
|
|
||||||
/* Get the location of the current TCB. */
|
|
||||||
ldr r3, =pxCurrentTCB
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1]
|
|
||||||
/* Pop the core registers. */
|
|
||||||
ldmia r0!, {r4-r11, r14}
|
|
||||||
msr psp, r0
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortStartFirstTask
|
|
||||||
/* Use the NVIC offset register to locate the stack. */
|
|
||||||
ldr r0, =0xE000ED08
|
|
||||||
ldr r0, [r0]
|
|
||||||
ldr r0, [r0]
|
|
||||||
/* Set the msp back to the start of the stack. */
|
|
||||||
msr msp, r0
|
|
||||||
/* Call SVC to start the first task. */
|
|
||||||
cpsie i
|
|
||||||
svc 0
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortEnableVFP:
|
|
||||||
/* The FPU enable bits are in the CPACR. */
|
|
||||||
ldr.w r0, =0xE000ED88
|
|
||||||
ldr r1, [r0]
|
|
||||||
|
|
||||||
/* Enable CP10 and CP11 coprocessors, then save back. */
|
|
||||||
orr r1, r1, #( 0xf << 20 )
|
|
||||||
str r1, [r0]
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
|
||||||
|
|
||||||
/* 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 ) )
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include <intrinsics.h>
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( ( uxReadyPriorities ) ) )
|
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMask );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef configASSERT
|
|
||||||
void vPortValidateInterruptPriority( void );
|
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
|
||||||
#define portNOP()
|
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
|
||||||
the source code because to do so would cause other compilers to generate
|
|
||||||
warnings. */
|
|
||||||
#pragma diag_suppress=Pe191
|
|
||||||
#pragma diag_suppress=Pa082
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
|||||||
;/*
|
|
||||||
; FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
; All rights reserved
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; ***************************************************************************
|
|
||||||
; * *
|
|
||||||
; * 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.
|
|
||||||
;*/
|
|
||||||
EXTERN pxCurrentTCB
|
|
||||||
EXTERN ulCriticalNesting
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Context save and restore macro definitions
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
portSAVE_CONTEXT MACRO
|
|
||||||
|
|
||||||
; Push R0 as we are going to use the register.
|
|
||||||
STMDB SP!, {R0}
|
|
||||||
|
|
||||||
; Set R0 to point to the task stack pointer.
|
|
||||||
STMDB SP, {SP}^
|
|
||||||
NOP
|
|
||||||
SUB SP, SP, #4
|
|
||||||
LDMIA SP!, {R0}
|
|
||||||
|
|
||||||
; Push the return address onto the stack.
|
|
||||||
STMDB R0!, {LR}
|
|
||||||
|
|
||||||
; Now we have saved LR we can use it instead of R0.
|
|
||||||
MOV LR, R0
|
|
||||||
|
|
||||||
; Pop R0 so we can save it onto the system mode stack.
|
|
||||||
LDMIA SP!, {R0}
|
|
||||||
|
|
||||||
; Push all the system mode registers onto the task stack.
|
|
||||||
STMDB LR, {R0-LR}^
|
|
||||||
NOP
|
|
||||||
SUB LR, LR, #60
|
|
||||||
|
|
||||||
; Push the SPSR onto the task stack.
|
|
||||||
MRS R0, SPSR
|
|
||||||
STMDB LR!, {R0}
|
|
||||||
|
|
||||||
LDR R0, =ulCriticalNesting
|
|
||||||
LDR R0, [R0]
|
|
||||||
STMDB LR!, {R0}
|
|
||||||
|
|
||||||
; Store the new top of stack for the task.
|
|
||||||
LDR R1, =pxCurrentTCB
|
|
||||||
LDR R0, [R1]
|
|
||||||
STR LR, [R0]
|
|
||||||
|
|
||||||
ENDM
|
|
||||||
|
|
||||||
|
|
||||||
portRESTORE_CONTEXT MACRO
|
|
||||||
|
|
||||||
; Set the LR to the task stack.
|
|
||||||
LDR R1, =pxCurrentTCB
|
|
||||||
LDR R0, [R1]
|
|
||||||
LDR LR, [R0]
|
|
||||||
|
|
||||||
; The critical nesting depth is the first item on the stack.
|
|
||||||
; Load it into the ulCriticalNesting variable.
|
|
||||||
LDR R0, =ulCriticalNesting
|
|
||||||
LDMFD LR!, {R1}
|
|
||||||
STR R1, [R0]
|
|
||||||
|
|
||||||
; Get the SPSR from the stack.
|
|
||||||
LDMFD LR!, {R0}
|
|
||||||
MSR SPSR_cxsf, R0
|
|
||||||
|
|
||||||
; Restore all system mode registers for the task.
|
|
||||||
LDMFD LR, {R0-R14}^
|
|
||||||
NOP
|
|
||||||
|
|
||||||
; 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
|
|
||||||
|
|
@ -1,355 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the Philips ARM7 port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Changes from V3.2.2
|
|
||||||
|
|
||||||
+ Bug fix - The prescale value for the timer setup is now written to T0PR
|
|
||||||
instead of T0PC. This bug would have had no effect unless a prescale
|
|
||||||
value was actually used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Standard includes. */
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <intrinsics.h>
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
/* 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 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 setup the PIT. */
|
|
||||||
#define portPIT_CLOCK_DIVISOR ( ( unsigned long ) 16 )
|
|
||||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
|
|
||||||
|
|
||||||
#define portINT_LEVEL_SENSITIVE 0
|
|
||||||
#define portPIT_ENABLE ( ( unsigned short ) 0x1 << 24 )
|
|
||||||
#define portPIT_INT_ENABLE ( ( unsigned short ) 0x1 << 25 )
|
|
||||||
|
|
||||||
/* 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 PIT to generate the tick interrupts. */
|
|
||||||
static void prvSetupTimerInterrupt( void );
|
|
||||||
|
|
||||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
|
||||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
|
||||||
during the kernel initialisation process. */
|
|
||||||
unsigned long ulCriticalNesting = ( unsigned long ) 9999;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00UL )
|
|
||||||
{
|
|
||||||
/* We want the task to start in thumb mode. */
|
|
||||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 vPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
|
||||||
here already. */
|
|
||||||
prvSetupTimerInterrupt();
|
|
||||||
|
|
||||||
/* Start the first task. */
|
|
||||||
vPortStartFirstTask();
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
|
||||||
simply increment the system tick. */
|
|
||||||
static __arm __irq void vPortNonPreemptiveTick( void );
|
|
||||||
static __arm __irq void vPortNonPreemptiveTick( void )
|
|
||||||
{
|
|
||||||
/* 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. */
|
|
||||||
xTaskIncrementTick();
|
|
||||||
|
|
||||||
/* Ready for the next interrupt. */
|
|
||||||
T0IR = portTIMER_MATCH_ISR_BIT;
|
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* This function is called from an asm wrapper, so does not require the __irq
|
|
||||||
keyword. */
|
|
||||||
void vPortPreemptiveTick( void );
|
|
||||||
void vPortPreemptiveTick( void )
|
|
||||||
{
|
|
||||||
/* Increment the tick counter. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* The new tick value might unblock a task. Ensure the highest task that
|
|
||||||
is ready to execute is the task that will execute when the tick ISR
|
|
||||||
exits. */
|
|
||||||
vTaskSwitchContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ready for the next interrupt. */
|
|
||||||
T0IR = portTIMER_MATCH_ISR_BIT;
|
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
unsigned long ulCompareMatch;
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
T0MR0 = ulCompareMatch;
|
|
||||||
|
|
||||||
/* Generate tick with timer 0 compare match. */
|
|
||||||
T0MCR = 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. */
|
|
||||||
#if configUSE_PREEMPTION == 1
|
|
||||||
{
|
|
||||||
extern void ( vPortPreemptiveTickEntry )( void );
|
|
||||||
|
|
||||||
VICVectAddr0 = ( unsigned long ) vPortPreemptiveTickEntry;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
extern void ( vNonPreemptiveTick )( void );
|
|
||||||
|
|
||||||
VICVectAddr0 = ( long ) vPortNonPreemptiveTick;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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. */
|
|
||||||
T0TCR = portENABLE_TIMER;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
/* Disable interrupts first! */
|
|
||||||
__disable_interrupt();
|
|
||||||
|
|
||||||
/* 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_interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
|||||||
;/*
|
|
||||||
; FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
; All rights reserved
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; ***************************************************************************
|
|
||||||
; * *
|
|
||||||
; * 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.
|
|
||||||
;*/
|
|
||||||
RSEG ICODE:CODE
|
|
||||||
CODE32
|
|
||||||
|
|
||||||
EXTERN vTaskSwitchContext
|
|
||||||
EXTERN vPortPreemptiveTick
|
|
||||||
|
|
||||||
PUBLIC vPortPreemptiveTickEntry
|
|
||||||
PUBLIC vPortYieldProcessor
|
|
||||||
PUBLIC vPortStartFirstTask
|
|
||||||
|
|
||||||
#include "FreeRTOSConfig.h"
|
|
||||||
#include "ISR_Support.h"
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Starting the first task is just a matter of restoring the context that
|
|
||||||
; was created by pxPortInitialiseStack().
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
vPortStartFirstTask:
|
|
||||||
portRESTORE_CONTEXT
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Manual context switch function. This is the SWI hander.
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
vPortYieldProcessor:
|
|
||||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
|
||||||
; as if the context was saved during and IRQ
|
|
||||||
; handler.
|
|
||||||
|
|
||||||
portSAVE_CONTEXT ; Save the context of the current task...
|
|
||||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
|
||||||
mov lr, pc
|
|
||||||
BX R0
|
|
||||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Preemptive context switch function. This will only ever get installed if
|
|
||||||
; portUSE_PREEMPTION is set to 1 in portmacro.h.
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
vPortPreemptiveTickEntry:
|
|
||||||
#if configUSE_PREEMPTION == 1
|
|
||||||
portSAVE_CONTEXT ; Save the context of the current task...
|
|
||||||
LDR R0, =vPortPreemptiveTick; before selecting the next task to execute.
|
|
||||||
mov lr, pc
|
|
||||||
BX R0
|
|
||||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
|
||||||
#define PORTMACRO_H
|
|
||||||
|
|
||||||
#include <intrinsics.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
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Hardware specifics. */
|
|
||||||
#define portSTACK_GROWTH ( -1 )
|
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
|
||||||
#define portBYTE_ALIGNMENT 8
|
|
||||||
#define portYIELD() asm ( "SWI 0" )
|
|
||||||
#define portNOP() asm ( "NOP" )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section handling. */
|
|
||||||
__arm __interwork void vPortDisableInterruptsFromThumb( void );
|
|
||||||
__arm __interwork void vPortEnableInterruptsFromThumb( void );
|
|
||||||
__arm __interwork void vPortEnterCritical( void );
|
|
||||||
__arm __interwork void vPortExitCritical( void );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
|
||||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Task utilities. */
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
|
||||||
{ \
|
|
||||||
extern void vTaskSwitchContext( void ); \
|
|
||||||
\
|
|
||||||
if( xSwitchRequired ) \
|
|
||||||
{ \
|
|
||||||
vTaskSwitchContext(); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
|
|
5
vendor/freertos/freertos/Source/portable/MemMang/ReadMe.url
vendored
Normal file
5
vendor/freertos/freertos/Source/portable/MemMang/ReadMe.url
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,2
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=http://www.freertos.org/a00111.html
|
||||||
|
IDList=
|
@ -1,74 +1,37 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
* FreeRTOS Kernel V10.0.0
|
||||||
All rights reserved
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
***************************************************************************
|
* the Software without restriction, including without limitation the rights to
|
||||||
* *
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* subject to the following conditions:
|
||||||
* platform software that has become a de facto standard. *
|
*
|
||||||
* *
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
*
|
||||||
* *
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* Thank you! *
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* *
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
***************************************************************************
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
This file is part of the FreeRTOS distribution.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* http://www.FreeRTOS.org
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* http://aws.amazon.com/freertos
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
>>! 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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A sample implementation of pvPortMalloc() and vPortFree() that combines
|
* A sample implementation of pvPortMalloc() and vPortFree() that combines
|
||||||
* (coalescences) adjacent memory blocks as they are freed, and in so doing
|
* (coalescences) adjacent memory blocks as they are freed, and in so doing
|
||||||
* limits memory fragmentation.
|
* limits memory fragmentation.
|
||||||
*
|
*
|
||||||
* See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
|
* See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
|
||||||
* memory management pages of http://www.FreeRTOS.org for more information.
|
* memory management pages of http://www.FreeRTOS.org for more information.
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -83,17 +46,24 @@ task.h is included from an application file. */
|
|||||||
|
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||||
|
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Block sizes must not get too small. */
|
/* Block sizes must not get too small. */
|
||||||
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
|
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||||
|
|
||||||
/* Assumes 8bit bytes! */
|
/* Assumes 8bit bytes! */
|
||||||
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
|
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
/* A few bytes might be lost to byte aligning the heap start address. */
|
|
||||||
#define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
|
|
||||||
|
|
||||||
/* Allocate the memory for the heap. */
|
/* Allocate the memory for the heap. */
|
||||||
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
|
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||||
|
/* The application writer has already defined the array used for the RTOS
|
||||||
|
heap - probably so it can be placed in a special segment or address. */
|
||||||
|
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
|
||||||
|
#else
|
||||||
|
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
|
||||||
|
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
|
||||||
/* Define the linked list structure. This is used to link free blocks in order
|
/* Define the linked list structure. This is used to link free blocks in order
|
||||||
of their memory address. */
|
of their memory address. */
|
||||||
@ -101,17 +71,17 @@ typedef struct A_BLOCK_LINK
|
|||||||
{
|
{
|
||||||
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
|
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
|
||||||
size_t xBlockSize; /*<< The size of the free block. */
|
size_t xBlockSize; /*<< The size of the free block. */
|
||||||
} xBlockLink;
|
} BlockLink_t;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inserts a block of memory that is being freed into the correct position in
|
* Inserts a block of memory that is being freed into the correct position in
|
||||||
* the list of free memory blocks. The block being freed will be merged with
|
* the list of free memory blocks. The block being freed will be merged with
|
||||||
* the block in front it and/or the block behind it if the memory blocks are
|
* the block in front it and/or the block behind it if the memory blocks are
|
||||||
* adjacent to each other.
|
* adjacent to each other.
|
||||||
*/
|
*/
|
||||||
static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert );
|
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called automatically to setup the required heap structures the first time
|
* Called automatically to setup the required heap structures the first time
|
||||||
@ -123,20 +93,18 @@ static void prvHeapInit( void );
|
|||||||
|
|
||||||
/* The size of the structure placed at the beginning of each allocated memory
|
/* The size of the structure placed at the beginning of each allocated memory
|
||||||
block must by correctly byte aligned. */
|
block must by correctly byte aligned. */
|
||||||
static const unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
|
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
/* Ensure the pxEnd pointer will end up on the correct byte alignment. */
|
|
||||||
static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
|
|
||||||
|
|
||||||
/* Create a couple of list links to mark the start and end of the list. */
|
/* Create a couple of list links to mark the start and end of the list. */
|
||||||
static xBlockLink xStart, *pxEnd = NULL;
|
static BlockLink_t xStart, *pxEnd = NULL;
|
||||||
|
|
||||||
/* Keeps track of the number of free bytes remaining, but says nothing about
|
/* Keeps track of the number of free bytes remaining, but says nothing about
|
||||||
fragmentation. */
|
fragmentation. */
|
||||||
static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
|
static size_t xFreeBytesRemaining = 0U;
|
||||||
|
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||||
|
|
||||||
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
|
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
|
||||||
member of an xBlockLink structure is set then the block belongs to the
|
member of an BlockLink_t structure is set then the block belongs to the
|
||||||
application. When the bit is free the block is still part of the free heap
|
application. When the bit is free the block is still part of the free heap
|
||||||
space. */
|
space. */
|
||||||
static size_t xBlockAllocatedBit = 0;
|
static size_t xBlockAllocatedBit = 0;
|
||||||
@ -145,7 +113,7 @@ static size_t xBlockAllocatedBit = 0;
|
|||||||
|
|
||||||
void *pvPortMalloc( size_t xWantedSize )
|
void *pvPortMalloc( size_t xWantedSize )
|
||||||
{
|
{
|
||||||
xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
||||||
void *pvReturn = NULL;
|
void *pvReturn = NULL;
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
@ -156,31 +124,44 @@ void *pvReturn = NULL;
|
|||||||
{
|
{
|
||||||
prvHeapInit();
|
prvHeapInit();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the requested block size is not so large that the top bit is
|
/* Check the requested block size is not so large that the top bit is
|
||||||
set. The top bit of the block size member of the xBlockLink structure
|
set. The top bit of the block size member of the BlockLink_t structure
|
||||||
is used to determine who owns the block - the application or the
|
is used to determine who owns the block - the application or the
|
||||||
kernel, so it must be free. */
|
kernel, so it must be free. */
|
||||||
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
|
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
|
||||||
{
|
{
|
||||||
/* The wanted size is increased so it can contain a xBlockLink
|
/* The wanted size is increased so it can contain a BlockLink_t
|
||||||
structure in addition to the requested amount of bytes. */
|
structure in addition to the requested amount of bytes. */
|
||||||
if( xWantedSize > 0 )
|
if( xWantedSize > 0 )
|
||||||
{
|
{
|
||||||
xWantedSize += heapSTRUCT_SIZE;
|
xWantedSize += xHeapStructSize;
|
||||||
|
|
||||||
/* Ensure that blocks are always aligned to the required number
|
/* Ensure that blocks are always aligned to the required number
|
||||||
of bytes. */
|
of bytes. */
|
||||||
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
|
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||||
{
|
{
|
||||||
/* Byte alignment required. */
|
/* Byte alignment required. */
|
||||||
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
|
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
|
||||||
|
configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||||
{
|
{
|
||||||
/* Traverse the list from the start (lowest address) block until
|
/* Traverse the list from the start (lowest address) block until
|
||||||
one of adequate size is found. */
|
one of adequate size is found. */
|
||||||
pxPreviousBlock = &xStart;
|
pxPreviousBlock = &xStart;
|
||||||
pxBlock = xStart.pxNextFreeBlock;
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
@ -190,50 +171,76 @@ void *pvReturn = NULL;
|
|||||||
pxBlock = pxBlock->pxNextFreeBlock;
|
pxBlock = pxBlock->pxNextFreeBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the end marker was reached then a block of adequate size
|
/* If the end marker was reached then a block of adequate size
|
||||||
was not found. */
|
was not found. */
|
||||||
if( pxBlock != pxEnd )
|
if( pxBlock != pxEnd )
|
||||||
{
|
{
|
||||||
/* Return the memory space pointed to - jumping over the
|
/* Return the memory space pointed to - jumping over the
|
||||||
xBlockLink structure at its start. */
|
BlockLink_t structure at its start. */
|
||||||
pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||||
|
|
||||||
/* This block is being returned for use so must be taken out
|
/* This block is being returned for use so must be taken out
|
||||||
of the list of free blocks. */
|
of the list of free blocks. */
|
||||||
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
|
||||||
/* If the block is larger than required it can be split into
|
/* If the block is larger than required it can be split into
|
||||||
two. */
|
two. */
|
||||||
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
|
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
|
||||||
{
|
{
|
||||||
/* This block is to be split into two. Create a new
|
/* This block is to be split into two. Create a new
|
||||||
block following the number of bytes requested. The void
|
block following the number of bytes requested. The void
|
||||||
cast is used to prevent byte alignment warnings from the
|
cast is used to prevent byte alignment warnings from the
|
||||||
compiler. */
|
compiler. */
|
||||||
pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize );
|
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||||
|
configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
/* Calculate the sizes of two blocks split from the
|
/* Calculate the sizes of two blocks split from the
|
||||||
single block. */
|
single block. */
|
||||||
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||||
pxBlock->xBlockSize = xWantedSize;
|
pxBlock->xBlockSize = xWantedSize;
|
||||||
|
|
||||||
/* Insert the new block into the list of free blocks. */
|
/* Insert the new block into the list of free blocks. */
|
||||||
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
|
prvInsertBlockIntoFreeList( pxNewBlockLink );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||||
|
{
|
||||||
|
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
/* The block is being returned - it is allocated and owned
|
/* The block is being returned - it is allocated and owned
|
||||||
by the application and has no "next" block. */
|
by the application and has no "next" block. */
|
||||||
pxBlock->xBlockSize |= xBlockAllocatedBit;
|
pxBlock->xBlockSize |= xBlockAllocatedBit;
|
||||||
pxBlock->pxNextFreeBlock = NULL;
|
pxBlock->pxNextFreeBlock = NULL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
traceMALLOC( pvReturn, xWantedSize );
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
}
|
}
|
||||||
xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
{
|
{
|
||||||
@ -242,23 +249,28 @@ void *pvReturn = NULL;
|
|||||||
extern void vApplicationMallocFailedHook( void );
|
extern void vApplicationMallocFailedHook( void );
|
||||||
vApplicationMallocFailedHook();
|
vApplicationMallocFailedHook();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
return pvReturn;
|
return pvReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFree( void *pv )
|
void vPortFree( void *pv )
|
||||||
{
|
{
|
||||||
unsigned char *puc = ( unsigned char * ) pv;
|
uint8_t *puc = ( uint8_t * ) pv;
|
||||||
xBlockLink *pxLink;
|
BlockLink_t *pxLink;
|
||||||
|
|
||||||
if( pv != NULL )
|
if( pv != NULL )
|
||||||
{
|
{
|
||||||
/* The memory being freed will have an xBlockLink structure immediately
|
/* The memory being freed will have an BlockLink_t structure immediately
|
||||||
before it. */
|
before it. */
|
||||||
puc -= heapSTRUCT_SIZE;
|
puc -= xHeapStructSize;
|
||||||
|
|
||||||
/* This casting is to keep the compiler from issuing warnings. */
|
/* This casting is to keep the compiler from issuing warnings. */
|
||||||
pxLink = ( void * ) puc;
|
pxLink = ( void * ) puc;
|
||||||
@ -266,7 +278,7 @@ xBlockLink *pxLink;
|
|||||||
/* Check the block is actually allocated. */
|
/* Check the block is actually allocated. */
|
||||||
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
|
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
|
||||||
configASSERT( pxLink->pxNextFreeBlock == NULL );
|
configASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||||
|
|
||||||
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
|
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
|
||||||
{
|
{
|
||||||
if( pxLink->pxNextFreeBlock == NULL )
|
if( pxLink->pxNextFreeBlock == NULL )
|
||||||
@ -279,11 +291,19 @@ xBlockLink *pxLink;
|
|||||||
{
|
{
|
||||||
/* Add this block to the list of free blocks. */
|
/* Add this block to the list of free blocks. */
|
||||||
xFreeBytesRemaining += pxLink->xBlockSize;
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) );
|
|
||||||
traceFREE( pv, pxLink->xBlockSize );
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
}
|
}
|
||||||
xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,6 +315,12 @@ size_t xPortGetFreeHeapSize( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xMinimumEverFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortInitialiseBlocks( void )
|
void vPortInitialiseBlocks( void )
|
||||||
{
|
{
|
||||||
/* This just exists to keep the linker quiet. */
|
/* This just exists to keep the linker quiet. */
|
||||||
@ -303,11 +329,22 @@ void vPortInitialiseBlocks( void )
|
|||||||
|
|
||||||
static void prvHeapInit( void )
|
static void prvHeapInit( void )
|
||||||
{
|
{
|
||||||
xBlockLink *pxFirstFreeBlock;
|
BlockLink_t *pxFirstFreeBlock;
|
||||||
unsigned char *pucHeapEnd, *pucAlignedHeap;
|
uint8_t *pucAlignedHeap;
|
||||||
|
size_t uxAddress;
|
||||||
|
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
/* Ensure the heap starts on a correctly aligned boundary. */
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
||||||
|
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
uxAddress += ( portBYTE_ALIGNMENT - 1 );
|
||||||
|
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||||
|
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||||
|
|
||||||
/* xStart is used to hold a pointer to the first item in the list of free
|
/* xStart is used to hold a pointer to the first item in the list of free
|
||||||
blocks. The void cast is used to prevent compiler warnings. */
|
blocks. The void cast is used to prevent compiler warnings. */
|
||||||
@ -316,31 +353,32 @@ unsigned char *pucHeapEnd, *pucAlignedHeap;
|
|||||||
|
|
||||||
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||||
at the end of the heap space. */
|
at the end of the heap space. */
|
||||||
pucHeapEnd = pucAlignedHeap + xTotalHeapSize;
|
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||||
pucHeapEnd -= heapSTRUCT_SIZE;
|
uxAddress -= xHeapStructSize;
|
||||||
pxEnd = ( void * ) pucHeapEnd;
|
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||||
configASSERT( ( ( ( unsigned long ) pxEnd ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL );
|
pxEnd = ( void * ) uxAddress;
|
||||||
pxEnd->xBlockSize = 0;
|
pxEnd->xBlockSize = 0;
|
||||||
pxEnd->pxNextFreeBlock = NULL;
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
/* To start with there is a single free block that is sized to take up the
|
/* To start with there is a single free block that is sized to take up the
|
||||||
entire heap space, minus the space taken by pxEnd. */
|
entire heap space, minus the space taken by pxEnd. */
|
||||||
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
pxFirstFreeBlock->xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE;
|
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||||
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
/* The heap now contains pxEnd. */
|
/* Only one block exists - and it covers the entire usable heap space. */
|
||||||
xFreeBytesRemaining -= heapSTRUCT_SIZE;
|
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
|
||||||
/* Work out the position of the top bit in a size_t variable. */
|
/* Work out the position of the top bit in a size_t variable. */
|
||||||
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
|
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert )
|
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
|
||||||
{
|
{
|
||||||
xBlockLink *pxIterator;
|
BlockLink_t *pxIterator;
|
||||||
unsigned char *puc;
|
uint8_t *puc;
|
||||||
|
|
||||||
/* Iterate through the list until a block is found that has a higher address
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
than the block being inserted. */
|
than the block being inserted. */
|
||||||
@ -350,18 +388,22 @@ unsigned char *puc;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do the block being inserted, and the block it is being inserted after
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
make a contiguous block of memory? */
|
make a contiguous block of memory? */
|
||||||
puc = ( unsigned char * ) pxIterator;
|
puc = ( uint8_t * ) pxIterator;
|
||||||
if( ( puc + pxIterator->xBlockSize ) == ( unsigned char * ) pxBlockToInsert )
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
{
|
{
|
||||||
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
pxBlockToInsert = pxIterator;
|
pxBlockToInsert = pxIterator;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
/* Do the block being inserted, and the block it is being inserted before
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
make a contiguous block of memory? */
|
make a contiguous block of memory? */
|
||||||
puc = ( unsigned char * ) pxBlockToInsert;
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
if( ( puc + pxBlockToInsert->xBlockSize ) == ( unsigned char * ) pxIterator->pxNextFreeBlock )
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
{
|
{
|
||||||
if( pxIterator->pxNextFreeBlock != pxEnd )
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
{
|
{
|
||||||
@ -376,7 +418,7 @@ unsigned char *puc;
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the block being inserted plugged a gab, so was merged with the block
|
/* If the block being inserted plugged a gab, so was merged with the block
|
||||||
@ -387,5 +429,9 @@ unsigned char *puc;
|
|||||||
{
|
{
|
||||||
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,329 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
/* Constants required to setup the initial 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 )
|
|
||||||
|
|
||||||
/* Constants required to handle interrupts. */
|
|
||||||
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
|
|
||||||
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* The code generated by the Keil 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 must be initialised to a non zero value. */
|
|
||||||
|
|
||||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
|
||||||
volatile unsigned portLONG ulCriticalNesting = 9999UL;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
|
||||||
static void prvSetupTimerInterrupt( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The scheduler can only be started from ARM mode, so
|
|
||||||
* vPortStartFirstSTask() is defined in portISR.c.
|
|
||||||
*/
|
|
||||||
extern __asm void vPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
|
||||||
{
|
|
||||||
portSTACK_TYPE *pxOriginalTOS;
|
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
|
||||||
expected by the portRESTORE_CONTEXT() macro.
|
|
||||||
|
|
||||||
Remember where the top of the (simulated) stack is before we place
|
|
||||||
anything on it. */
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
|
||||||
is not really required. */
|
|
||||||
pxTopOfStack--;
|
|
||||||
|
|
||||||
/* 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--;
|
|
||||||
*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 ) != 0x00UL )
|
|
||||||
{
|
|
||||||
/* We want the task to start in thumb mode. */
|
|
||||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
pxTopOfStack--;
|
|
||||||
|
|
||||||
/* The code generated by the Keil 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 = portNO_CRITICAL_SECTION_NESTING;
|
|
||||||
|
|
||||||
return pxTopOfStack;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
|
||||||
prvSetupTimerInterrupt();
|
|
||||||
|
|
||||||
/* Start the first task. This is done from portISR.c as ARM mode must be
|
|
||||||
used. */
|
|
||||||
vPortStartFirstTask();
|
|
||||||
|
|
||||||
/* 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. If this is required - stop the tick ISR then
|
|
||||||
return back to main. */
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The cooperative scheduler requires a normal IRQ service routine to
|
|
||||||
* simply increment the system tick.
|
|
||||||
*/
|
|
||||||
void vNonPreemptiveTick( void ) __irq;
|
|
||||||
void vNonPreemptiveTick( void ) __irq
|
|
||||||
{
|
|
||||||
/* Increment the tick count - this may make a delaying task ready
|
|
||||||
to run - but a context switch is not performed. */
|
|
||||||
xTaskIncrementTick();
|
|
||||||
|
|
||||||
T0IR = portTIMER_MATCH_ISR_BIT; /* Clear the timer event */
|
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT; /* Acknowledge the Interrupt */
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
**************************************************************************
|
|
||||||
* The preemptive scheduler ISR is written in assembler and can be found
|
|
||||||
* in the portASM.s file. This will only get used if portUSE_PREEMPTION
|
|
||||||
* is set to 1 in portmacro.h
|
|
||||||
**************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
void vPreemptiveTick( void );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
unsigned portLONG ulCompareMatch;
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
T0MR0 = ulCompareMatch;
|
|
||||||
|
|
||||||
/* Generate tick with timer 0 compare match. */
|
|
||||||
T0MCR = 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. */
|
|
||||||
#if configUSE_PREEMPTION == 1
|
|
||||||
{
|
|
||||||
VICVectAddr0 = ( unsigned portLONG ) vPreemptiveTick;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
VICVectAddr0 = ( unsigned portLONG ) vNonPreemptiveTick;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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. */
|
|
||||||
T0TCR = portENABLE_TIMER;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
/* 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(). */
|
|
||||||
__enable_irq();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
|||||||
;/*
|
|
||||||
; FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
; All rights reserved
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; ***************************************************************************
|
|
||||||
; * *
|
|
||||||
; * 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.
|
|
||||||
;*/
|
|
||||||
|
|
||||||
INCLUDE portmacro.inc
|
|
||||||
|
|
||||||
IMPORT vTaskSwitchContext
|
|
||||||
IMPORT xTaskIncrementTick
|
|
||||||
|
|
||||||
EXPORT vPortYieldProcessor
|
|
||||||
EXPORT vPortStartFirstTask
|
|
||||||
EXPORT vPreemptiveTick
|
|
||||||
EXPORT vPortYield
|
|
||||||
|
|
||||||
|
|
||||||
VICVECTADDR EQU 0xFFFFF030
|
|
||||||
T0IR EQU 0xE0004000
|
|
||||||
T0MATCHBIT EQU 0x00000001
|
|
||||||
|
|
||||||
ARM
|
|
||||||
AREA PORT_ASM, CODE, READONLY
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Starting the first task is done by just restoring the context
|
|
||||||
; setup by pxPortInitialiseStack
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
vPortStartFirstTask
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
portRESTORE_CONTEXT
|
|
||||||
|
|
||||||
vPortYield
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
SVC 0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Interrupt service routine for the SWI interrupt. The vector table is
|
|
||||||
; configured in the startup.s file.
|
|
||||||
;
|
|
||||||
; vPortYieldProcessor() is used to manually force a context switch. The
|
|
||||||
; SWI interrupt is generated by a call to taskYIELD() or portYIELD().
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
vPortYieldProcessor
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
; 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.
|
|
||||||
ADD LR, LR, #4
|
|
||||||
|
|
||||||
; Perform the context switch.
|
|
||||||
portSAVE_CONTEXT ; Save current task context
|
|
||||||
LDR R0, =vTaskSwitchContext ; Get the address of the context switch function
|
|
||||||
MOV LR, PC ; Store the return address
|
|
||||||
BX R0 ; Call the contedxt switch function
|
|
||||||
portRESTORE_CONTEXT ; restore the context of the selected task
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; Interrupt service routine for preemptive scheduler tick timer
|
|
||||||
; Only used if portUSE_PREEMPTION is set to 1 in portmacro.h
|
|
||||||
;
|
|
||||||
; Uses timer 0 of LPC21XX Family
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
vPreemptiveTick
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
portSAVE_CONTEXT ; Save the context of the current task.
|
|
||||||
|
|
||||||
LDR R0, =xTaskIncrementTick ; Increment the tick count.
|
|
||||||
MOV LR, PC ; This may make a delayed task ready
|
|
||||||
BX R0 ; to run.
|
|
||||||
|
|
||||||
CMP R0, #0
|
|
||||||
BEQ SkipContextSwitch
|
|
||||||
LDR R0, =vTaskSwitchContext ; Find the highest priority task that
|
|
||||||
MOV LR, PC ; is ready to run.
|
|
||||||
BX R0
|
|
||||||
SkipContextSwitch
|
|
||||||
MOV R0, #T0MATCHBIT ; Clear the timer event
|
|
||||||
LDR R1, =T0IR
|
|
||||||
STR R0, [R1]
|
|
||||||
|
|
||||||
LDR R0, =VICVECTADDR ; Acknowledge the interrupt
|
|
||||||
STR R0,[R0]
|
|
||||||
|
|
||||||
portRESTORE_CONTEXT ; Restore the context of the highest
|
|
||||||
; priority task that is ready to run.
|
|
||||||
END
|
|
||||||
|
|
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Hardware specifics. */
|
|
||||||
#define portSTACK_GROWTH ( -1 )
|
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
|
||||||
#define portBYTE_ALIGNMENT 8
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Task utilities. */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* ISR entry and exit macros. These are only required if a task switch
|
|
||||||
* is required from an ISR.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* If a switch is required then we just need to call */
|
|
||||||
/* vTaskSwitchContext() as the context has already been */
|
|
||||||
/* saved. */
|
|
||||||
|
|
||||||
#define portEXIT_SWITCHING_ISR(SwitchRequired) \
|
|
||||||
{ \
|
|
||||||
extern void vTaskSwitchContext(void); \
|
|
||||||
\
|
|
||||||
if(SwitchRequired) \
|
|
||||||
{ \
|
|
||||||
vTaskSwitchContext(); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
|
|
||||||
extern void vPortYield( void );
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
******************************************************************
|
|
||||||
* We don't need to worry about whether we're in ARM or
|
|
||||||
* THUMB mode with the Keil Real View compiler when enabling
|
|
||||||
* or disabling interrupts as the compiler's intrinsic functions
|
|
||||||
* take care of that for us.
|
|
||||||
*******************************************************************
|
|
||||||
*/
|
|
||||||
#define portDISABLE_INTERRUPTS() __disable_irq()
|
|
||||||
#define portENABLE_INTERRUPTS() __enable_irq()
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Critical section control
|
|
||||||
*
|
|
||||||
* The code generated by the Keil 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 necessitates the use of a
|
|
||||||
* function in place of the macro.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Compiler specifics. */
|
|
||||||
#define inline
|
|
||||||
#define register
|
|
||||||
#define portNOP() __asm{ 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 */
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
|||||||
;/*
|
|
||||||
; FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
; All rights reserved
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; ***************************************************************************
|
|
||||||
; * *
|
|
||||||
; * 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.
|
|
||||||
;*/
|
|
||||||
|
|
||||||
IMPORT ulCriticalNesting ;
|
|
||||||
IMPORT pxCurrentTCB ;
|
|
||||||
|
|
||||||
|
|
||||||
MACRO
|
|
||||||
portRESTORE_CONTEXT
|
|
||||||
|
|
||||||
|
|
||||||
LDR R0, =pxCurrentTCB ; Set the LR to the task stack. The location was...
|
|
||||||
LDR R0, [R0] ; ... stored in pxCurrentTCB
|
|
||||||
LDR LR, [R0]
|
|
||||||
|
|
||||||
LDR R0, =ulCriticalNesting ; The critical nesting depth is the first item on...
|
|
||||||
LDMFD LR!, {R1} ; ...the stack. Load it into the ulCriticalNesting var.
|
|
||||||
STR R1, [R0] ;
|
|
||||||
|
|
||||||
LDMFD LR!, {R0} ; Get the SPSR from the stack.
|
|
||||||
MSR SPSR_cxsf, R0 ;
|
|
||||||
|
|
||||||
LDMFD LR, {R0-R14}^ ; Restore all system mode registers for the task.
|
|
||||||
NOP ;
|
|
||||||
|
|
||||||
LDR LR, [LR, #+60] ; Restore the return address
|
|
||||||
|
|
||||||
; And return - correcting the offset in the LR to obtain ...
|
|
||||||
SUBS PC, LR, #4 ; ...the correct address.
|
|
||||||
|
|
||||||
MEND
|
|
||||||
|
|
||||||
; /**********************************************************************/
|
|
||||||
|
|
||||||
MACRO
|
|
||||||
portSAVE_CONTEXT
|
|
||||||
|
|
||||||
|
|
||||||
STMDB SP!, {R0} ; Store R0 first as we need to use it.
|
|
||||||
|
|
||||||
STMDB SP,{SP}^ ; Set R0 to point to the task stack pointer.
|
|
||||||
NOP ;
|
|
||||||
SUB SP, SP, #4 ;
|
|
||||||
LDMIA SP!,{R0} ;
|
|
||||||
|
|
||||||
STMDB R0!, {LR} ; Push the return address onto the stack.
|
|
||||||
MOV LR, R0 ; Now we have saved LR we can use it instead of R0.
|
|
||||||
LDMIA SP!, {R0} ; Pop R0 so we can save it onto the system mode stack.
|
|
||||||
|
|
||||||
STMDB LR,{R0-LR}^ ; Push all the system mode registers onto the task stack.
|
|
||||||
NOP ;
|
|
||||||
SUB LR, LR, #60 ;
|
|
||||||
|
|
||||||
MRS R0, SPSR ; Push the SPSR onto the task stack.
|
|
||||||
STMDB LR!, {R0} ;
|
|
||||||
|
|
||||||
LDR R0, =ulCriticalNesting ;
|
|
||||||
LDR R0, [R0] ;
|
|
||||||
STMDB LR!, {R0} ;
|
|
||||||
|
|
||||||
LDR R0, =pxCurrentTCB ; Store the new top of stack for the task.
|
|
||||||
LDR R1, [R0] ;
|
|
||||||
STR LR, [R1] ;
|
|
||||||
|
|
||||||
MEND
|
|
||||||
|
|
||||||
END
|
|
@ -1,340 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* 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 )
|
|
||||||
|
|
||||||
/* Constants used with memory barrier intrinsics. */
|
|
||||||
#define portSY_FULL_READ_WRITE ( 15 )
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
static void prvSetupTimerInterrupt( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exception handlers.
|
|
||||||
*/
|
|
||||||
void xPortPendSVHandler( void );
|
|
||||||
void xPortSysTickHandler( void );
|
|
||||||
void vPortSVCHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
static void prvPortStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* LR */
|
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
|
||||||
pxTopOfStack -= 8; /* R11..R4. */
|
|
||||||
|
|
||||||
return pxTopOfStack;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortSVCHandler( void )
|
|
||||||
{
|
|
||||||
/* This function is no longer used, but retained for backward
|
|
||||||
compatibility. */
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void prvPortStartFirstTask( void )
|
|
||||||
{
|
|
||||||
extern pxCurrentTCB;
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
|
||||||
table offset register that can be used to locate the initial stack value.
|
|
||||||
Not all M0 parts have the application vector table at address 0. */
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
adds r0, #32 /* Discard everything up to r0. */
|
|
||||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
|
||||||
movs r0, #2 /* Switch to the psp stack. */
|
|
||||||
msr CONTROL, r0
|
|
||||||
pop {r0-r5} /* Pop the registers that are saved automatically. */
|
|
||||||
mov lr, r5 /* lr is now in r5. */
|
|
||||||
cpsie i /* The first task has its context and interrupts can be enabled. */
|
|
||||||
pop {pc} /* Finally, pop the PC to jump to the user defined task code. */
|
|
||||||
|
|
||||||
ALIGN
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
|
||||||
here already. */
|
|
||||||
prvSetupTimerInterrupt();
|
|
||||||
|
|
||||||
/* 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 CM0 port will require this function as there
|
|
||||||
is nothing to return to. */
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm unsigned long ulSetInterruptMaskFromISR( void )
|
|
||||||
{
|
|
||||||
mrs r0, PRIMASK
|
|
||||||
cpsid i
|
|
||||||
bx lr
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vClearInterruptMaskFromISR( unsigned long ulMask )
|
|
||||||
{
|
|
||||||
msr PRIMASK, r0
|
|
||||||
bx lr
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void xPortPendSVHandler( void )
|
|
||||||
{
|
|
||||||
extern vTaskSwitchContext
|
|
||||||
extern pxCurrentTCB
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, psp
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
subs r0, #32 /* Make space for the remaining low registers. */
|
|
||||||
str r0, [r2] /* Save the new top of stack. */
|
|
||||||
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
|
|
||||||
mov r4, r8 /* Store the high registers. */
|
|
||||||
mov r5, r9
|
|
||||||
mov r6, r10
|
|
||||||
mov r7, r11
|
|
||||||
stmia r0!, {r4-r7}
|
|
||||||
|
|
||||||
push {r3, r14}
|
|
||||||
cpsid i
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
cpsie i
|
|
||||||
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */
|
|
||||||
|
|
||||||
ldr r1, [r2]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
adds r0, #16 /* Move to the high registers. */
|
|
||||||
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
|
||||||
mov r8, r4
|
|
||||||
mov r9, r5
|
|
||||||
mov r10, r6
|
|
||||||
mov r11, r7
|
|
||||||
|
|
||||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
|
||||||
|
|
||||||
subs r0, #32 /* Go back for the low registers that are not automatically restored. */
|
|
||||||
ldmia r0!, {r4-r7} /* Pop low registers. */
|
|
||||||
|
|
||||||
bx r3
|
|
||||||
ALIGN
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
unsigned long ulPreviousMask;
|
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* Pend a context switch. */
|
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
extern unsigned long ulSetInterruptMaskFromISR( void );
|
|
||||||
extern void vClearInterruptMaskFromISR( unsigned long ulMask );
|
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
|
||||||
#define portDISABLE_INTERRUPTS() __disable_irq()
|
|
||||||
#define portENABLE_INTERRUPTS() __enable_irq()
|
|
||||||
#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 */
|
|
||||||
|
|
@ -1,696 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
|
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The __weak attribute does not work as you might expect with the Keil tools
|
|
||||||
so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if
|
|
||||||
the application writer wants to provide their own implementation of
|
|
||||||
vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION
|
|
||||||
is defined. */
|
|
||||||
#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION
|
|
||||||
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
|
|
||||||
#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_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_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 check the validity of an interrupt priority. */
|
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
|
||||||
|
|
||||||
/* Constants used with memory barrier intrinsics. */
|
|
||||||
#define portSY_FULL_READ_WRITE ( 15 )
|
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
|
||||||
calculations. */
|
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
||||||
|
|
||||||
/* 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 );
|
|
||||||
void xPortSysTickHandler( void );
|
|
||||||
void vPortSVCHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
static void prvStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of SysTick increments that make up one tick period.
|
|
||||||
*/
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
*/
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vPortSVCHandler( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Restore the context. */
|
|
||||||
ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
|
||||||
msr psp, r0 /* Restore the task stack pointer. */
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
orr r14, #0xd
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void prvStartFirstTask( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* Use the NVIC offset register to locate the stack. */
|
|
||||||
ldr r0, =0xE000ED08
|
|
||||||
ldr r0, [r0]
|
|
||||||
ldr r0, [r0]
|
|
||||||
/* Set the msp back to the start of the stack. */
|
|
||||||
msr msp, r0
|
|
||||||
/* Globally enable interrupts. */
|
|
||||||
cpsie i
|
|
||||||
/* Call SVC to start the first task. */
|
|
||||||
svc 0
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
{
|
|
||||||
volatile unsigned long ulOriginalPriority;
|
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
|
||||||
functions can be called. ISR safe functions are those that end in
|
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
possible bits. */
|
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
|
||||||
of bits read back. */
|
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
||||||
{
|
|
||||||
ulMaxPRIGROUPValue--;
|
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
|
||||||
register. */
|
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
value. */
|
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
|
||||||
}
|
|
||||||
#endif /* conifgASSERT_DEFINED */
|
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
||||||
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. */
|
|
||||||
prvStartFirstTask();
|
|
||||||
|
|
||||||
/* 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 vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void xPortPendSVHandler( void )
|
|
||||||
{
|
|
||||||
extern uxCriticalNesting;
|
|
||||||
extern pxCurrentTCB;
|
|
||||||
extern vTaskSwitchContext;
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, psp
|
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
stmdb r0!, {r4-r11} /* Save the remaining registers. */
|
|
||||||
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
|
|
||||||
|
|
||||||
stmdb sp!, {r3, r14}
|
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r0
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
ldmia sp!, {r3, r14}
|
|
||||||
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
ldmia r0!, {r4-r11} /* Pop the registers and the critical nesting count. */
|
|
||||||
msr psp, r0
|
|
||||||
bx r14
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
|
||||||
save and then restore the interrupt mask value as its value is already
|
|
||||||
known. */
|
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* A context switch is required. Context switching is performed in
|
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
|
||||||
{
|
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
|
||||||
portTickType xModifiableIdleTime;
|
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
|
||||||
{
|
|
||||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
|
||||||
{
|
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
|
||||||
to be unsuspended then abandon the low power entry. */
|
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
|
||||||
{
|
|
||||||
/* Restart from whatever is left in the count register to complete
|
|
||||||
this tick period. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* Restart SysTick. */
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
|
||||||
periods. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
|
||||||
above. */
|
|
||||||
__enable_irq();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the new reload value. */
|
|
||||||
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() can
|
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
|
||||||
should not be executed again. However, the original expected idle
|
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
|
||||||
if( xModifiableIdleTime > 0 )
|
|
||||||
{
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__wfi();
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
|
||||||
above. */
|
|
||||||
__enable_irq();
|
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
|
||||||
{
|
|
||||||
unsigned long ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
|
||||||
count reloaded with ulReloadValue. Reset the
|
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
|
||||||
period. */
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
|
||||||
underflowed because the post sleep hook did something
|
|
||||||
that took too long. */
|
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
|
||||||
{
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
|
||||||
}
|
|
||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* 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 rounded to complete tick
|
|
||||||
periods (not the ulReload value which accounted for part
|
|
||||||
ticks). */
|
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
|
||||||
was waiting? */
|
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
|
||||||
period remains. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
|
||||||
value. The critical section is used to ensure the tick interrupt
|
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the SysTick timer to generate the tick interrupts at the required
|
|
||||||
* frequency.
|
|
||||||
*/
|
|
||||||
#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0
|
|
||||||
|
|
||||||
void vPortSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
{
|
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
|
||||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm unsigned long ulPortSetInterruptMask( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vPortClearInterruptMask( unsigned long ulNewMask )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm unsigned long vPortGetIPSR( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, ipsr
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
|
||||||
{
|
|
||||||
unsigned long ulCurrentInterrupt;
|
|
||||||
unsigned char ucCurrentPriority;
|
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
|
||||||
ulCurrentInterrupt = vPortGetIPSR();
|
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
|
||||||
{
|
|
||||||
/* Look up the interrupt's priority. */
|
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
|
||||||
an interrupt that has been assigned a priority above
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
|
||||||
from interrupts that have been assigned a priority at or below
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Numerically low interrupt priority numbers represent logically high
|
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
|
||||||
be set to a value equal to or numerically *higher* than
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
|
||||||
default priority of zero as that is the highest possible priority,
|
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
|
||||||
and therefore also guaranteed to be invalid.
|
|
||||||
|
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
|
||||||
interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
The following links provide detailed information:
|
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
|
||||||
http://www.freertos.org/FAQHelp.html */
|
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
|
||||||
that define each interrupt's priority to be split between bits that
|
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
|
||||||
this is not the case (if some bits represent a sub-priority).
|
|
||||||
|
|
||||||
If the application only uses CMSIS libraries for interrupt
|
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
|
||||||
of zero will result in unpredicable behaviour. */
|
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMask );
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Port specific optimisations. */
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
|
||||||
|
|
||||||
/* 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 - __clz( ( uxReadyPriorities ) ) )
|
|
||||||
|
|
||||||
#endif /* taskRECORD_READY_PRIORITY */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef configASSERT
|
|
||||||
void vPortValidateInterruptPriority( void );
|
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
|
||||||
#define portNOP()
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
|
||||||
|
|
@ -1,767 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
|
||||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
|
||||||
*----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#ifndef __TARGET_FPU_VFP
|
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
|
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The __weak attribute does not work as you might expect with the Keil tools
|
|
||||||
so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if
|
|
||||||
the application writer wants to provide their own implementation of
|
|
||||||
vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION
|
|
||||||
is defined. */
|
|
||||||
#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION
|
|
||||||
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
|
|
||||||
#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_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_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 check the validity of an interrupt priority. */
|
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
|
||||||
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
|
||||||
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
|
||||||
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
|
|
||||||
/* Constants used with memory barrier intrinsics. */
|
|
||||||
#define portSY_FULL_READ_WRITE ( 15 )
|
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
|
||||||
calculations. */
|
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
||||||
|
|
||||||
/* 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 );
|
|
||||||
void xPortSysTickHandler( void );
|
|
||||||
void vPortSVCHandler( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
|
||||||
*/
|
|
||||||
static void prvStartFirstTask( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions defined in portasm.s to enable the VFP.
|
|
||||||
*/
|
|
||||||
static void prvEnableVFP( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
|
||||||
*/
|
|
||||||
static void prvTaskExitError( void );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of SysTick increments that make up one tick period.
|
|
||||||
*/
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
static unsigned long ulTimerCountsForOneTick = 0;
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
||||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
|
||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
*/
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
|
||||||
static unsigned long ulMaxPRIGROUPValue = 0;
|
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 = ( portSTACK_TYPE ) prvTaskExitError; /* 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;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
|
||||||
{
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
|
||||||
should instead call vTaskDelete( NULL ).
|
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
|
||||||
defined, then stop here so application writers can catch the error. */
|
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
for( ;; );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vPortSVCHandler( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* Get the location of the current TCB. */
|
|
||||||
ldr r3, =pxCurrentTCB
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1]
|
|
||||||
/* Pop the core registers. */
|
|
||||||
ldmia r0!, {r4-r11, r14}
|
|
||||||
msr psp, r0
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void prvStartFirstTask( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* Use the NVIC offset register to locate the stack. */
|
|
||||||
ldr r0, =0xE000ED08
|
|
||||||
ldr r0, [r0]
|
|
||||||
ldr r0, [r0]
|
|
||||||
/* Set the msp back to the start of the stack. */
|
|
||||||
msr msp, r0
|
|
||||||
/* Globally enable interrupts. */
|
|
||||||
cpsie i
|
|
||||||
/* Call SVC to start the first task. */
|
|
||||||
svc 0
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void prvEnableVFP( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
/* The FPU enable bits are in the CPACR. */
|
|
||||||
ldr.w r0, =0xE000ED88
|
|
||||||
ldr r1, [r0]
|
|
||||||
|
|
||||||
/* Enable CP10 and CP11 coprocessors, then save back. */
|
|
||||||
orr r1, r1, #( 0xf << 20 )
|
|
||||||
str r1, [r0]
|
|
||||||
bx r14
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
|
||||||
{
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
{
|
|
||||||
volatile unsigned long ulOriginalPriority;
|
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
|
||||||
volatile unsigned char ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
|
||||||
functions can be called. ISR safe functions are those that end in
|
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
|
||||||
possible bits. */
|
|
||||||
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
|
||||||
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
|
||||||
of bits read back. */
|
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
||||||
{
|
|
||||||
ulMaxPRIGROUPValue--;
|
|
||||||
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
|
||||||
register. */
|
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
|
||||||
value. */
|
|
||||||
*pcFirstUserPriorityRegister = ulOriginalPriority;
|
|
||||||
}
|
|
||||||
#endif /* conifgASSERT_DEFINED */
|
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
||||||
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. */
|
|
||||||
prvEnableVFP();
|
|
||||||
|
|
||||||
/* Lazy save always. */
|
|
||||||
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
|
||||||
|
|
||||||
/* Start the first task. */
|
|
||||||
prvStartFirstTask();
|
|
||||||
|
|
||||||
/* 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 vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
|
||||||
uxCriticalNesting++;
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
|
||||||
{
|
|
||||||
uxCriticalNesting--;
|
|
||||||
if( uxCriticalNesting == 0 )
|
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void xPortPendSVHandler( void )
|
|
||||||
{
|
|
||||||
extern uxCriticalNesting;
|
|
||||||
extern pxCurrentTCB;
|
|
||||||
extern vTaskSwitchContext;
|
|
||||||
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, psp
|
|
||||||
|
|
||||||
/* Get the location of the current TCB. */
|
|
||||||
ldr r3, =pxCurrentTCB
|
|
||||||
ldr r2, [r3]
|
|
||||||
|
|
||||||
/* Is the task using the FPU context? If so, push high vfp registers. */
|
|
||||||
tst r14, #0x10
|
|
||||||
it eq
|
|
||||||
vstmdbeq r0!, {s16-s31}
|
|
||||||
|
|
||||||
/* Save the core registers. */
|
|
||||||
stmdb r0!, {r4-r11, r14}
|
|
||||||
|
|
||||||
/* Save the new top of stack into the first member of the TCB. */
|
|
||||||
str r0, [r2]
|
|
||||||
|
|
||||||
stmdb sp!, {r3}
|
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r0
|
|
||||||
bl vTaskSwitchContext
|
|
||||||
mov r0, #0
|
|
||||||
msr basepri, r0
|
|
||||||
ldmia sp!, {r3}
|
|
||||||
|
|
||||||
/* The first item in pxCurrentTCB is the task top of stack. */
|
|
||||||
ldr r1, [r3]
|
|
||||||
ldr r0, [r1]
|
|
||||||
|
|
||||||
/* Pop the core registers. */
|
|
||||||
ldmia r0!, {r4-r11, r14}
|
|
||||||
|
|
||||||
/* Is the task using the FPU context? If so, pop the high vfp registers
|
|
||||||
too. */
|
|
||||||
tst r14, #0x10
|
|
||||||
it eq
|
|
||||||
vldmiaeq r0!, {s16-s31}
|
|
||||||
|
|
||||||
msr psp, r0
|
|
||||||
|
|
||||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
|
||||||
#if WORKAROUND_PMU_CM001 == 1
|
|
||||||
push { r14 }
|
|
||||||
pop { pc }
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bx r14
|
|
||||||
nop
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
|
||||||
{
|
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
|
||||||
save and then restore the interrupt mask value as its value is already
|
|
||||||
known. */
|
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
|
||||||
{
|
|
||||||
/* Increment the RTOS tick. */
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
|
||||||
{
|
|
||||||
/* A context switch is required. Context switching is performed in
|
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
|
|
||||||
__weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
|
|
||||||
{
|
|
||||||
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
|
||||||
portTickType xModifiableIdleTime;
|
|
||||||
|
|
||||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
|
||||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
|
||||||
{
|
|
||||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
|
||||||
{
|
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
|
||||||
to be unsuspended then abandon the low power entry. */
|
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
|
||||||
{
|
|
||||||
/* Restart from whatever is left in the count register to complete
|
|
||||||
this tick period. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* Restart SysTick. */
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
|
||||||
periods. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
|
||||||
above. */
|
|
||||||
__enable_irq();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the new reload value. */
|
|
||||||
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() can
|
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
|
||||||
should not be executed again. However, the original expected idle
|
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
|
||||||
if( xModifiableIdleTime > 0 )
|
|
||||||
{
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__wfi();
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_irq() call
|
|
||||||
above. */
|
|
||||||
__enable_irq();
|
|
||||||
|
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
|
||||||
{
|
|
||||||
unsigned long ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* The tick interrupt has already executed, and the SysTick
|
|
||||||
count reloaded with ulReloadValue. Reset the
|
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
|
||||||
period. */
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
|
||||||
underflowed because the post sleep hook did something
|
|
||||||
that took too long. */
|
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
|
||||||
{
|
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
|
||||||
}
|
|
||||||
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
|
||||||
|
|
||||||
/* 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 rounded to complete tick
|
|
||||||
periods (not the ulReload value which accounted for part
|
|
||||||
ticks). */
|
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
|
||||||
was waiting? */
|
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
|
||||||
period remains. */
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
|
||||||
value. The critical section is used to ensure the tick interrupt
|
|
||||||
can only execute once in the case that the reload register is near
|
|
||||||
zero. */
|
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
|
||||||
portENTER_CRITICAL();
|
|
||||||
{
|
|
||||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
||||||
}
|
|
||||||
portEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the SysTick timer to generate the tick interrupts at the required
|
|
||||||
* frequency.
|
|
||||||
*/
|
|
||||||
#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0
|
|
||||||
|
|
||||||
void vPortSetupTimerInterrupt( void )
|
|
||||||
{
|
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
|
||||||
#if configUSE_TICKLESS_IDLE == 1
|
|
||||||
{
|
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
|
||||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm unsigned long ulPortSetInterruptMask( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vPortClearInterruptMask( unsigned long ulNewMask )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm unsigned long vPortGetIPSR( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, ipsr
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
|
||||||
{
|
|
||||||
unsigned long ulCurrentInterrupt;
|
|
||||||
unsigned char ucCurrentPriority;
|
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
|
||||||
ulCurrentInterrupt = vPortGetIPSR();
|
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
|
||||||
{
|
|
||||||
/* Look up the interrupt's priority. */
|
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
|
||||||
an interrupt that has been assigned a priority above
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
|
||||||
from interrupts that have been assigned a priority at or below
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Numerically low interrupt priority numbers represent logically high
|
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
|
||||||
be set to a value equal to or numerically *higher* than
|
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
||||||
|
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
|
||||||
default priority of zero as that is the highest possible priority,
|
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
|
||||||
and therefore also guaranteed to be invalid.
|
|
||||||
|
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
|
||||||
interrupt entry is as fast and simple as possible.
|
|
||||||
|
|
||||||
The following links provide detailed information:
|
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
|
||||||
http://www.freertos.org/FAQHelp.html */
|
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
|
||||||
that define each interrupt's priority to be split between bits that
|
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
|
||||||
this is not the case (if some bits represent a sub-priority).
|
|
||||||
|
|
||||||
If the application only uses CMSIS libraries for interrupt
|
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
|
||||||
of zero will result in unpredicable behaviour. */
|
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
|
||||||
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
|
||||||
All rights reserved
|
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
|
||||||
|
|
||||||
***************************************************************************
|
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that has become a de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly and support the FreeRTOS *
|
|
||||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
|
||||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
* Thank you! *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
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. Full license text is available from the following
|
|
||||||
link: http://www.freertos.org/a00114.html
|
|
||||||
|
|
||||||
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, books, training, latest versions,
|
|
||||||
license and Real Time Engineers Ltd. contact details.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
|
||||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000ed04 ) )
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
#define portYIELD() vPortYield()
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Critical section management. */
|
|
||||||
extern unsigned long ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( unsigned long ulNewMask );
|
|
||||||
extern void vPortEnterCritical( void );
|
|
||||||
extern void vPortExitCritical( void );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
|
||||||
extern void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime );
|
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Port specific optimisations. */
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
|
||||||
|
|
||||||
/* 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 - __clz( ( uxReadyPriorities ) ) )
|
|
||||||
|
|
||||||
#endif /* taskRECORD_READY_PRIORITY */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef configASSERT
|
|
||||||
void vPortValidateInterruptPriority( void );
|
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
|
||||||
#define portNOP()
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
|||||||
Each real time kernel port consists of three files that contain the core kernel
|
Each real time kernel port consists of three files that contain the core kernel
|
||||||
components and are common to every port, and one or more files that are
|
components and are common to every port, and one or more files that are
|
||||||
specific to a particular microcontroller and/or compiler.
|
specific to a particular microcontroller and/or compiler.
|
||||||
|
|
||||||
|
|
||||||
+ The FreeRTOS/Source/Portable/MemMang directory contains the three sample
|
+ The FreeRTOS/Source/Portable/MemMang directory contains the five sample
|
||||||
memory allocators as described on the http://www.FreeRTOS.org WEB site.
|
memory allocators as described on the http://www.FreeRTOS.org WEB site.
|
||||||
|
|
||||||
+ The other directories each contain files specific to a particular
|
+ The other directories each contain files specific to a particular
|
||||||
microcontroller or compiler.
|
microcontroller or compiler, where the directory name denotes the compiler
|
||||||
|
specific files the directory contains.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
For example, if you are interested in the GCC port for the ATMega323
|
For example, if you are interested in the [compiler] port for the [architecture]
|
||||||
microcontroller then the port specific files are contained in
|
microcontroller, then the port specific files are contained in
|
||||||
FreeRTOS/Source/Portable/GCC/ATMega323 directory. If this is the only
|
FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the
|
||||||
port you are interested in then all the other directories can be
|
only port you are interested in then all the other directories can be
|
||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
|
2335
vendor/freertos/freertos/Source/queue.c
vendored
2335
vendor/freertos/freertos/Source/queue.c
vendored
File diff suppressed because it is too large
Load Diff
1196
vendor/freertos/freertos/Source/stream_buffer.c
vendored
Normal file
1196
vendor/freertos/freertos/Source/stream_buffer.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4196
vendor/freertos/freertos/Source/tasks.c
vendored
4196
vendor/freertos/freertos/Source/tasks.c
vendored
File diff suppressed because it is too large
Load Diff
894
vendor/freertos/freertos/Source/timers.c
vendored
894
vendor/freertos/freertos/Source/timers.c
vendored
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user