mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
Move the stm32l1 sources, headers and boards into arch/arm/src/stm32l1, arch/arm/include/stm32l1 and boards/arm/stm32l1, then finalize the split: source each split family directly in arch/arm/Kconfig and boards/Kconfig and remove the now-empty combined arch/arm/src/stm32 and boards/arm/stm32 trees. BREAKING CHANGE: The legacy STM32 architecture and board paths were split into stm32f1, stm32l1, stm32f2, stm32f3, stm32f4, and stm32g4 directories. Out-of-tree boards must move from stm32 to the matching split family. Signed-off-by: raiden00pl <raiden00@railab.me>
125 lines
6 KiB
ReStructuredText
125 lines
6 KiB
ReStructuredText
.. _chip-h:
|
|
|
|
======
|
|
chip.h
|
|
======
|
|
|
|
The purpose of the two chip.h files in each arm chip
|
|
====================================================
|
|
|
|
If you wonder about the purpose of the two ``chip.h`` files in each arm chip.
|
|
|
|
.. code:: sh
|
|
|
|
$ find arch/arm -name chip.h | grep stm32
|
|
arch/arm/include/stm32f4/chip.h
|
|
arch/arm/src/stm32f4/chip.h
|
|
|
|
The reason behind ``arch/arm/src/stm32f4/chip.h`` file was a bad idea
|
|
that happened a long time ago.
|
|
|
|
Right now, I believe that its only required when ``CONFIG_ARMV7M_CMNVECTOR``
|
|
is selected in the configuration. In that case, ``arch/arm/src/stm32f4/chip.h``
|
|
is included by ``arch/arm/src/armv7-m/up_vectors.c`` in order provide
|
|
the number of interrupt vectors. In stm32, ``arch/arm/src/stm32f4/chip.h``
|
|
provides the number of vectors indirectly by including the correct,
|
|
chip-specific vectors.h file.
|
|
This function is a little more obvious in ``arch/arm/srch/lpc43xx/chip.h``.
|
|
|
|
This ``arch/arm/src/xyz/chip.h`` is also a good way to export awkward
|
|
internal header files in a cleaner way. But that use is optional
|
|
and not required outside of the chip- and board-related directories.
|
|
|
|
For the ``arch/include/stm32/chip.h`` file, only set of definitions
|
|
is required there, the NVIC priorities:
|
|
|
|
* ``NVIC_SYSH_PRIORITY_MIN`` provides the lowest interrupt priority
|
|
supported by the system. This is the highest numeric value;
|
|
but the lowest interrupt priority.
|
|
* ``NVIC_SYSH_PRIORITY_DEFAULT`` provides the default priority of all
|
|
interrupts. Since truly nested interrupts are not supported, this is
|
|
the priority of all interrupts except for the SVCall interrupt.
|
|
* ``NVIC_SYSH_PRIORITY_MAX`` provides the maximum interrupt priority.
|
|
For all ARMv7-M's, this will be the value zero.
|
|
* ``NVIC_SYSH_PRIORITY_STEP`` is the value need to increment from one
|
|
priority level to next, lower priority level.
|
|
|
|
If ``CONFIG_ARMV7M_USEBASEPRI`` is selected, then interrupts will be disabled
|
|
by setting the ``BASEPRI`` register to ``NVIC_SYSH_DISABLE_PRIORITY`` so that
|
|
most interrupts will not have execution priority.
|
|
SVCall must have execution priority in all cases.
|
|
|
|
In the normal cases, interrupts are not nest-able and all interrupts run
|
|
at an execution priority between ``NVIC_SYSH_PRIORITY_MIN`` and
|
|
``NVIC_SYSH_PRIORITY_MAX`` (with ``NVIC_SYSH_PRIORITY_MAX`` reserved
|
|
for SVCall).
|
|
|
|
If, in addition, ``CONFIG_ARCH_HIPRI_INTERRUPT`` is defined, then special high
|
|
priority interrupts are supported. These are not "nested" in the normal sense
|
|
of the word. These high priority interrupts can interrupt normal interrupt
|
|
processing but execute outside of OS (although they can "get back
|
|
into the game" via a PendSV interrupt).
|
|
|
|
In the normal course of things, interrupts must occasionally be disabled
|
|
using the ``up_irq_save()`` inline function to prevent contention in use
|
|
of resources that may be shared between interrupt level and non-interrupt
|
|
level logic. Now the question arises, if we are using the ``BASEPRI``
|
|
to disable interrupts and have high priority interrupts enabled
|
|
(``CONFIG_ARCH_HIPRI_INTERRUPT=y``), do we disable all interrupts except
|
|
SVCall (we cannot disable SVCall interrupts)?
|
|
Or do we only disable the "normal" interrupts?
|
|
|
|
If we are using the ``BASEPRI`` register to disable interrupts, then
|
|
the answer is that we must disable ONLY the normal interrupts. That is
|
|
because we cannot disable SVCALL interrupts and we cannot permit SVCAll
|
|
interrupts running at a higher priority than the high priority interrupts.
|
|
Otherwise, they will introduce jitter in the high priority interrupt
|
|
response time.
|
|
|
|
Hence, if you need to disable the high priority interrupt, you will have to
|
|
disable the interrupt either at the peripheral that generates the interrupt
|
|
or at the interrupt controller (e.g., ``NVIC``). Disabling global interrupts
|
|
via the ``BASEPRI`` register cannot effect high priority interrupts.
|
|
|
|
* ``NVIC_SYSH_MAXNORMAL_PRIORITY`` is the maximum priority of "normal"
|
|
interrupts. Interrupt are disabled at the level
|
|
``NVIC_SYSH_MAXNORMAL_PRIORITY``, disabling all "normal" interrupt
|
|
but leaving the high priority and SVCALL interrupts enabled.
|
|
* ``NVIC_SYSH_HIGH_PRIORITY`` is the priority of the high priority interrupt.
|
|
* ``NVIC_SYSH_DISABLE_PRIORITY`` is the level at which interrupts will
|
|
be disabled. This will be equal to ``NVIC_SYSH_MAXNORMAL_PRIORITY``.
|
|
* ``NVIC_SYSH_SVCALL_PRIORITY`` is the priority of the SVCall interrupt.
|
|
This must be higher priority than ``NVIC_SYSH_DISABLE_PRIORITY`` so that
|
|
it is never disabled, but lower in priority than
|
|
``NVIC_SYSH_DISABLE_PRIORITY`` so that SVCall handling cannot interfere
|
|
with high priority interrupt handling.
|
|
|
|
These definitions only have to be here because NVIC implementations may differ
|
|
in the number of priority levels.
|
|
|
|
Now, by convention, the ``arch/xyz/include/chip/abc/chip.h`` file is also used
|
|
to provide all of the definitions that discriminate the features of the
|
|
different members of the chip family.
|
|
It is not technically necessary that those chip feature definitions exist
|
|
in this header file, but it is a good convention to follow so that
|
|
it is easier for people who have to work across the differ architectures.
|
|
|
|
There is another really big difference between the two chip header files:
|
|
They also different in scope:
|
|
|
|
1. Code in the ``arch/arm/src/xyz`` and in ``boards/arm/xyz/abc/src``
|
|
directories can both include the ``arch/arm/src/xyz/chip.h`` header file,
|
|
but nothing else can (only because nothing else is provided the header
|
|
file path in the build system). So that ``chip.h`` file is intended to be
|
|
used only in low-level board/chip logic.
|
|
2. The ``chip.h`` header file at ``arch/arm/include/xyz/chip.h``,
|
|
on the other hand, will be linked at include/arch/chip and, hence,
|
|
can be included anywhere in the system, even from applications.
|
|
It can be included like::
|
|
|
|
#include <arch/chip/chip.h>
|
|
|
|
So the ``arch/arm/include/xyz/chip.h`` header file is a place where you would
|
|
want to put chip-related stuff that can be made visible to application code.
|
|
Chip capabilities is a good example of the kind of knowledge that
|
|
applications might care about.
|