This allows concurrent read access, which are much more common; reducing
potential lock contention and increasing concurrency.
Taking a lock is expensive, and the reader lock is now even more expensive.
An RCU synchronization scheme would reduce the overhead of the readers to
increasing/decreasing an atomic counter.
Thus this should only be an intermediate step until we move towards RCU.
Tested on SITL & Pixracer.
param_t is only used as an offset and we have <1000 params, so an uint16_t
is enough.
This saves roughly 1KB of RAM. We only do that on NuttX because normal
integers have better performance in general.
Previously on amd64, this was even 64bits because it was an uintptr_t.
If param_find() returned PARAM_INVALID, and this was directly passed to
param_get(), param_get_value_ptr() returned null and we read garbage data
(or segfaulted on systems with virtual memory).
On px4fmu-v2, this happened for the param ATT_VIBE_THRESH in sensors.
Because of the recently added parameter scoping, this param got pruned, as
it's defined in attitude_estimator_q.
credits for finding this go to Jeyong Shin (jeyong).
We need to protect access to the param_values array. This is dynamically
allocated and resized (utarray_reserve() calls realloc). If some thread
was iterating the array while another was resizing the array, the first one
would iterate on a freed array, thus accessing invalid memory.
On NuttX this could lead to hardfaults in rare conditions.
Unfortunately we need to initialize the semaphore on startup, by calling
sem_init(). This adds a param_init() method called by every board/config
that uses the params (at least I think I've found all of them)
This patch reorders px4_defines.h to make it more readable (I think)
but more importantly, cleans up the #include <math.h>/<cmath>
and [std::]isfinite stuff.
My main goal was to completely get rid of including math.h/cmath,
because that doesn't really belong in a header that is supposed to
define macro's and is included in almost every source file (if not
all).
I'm not sure what it did before ;) (pun intended), but now it does
the following:
PX4_ISFINITE is only used in C++ code (that was already the case,
but hereby is official; for C code just use 'isfinite()') and is
defined to be std::isfinite, except on __PX4_QURT because that uses
the HEXAGON toolset which (erroneously) defines isfinite as macro.
I would have liked to remove PX4_ISFINITE completely from the code
and just use std::isfinite whereever that is needed, but that would
have required changing the libecl submodule, and at the moment I'm
getting tired of changing submodules... so maybe something for the
future.
Also, all includes of <math.h> or <cmath> have been removed except
for __PX4_NUTTX. Like the HEXAGON toolset NuttX currently defines
isfinite as macro for C++. So, we could have solved this in the
same was as __P4_QURT; but since we can fix NuttX ourselves I chose
to add a kludge to px4_defines.h instead that fixes this problem,
until the time that NuttX can be fixed (again postponing changing
a submodule). The kludge still demands including <cmath>, thus.
After removal of the math header file, it needed to be included
in source files that actually need it, of course.
Finally, I had a look at the math macro's (like M_PI, M_PI_F,
M_DEG_TO_RAD etc). These are sometimes (erroneously) defined in
certain math.h header files (like both, hexagon and nuttx).
This is incorrect: neither the C nor the C++ standard defines
math constants (neither as macro nor otherwise). The "problem"
here was that px4_defines.h defined some of the M_*_F float
constants in terms of the M_* double constant, which are
sometimes not defined either thus. So, I cleaned this up by
defining the M_*_F math constants as float literals in px4_defines.h,
except when they are defined in math.h for that platform.
This means that math.h has to be always included when using those
constants, but well; not much difference there as those files
usually also need/use the macro NAN (which *is* a standard macro
defined by math.h).
Finally finally, DEFAULT_PARAM_FILE was removed as it isn't
used anymore.
All in all I think the resulting px4_defines.h is nice, giving me
much less the feeling of a nearly unmaintainable and over time
slowly growing collection of kludges and hacks.
Since the FRAM and the baro are on the same bus on the Pixracer, we
currently need to lock down everything (instead of just this SPI bus)
for the time when the params are written.
Therefore, we need to keep this locking as short as possible.
This change makes the locking even shorter by moving all param_get and
param_name and param_size calls out of the lock.
There was the case where a param was changed on the Linux side but the
change did not get saved on the DSP side because the param was not in
the local list of changed params on the DSP side. On save, the param
index is now refreshed, and param_get is called on all params that have
changed. This is a hacky workaround but resolves the problem for now.
The recent workaround to flag all params as used did not include
param_for_used_index(). However, this function got used in the case if
one param had not been received by QGC and was requested by its index.
On Snapdragon we can't yet use the "used" mask for parameters and
therefore need to send all of them down to the ground station. All
params were set to used in an earlier commit but the count and index
function didn't reflect this change. This is fixed now, therefore we can
successfully receive all params in QGC.
This is a workaround for the fact that the used information is not
shared between the ADSP and the Linux side on the Snapdragon. By
flagging all params used, we can at least receive them on QGC.