mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 02:48:37 +08:00
Compare commits
23 commits
dea8f73134
...
d9a766582a
Author | SHA1 | Date | |
---|---|---|---|
|
d9a766582a | ||
|
e26e8bda0e | ||
|
7d6b2e4804 | ||
|
7548db1980 | ||
|
02828921db | ||
|
e039fa039d | ||
|
bbd6931d61 | ||
|
a58d6552e6 | ||
|
1701ca1e11 | ||
|
0d4e36ce29 | ||
|
0af01312fd | ||
|
2badabfb67 | ||
|
8fcdae3544 | ||
|
092f4a1b79 | ||
|
16789ed818 | ||
|
a8cdd63d56 | ||
|
203fb15c2e | ||
|
23e0b70290 | ||
|
2b34c61c6e | ||
|
67b95d0142 | ||
|
0fe3aebd6a | ||
|
035fdb4951 | ||
|
d36ddb5790 |
59 changed files with 2102 additions and 421 deletions
|
@ -85,7 +85,7 @@ And you can do distclean by following command.
|
|||
Step4 : Compile
|
||||
---------------
|
||||
|
||||
Try to buid with the implementation of Step1-2, you would face the error as following
|
||||
Try to build with the implementation of Step1-2, you would face the error as following
|
||||
if you implemented only directory / Kconfig / Make.defs / Makefile / defconfig about Step1-2.
|
||||
|
||||
.. code-block::
|
||||
|
@ -178,7 +178,7 @@ Step6 : Implement
|
|||
-----------------
|
||||
|
||||
There are some implementation items, major items are bellow listed. To pass the Linking,
|
||||
try to implement these symboles.
|
||||
try to implement these symbols.
|
||||
|
||||
+-----------------+------------------------+--------------------------------------------------------------------+
|
||||
| Category | Item | Comment |
|
||||
|
@ -201,7 +201,7 @@ try to implement these symboles.
|
|||
.. _apache/nuttx/pull/12441: https://github.com/apache/nuttx/pull/12441
|
||||
.. _sched/Kconfig: https://github.com/apache/nuttx/blob/master/sched/Kconfig
|
||||
|
||||
If got the pass of Linking, you would see follwoing result.
|
||||
If got the pass of Linking, you would see following result.
|
||||
|
||||
.. code-block::
|
||||
|
||||
|
@ -216,7 +216,7 @@ If got the pass of Linking, you would see follwoing result.
|
|||
Step7 : Verify
|
||||
--------------
|
||||
|
||||
To execute and debug on the evalutaion board, add following configurations.
|
||||
To execute and debug on the evaluation board, add following configurations.
|
||||
|
||||
.. code-block::
|
||||
|
||||
|
@ -232,7 +232,7 @@ If your implementations were good, you would see following logs.
|
|||
nsh>
|
||||
nsh>
|
||||
|
||||
After comfirming to boot NuttShell(NSH), try to execute "apps/testing/ostest".
|
||||
After confirming to boot NuttShell(NSH), try to execute "apps/testing/ostest".
|
||||
The "apps/testing/ostest" needs following configurations.
|
||||
|
||||
.. code-block::
|
||||
|
@ -242,7 +242,7 @@ The "apps/testing/ostest" needs following configurations.
|
|||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
|
||||
And one more test is recomended to check the timer implementation whether
|
||||
And one more test is recommended to check the timer implementation whether
|
||||
the kernel could count the time accurately or not.
|
||||
I checked it by following code. About the function : cxd32_timerget(),
|
||||
see `apache/nuttx/pull/12441`_
|
||||
|
@ -406,7 +406,7 @@ Appendix : out-of-tree code
|
|||
+ string "Program name"
|
||||
+ default "time"
|
||||
+ ---help---
|
||||
+ This apps measures the elasped time of sleep system call to confirm the timer implementation.
|
||||
+ This apps measures the elapsed time of sleep system call to confirm the timer implementation.
|
||||
+
|
||||
+config CXD32XX_APPS_TIME_PRIORITY
|
||||
+ int "CXD32XX Time task priority"
|
||||
|
@ -478,7 +478,7 @@ Appendix : out-of-tree code
|
|||
+ uint32_t pre;
|
||||
+ uint32_t post;
|
||||
+
|
||||
+ printf("measures the elasped time of sleep system call to confirm \
|
||||
+ printf("measures the elapsed time of sleep system call to confirm \
|
||||
+ the timer implementation.\n");
|
||||
+
|
||||
+ pre = cxd32_timerget();
|
||||
|
|
|
@ -158,6 +158,7 @@ config ARCH_XTENSA
|
|||
select ARCH_HAVE_INTERRUPTSTACK
|
||||
select ARCH_HAVE_STACKCHECK
|
||||
select ARCH_HAVE_CUSTOMOPT
|
||||
select ARCH_HAVE_THREAD_LOCAL
|
||||
select ARCH_HAVE_TCBINFO
|
||||
select ARCH_HAVE_STDARG_H
|
||||
select ARCH_HAVE_SETJMP if ARCH_TOOLCHAIN_GNU
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1
|
||||
static volatile cpu_set_t g_gic_init_done;
|
||||
static atomic_t g_gic_init_done;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -72,11 +72,7 @@ static volatile cpu_set_t g_gic_init_done;
|
|||
#if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1
|
||||
static void arm_gic_init_done(void)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
CPU_SET(this_cpu(), &g_gic_init_done);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
atomic_fetch_or(&g_gic_init_done, 1 << this_cpu());
|
||||
}
|
||||
|
||||
static void arm_gic_wait_done(cpu_set_t cpuset)
|
||||
|
@ -85,7 +81,7 @@ static void arm_gic_wait_done(cpu_set_t cpuset)
|
|||
|
||||
do
|
||||
{
|
||||
CPU_AND(&tmpset, &g_gic_init_done, &cpuset);
|
||||
tmpset = (cpu_set_t)atomic_read(&g_gic_init_done) & cpuset;
|
||||
}
|
||||
while (!CPU_EQUAL(&tmpset, &cpuset));
|
||||
}
|
||||
|
|
|
@ -33,9 +33,7 @@ set(SRCS
|
|||
arm_getintstack.c
|
||||
arm_initialize.c
|
||||
arm_lowputs.c
|
||||
arm_modifyreg8.c
|
||||
arm_modifyreg16.c
|
||||
arm_modifyreg32.c
|
||||
arm_modifyreg.c
|
||||
arm_nputs.c
|
||||
arm_releasestack.c
|
||||
arm_registerdump.c
|
||||
|
|
|
@ -24,9 +24,8 @@
|
|||
|
||||
CMN_CSRCS += arm_allocateheap.c arm_createstack.c arm_exit.c
|
||||
CMN_CSRCS += arm_getintstack.c arm_initialize.c arm_lowputs.c
|
||||
CMN_CSRCS += arm_modifyreg8.c arm_modifyreg16.c arm_modifyreg32.c
|
||||
CMN_CSRCS += arm_nputs.c arm_releasestack.c arm_registerdump.c
|
||||
CMN_CSRCS += arm_stackframe.c
|
||||
CMN_CSRCS += arm_stackframe.c arm_modifyreg.c
|
||||
CMN_CSRCS += arm_usestack.c arm_fork.c
|
||||
|
||||
ifneq ($(CONFIG_ALARM_ARCH),y)
|
||||
|
|
107
arch/arm/src/common/arm_modifyreg.c
Normal file
107
arch/arm/src/common/arm_modifyreg.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/arm_modifyreg.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg8
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint8_t regval;
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg8(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg8(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg16
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint16_t regval;
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg16(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg16(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg32
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg32(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg32(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
|
@ -196,6 +196,7 @@ struct imx_uart_s
|
|||
uint32_t ucr1; /* Saved UCR1 value */
|
||||
uint8_t irq; /* IRQ associated with this UART */
|
||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
uint8_t bits; /* Number of bits (7 or 8) */
|
||||
uint8_t stopbits2:1; /* 1: Configure with 2 stop bits vs 1 */
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
|
@ -295,6 +296,7 @@ static struct imx_uart_s g_uart1priv =
|
|||
.baud = CONFIG_UART1_BAUD,
|
||||
.irq = IMX_IRQ_UART1,
|
||||
.parity = CONFIG_UART1_PARITY,
|
||||
.lock = SP_UNLOCKED,
|
||||
.bits = CONFIG_UART1_BITS,
|
||||
.stopbits2 = CONFIG_UART1_2STOP,
|
||||
};
|
||||
|
@ -325,6 +327,7 @@ static struct imx_uart_s g_uart2priv =
|
|||
.baud = CONFIG_UART2_BAUD,
|
||||
.irq = IMX_IRQ_UART2,
|
||||
.parity = CONFIG_UART2_PARITY,
|
||||
.lock = SP_UNLOCKED
|
||||
.bits = CONFIG_UART2_BITS,
|
||||
.stopbits2 = CONFIG_UART2_2STOP,
|
||||
};
|
||||
|
@ -353,6 +356,7 @@ static struct imx_uart_s g_uart3priv =
|
|||
.baud = IMX_UART3_VBASE,
|
||||
.irq = IMX_IRQ_UART3,
|
||||
.parity = CONFIG_UART3_PARITY,
|
||||
.lock = SP_UNLOCKED
|
||||
.bits = CONFIG_UART3_BITS,
|
||||
.stopbits2 = CONFIG_UART3_2STOP,
|
||||
};
|
||||
|
@ -381,6 +385,7 @@ static struct imx_uart_s g_uart4priv =
|
|||
.baud = IMX_UART4_VBASE,
|
||||
.irq = IMX_IRQ_UART4,
|
||||
.parity = CONFIG_UART4_PARITY,
|
||||
.lock = SP_UNLOCKED
|
||||
.bits = CONFIG_UART4_BITS,
|
||||
.stopbits2 = CONFIG_UART4_2STOP,
|
||||
};
|
||||
|
@ -409,6 +414,7 @@ static struct imx_uart_s g_uart5priv =
|
|||
.baud = IMX_UART5_VBASE,
|
||||
.irq = IMX_IRQ_UART5,
|
||||
.parity = CONFIG_UART5_PARITY,
|
||||
.lock = SP_UNLOCKED
|
||||
.bits = CONFIG_UART5_BITS,
|
||||
.stopbits2 = CONFIG_UART5_2STOP,
|
||||
};
|
||||
|
@ -877,7 +883,7 @@ static int imx_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||
* implement TCSADRAIN / TCSAFLUSH
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
imx_disableuartint(priv, &ie);
|
||||
ret = imx_setup(dev);
|
||||
|
||||
|
@ -885,7 +891,7 @@ static int imx_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||
|
||||
imx_restoreuartint(priv, ie);
|
||||
priv->ie = ie;
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -267,6 +267,7 @@ struct imxrt_driver_s
|
|||
bool bifup; /* true:ifup false:ifdown */
|
||||
bool canfd_capable;
|
||||
int mb_address_offset;
|
||||
spinlock_t lock;
|
||||
#ifdef TX_TIMEOUT_WQ
|
||||
struct wdog_s txtimeout[TXMBCOUNT]; /* TX timeout timer */
|
||||
#endif
|
||||
|
@ -777,7 +778,7 @@ static int imxrt_txpoll(struct net_driver_s *dev)
|
|||
* the field d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
if (priv->dev.d_len > 0)
|
||||
{
|
||||
|
@ -793,12 +794,12 @@ static int imxrt_txpoll(struct net_driver_s *dev)
|
|||
|
||||
if (imxrt_txringfull(priv))
|
||||
{
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/* If zero is returned, the polling will continue until all connections
|
||||
* have been examined.
|
||||
|
@ -2032,6 +2033,7 @@ int imxrt_caninitialize(int intf)
|
|||
priv->dev.d_ioctl = imxrt_ioctl; /* Support CAN ioctl() calls */
|
||||
#endif
|
||||
priv->dev.d_private = (void *)priv; /* Used to recover private state from dev */
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
/* Put the interface in the down state. This usually amounts to resetting
|
||||
* the device and/or calling imxrt_ifdown().
|
||||
|
|
|
@ -169,6 +169,7 @@ struct litex_emac_s
|
|||
uint8_t phyaddr; /* PHY address (pre-defined by pins on reset) */
|
||||
|
||||
uint8_t txslot;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -511,7 +512,7 @@ static int litex_transmit(struct litex_emac_s *priv)
|
|||
|
||||
/* Make the following operations atomic */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
/* Now start transmission */
|
||||
|
||||
|
@ -528,7 +529,7 @@ static int litex_transmit(struct litex_emac_s *priv)
|
|||
wd_start(&priv->txtimeout, LITEX_TXTIMEOUT,
|
||||
litex_txtimeout_expiry, (wdparm_t)priv);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -1524,6 +1525,8 @@ static void litex_ethinitialize(void)
|
|||
return;
|
||||
}
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
nerr("ERROR: netdev_register() failed: %d\n", ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,8 @@ static void mpfs_callback(void *arg);
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_mpfs_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
struct mpfs_dev_s g_coremmc_dev =
|
||||
{
|
||||
.dev =
|
||||
|
@ -282,12 +284,12 @@ static void mpfs_modifyreg8(uintptr_t addr, uint8_t clearbits,
|
|||
irqstate_t flags;
|
||||
uint8_t regval;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_mpfs_modifyreg_lock);
|
||||
regval = getreg8(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg8(regval, addr);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_mpfs_modifyreg_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -224,6 +224,8 @@ static void mpfs_epset_reset(struct mpfs_usbdev_s *priv, uint16_t epset);
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_mpfs_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
static struct mpfs_usbdev_s g_usbd;
|
||||
static uint8_t g_clkrefs;
|
||||
|
||||
|
@ -297,12 +299,12 @@ static void mpfs_modifyreg16(uintptr_t addr, uint16_t clearbits,
|
|||
DEBUGASSERT((addr >= MPFS_USB_BASE) && addr < (MPFS_USB_BASE +
|
||||
MPFS_USB_REG_MAX));
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_mpfs_modifyreg_lock);
|
||||
regval = getreg16(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg16(regval, addr);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_mpfs_modifyreg_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -331,12 +333,12 @@ static void mpfs_modifyreg8(uintptr_t addr, uint8_t clearbits,
|
|||
DEBUGASSERT((addr >= MPFS_USB_BASE) && addr < (MPFS_USB_BASE +
|
||||
MPFS_USB_REG_MAX));
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_mpfs_modifyreg_lock);
|
||||
regval = getreg8(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg8(regval, addr);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_mpfs_modifyreg_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <nuttx/audio/audio_fake.h>
|
||||
#include <nuttx/kthread.h>
|
||||
#include <nuttx/motor/foc/foc_dummy.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
|
@ -298,6 +299,12 @@ void up_initialize(void)
|
|||
|
||||
audio_register("mixer", sim_audio_initialize(false, false));
|
||||
|
||||
#ifdef CONFIG_AUDIO_FAKE
|
||||
/* Register fake audio driver */
|
||||
|
||||
audio_fake_initialize();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_USB_DEV
|
||||
|
|
|
@ -94,8 +94,9 @@
|
|||
#define REG_SAR (18)
|
||||
#define REG_EXCCAUSE (19)
|
||||
#define REG_EXCVADDR (20)
|
||||
#define REG_THREADPTR (21)
|
||||
|
||||
#define _REG_EXTRA_START (21)
|
||||
#define _REG_EXTRA_START (22)
|
||||
|
||||
#if XCHAL_HAVE_S32C1I != 0
|
||||
# define REG_SCOMPARE1 (_REG_EXTRA_START + 0)
|
||||
|
|
|
@ -128,13 +128,14 @@
|
|||
|
||||
/* Tensilica-defined user registers: */
|
||||
|
||||
#define THREADPTR 231 /* threadptr option */
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
#define ... 21..24 /* (545CK) */
|
||||
#define ... 140..143 /* (545CK) */
|
||||
#endif
|
||||
#define EXPSTATE 230 /* Diamond */
|
||||
#define THREADPTR 231 /* threadptr option */
|
||||
#define FCR 232 /* FPU */
|
||||
#define FSR 233 /* FPU */
|
||||
#define AE_OVF_SAR 240 /* HiFi2 */
|
||||
|
|
|
@ -54,6 +54,10 @@ ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
|||
CMN_CSRCS += xtensa_backtrace.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
|
||||
CMN_CSRCS += xtensa_tls.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
CMN_CSRCS += xtensa_smpcall.c
|
||||
endif
|
||||
|
|
|
@ -144,6 +144,18 @@
|
|||
#define INTSTACK_COLOR 0xdeadbeef
|
||||
#define HEAP_COLOR 'h'
|
||||
|
||||
#define _START_TEXT _stext
|
||||
#define _END_TEXT _etext
|
||||
#define _START_BSS _sbss
|
||||
#define _END_BSS _ebss
|
||||
#define _DATA_INIT _eronly
|
||||
#define _START_DATA _sdata
|
||||
#define _END_DATA _edata
|
||||
#define _START_TDATA _stdata
|
||||
#define _END_TDATA _etdata
|
||||
#define _START_TBSS _stbss
|
||||
#define _END_TBSS _etbss
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
@ -177,6 +189,10 @@ extern uint8_t _sbss[]; /* Start of .bss */
|
|||
extern uint8_t _ebss[]; /* End+1 of .bss */
|
||||
extern uint8_t _sheap[]; /* Start of heap */
|
||||
extern uint8_t _eheap[]; /* End+1 of heap */
|
||||
extern uint8_t _stdata[]; /* Start of .tdata */
|
||||
extern uint8_t _etdata[]; /* End+1 of .tdata */
|
||||
extern uint8_t _stbss[]; /* Start of .tbss */
|
||||
extern uint8_t _etbss[]; /* End+1 of .tbss */
|
||||
extern uint8_t _sbss_extmem[]; /* start of external memory bss */
|
||||
extern uint8_t _ebss_extmem[]; /* End+1 of external memory bss */
|
||||
|
||||
|
|
|
@ -131,6 +131,9 @@ _xtensa_context_save:
|
|||
s32i a15, sp, (4 * REG_A15)
|
||||
#endif
|
||||
|
||||
rur a3, THREADPTR
|
||||
s32i a3, sp, (4 * REG_THREADPTR)
|
||||
|
||||
rsr a3, SAR
|
||||
s32i a3, sp, (4 * REG_SAR)
|
||||
|
||||
|
@ -276,6 +279,9 @@ _xtensa_context_restore:
|
|||
wsr a3, SCOMPARE1
|
||||
#endif
|
||||
|
||||
l32i a3, a2, (4 * REG_THREADPTR)
|
||||
wur a3, THREADPTR
|
||||
|
||||
l32i a3, a2, (4 * REG_SAR)
|
||||
wsr a3, SAR
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/nuttx.h>
|
||||
#include <arch/irq.h>
|
||||
#include <arch/xtensa/core.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
@ -39,6 +40,23 @@
|
|||
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||
# define TCB_SIZE 8
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern int _thread_local_start;
|
||||
extern int _thread_local_end;
|
||||
extern int _rodata_reserved_start;
|
||||
extern int _rodata_reserved_align;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -59,6 +77,10 @@
|
|||
void up_initial_state(struct tcb_s *tcb)
|
||||
{
|
||||
struct xcptcontext *xcp = &tcb->xcp;
|
||||
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||
const uint32_t base = ALIGN_UP((uint32_t)&_rodata_reserved_align,
|
||||
TCB_SIZE);
|
||||
#endif
|
||||
|
||||
/* Initialize the initial exception register context structure */
|
||||
|
||||
|
@ -100,6 +122,116 @@ void up_initial_state(struct tcb_s *tcb)
|
|||
xcp->regs[REG_A1] = (uint32_t)tcb->stack_base_ptr + /* Physical top of stack frame */
|
||||
tcb->adj_stack_size;
|
||||
|
||||
/* Each task access the TLS variables using the THREADPTR register plus an
|
||||
* offset to obtain the address of the variable.
|
||||
*
|
||||
* TLS layout at link-time (on flash), where 0xNNN is the offset that the
|
||||
* linker calculates to a particular TLS variable:
|
||||
*
|
||||
* LOW ADDRESS
|
||||
* |---------------------------| Linker Symbols
|
||||
* | Section | --------------
|
||||
* | .flash.rodata |
|
||||
* 0x0|---------------------------| <- _rodata_reserved_start
|
||||
* ^ | Other Data |
|
||||
* | |---------------------------| <- _thread_local_start
|
||||
* | | .tdata | ^ ^
|
||||
* | | | | |
|
||||
* | | | | Offset from |
|
||||
* | | | | TLS start |
|
||||
* | | | | | tls_area_size
|
||||
* V | | V |
|
||||
* 0xNNN | int example; | |
|
||||
* | | |
|
||||
* | | |
|
||||
* | .tbss | V
|
||||
* |---------------------------| <- _thread_local_end
|
||||
* | Other data |
|
||||
* | ... |
|
||||
* |---------------------------|
|
||||
* HIGH ADDRESS
|
||||
*
|
||||
* Consider the TLS variable `example`. Its location is calculated as:
|
||||
*
|
||||
* &example = &_rodata_reserved_start + 0xNNN
|
||||
*
|
||||
* And the offset 0xNNN can be calculated as:
|
||||
*
|
||||
* 0xNNN = (&_thread_local_start - &_rodata_reserved_start) +
|
||||
* Offset from TLS start
|
||||
*
|
||||
* Consider the following diagram for the stack layout:
|
||||
*
|
||||
* Note: the following diagram shows the stack layout for a particular task
|
||||
* and the memory grows towards the stack base (lower memory addresses).
|
||||
*
|
||||
* HIGH ADDRESS
|
||||
* |---------------------------| <- Top of the stack
|
||||
* | |
|
||||
* | |
|
||||
* |---------------------------| <- Base of the stack
|
||||
* | .tbss (*) |
|
||||
* | |
|
||||
* | |
|
||||
* | int example; |
|
||||
* ^ | | ^
|
||||
* | | | | Offset from TLS start
|
||||
* | | .tdata (*) | V
|
||||
* | |---------------------------| <- Start of the TLS area
|
||||
* 0xNNN | | | ^
|
||||
* | | | |
|
||||
* | | ... | | (_thread_local_start -
|
||||
* | | | | _rodata_reserved_start)
|
||||
* | | | | + align_up(TCB_SIZE,
|
||||
* | | | | tls_section_align)
|
||||
* | | | |
|
||||
* | | | V
|
||||
* V | | <- threadptr register's value
|
||||
*
|
||||
* LOW ADDRESS
|
||||
*
|
||||
* At run-time, each task accesses the TLS variables using the THREADPTR
|
||||
* register plus an offset to obtain the address of the variable.
|
||||
*
|
||||
* &example = THREADPTR + 0xNNN (calculated at link-time)
|
||||
*
|
||||
* Similarly, example can be accessed as:
|
||||
*
|
||||
* &example = Start of the TLS area + Offset from TLS start
|
||||
*
|
||||
* The start of the TLS area is given by (check xtensa_tls.c):
|
||||
*
|
||||
* Start of the TLS area = tcb->stack_alloc_ptr +
|
||||
* sizeof(struct tls_info_s)
|
||||
*
|
||||
* Calculate the THREADPTR register's initialization value based on the
|
||||
* link-time offset and the TLS area allocated on the stack.
|
||||
*
|
||||
* THREADPTR = &example - 0xNNN
|
||||
* THREADPTR = (tcb->stack_alloc_ptr + sizeof(struct tls_info_s)) +
|
||||
* Offset from TLS start - 0xNNN
|
||||
*
|
||||
* And, finally, based on 0xNNN calculated at link-time:
|
||||
*
|
||||
* THREADPTR = (tcb->stack_alloc_ptr + sizeof(struct tls_info_s)) -
|
||||
* (&_thread_local_start - &_rodata_reserved_start) - base
|
||||
*
|
||||
* Note: Xtensa is slightly different compared to the RISC-V port as there
|
||||
* is an implicit aligned TCB_SIZE added to the offset.
|
||||
* - "offset = address - tls_section_vma +
|
||||
* align_up(TCB_SIZE, tls_section_align)"
|
||||
* - TCB_SIZE is hardcoded to 8
|
||||
* Refer to https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/
|
||||
* elf32-xtensa.c;h=f078cbde7146675fd2ed82eb5102ae2596c20775;hb=HEAD#l1830
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||
xcp->regs[REG_THREADPTR] = (uintptr_t)tcb->stack_alloc_ptr +
|
||||
sizeof(struct tls_info_s) -
|
||||
((uint32_t)&_thread_local_start -
|
||||
(uint32_t)&_rodata_reserved_start) - base;
|
||||
#endif
|
||||
|
||||
/* Set initial PS to int level 0, user mode. */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
|
|
@ -79,6 +79,8 @@ int up_saveusercontext(void *saveregs)
|
|||
" s32i a14, %0, (4 * " STRINGIFY(REG_A14) ")\n"
|
||||
" s32i a15, %0, (4 * " STRINGIFY(REG_A15) ")\n"
|
||||
#endif
|
||||
" rur a2, THREADPTR\n"
|
||||
" s32i a2, %0, (4 * " STRINGIFY(THREADPTR) ")\n"
|
||||
" rsr a2, SAR\n"
|
||||
" s32i a2, %0, (4 * " STRINGIFY(REG_SAR) ")\n"
|
||||
#if XCHAL_HAVE_S32C1I != 0
|
||||
|
|
74
arch/xtensa/src/common/xtensa_tls.c
Normal file
74
arch/xtensa/src/common/xtensa_tls.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/****************************************************************************
|
||||
* arch/xtensa/src/common/xtensa_tls.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/tls.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_tls_size
|
||||
*
|
||||
* Description:
|
||||
* Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
|
||||
*
|
||||
* Returned Value:
|
||||
* Size of (sizeof(struct tls_info_s) + tdata + tbss).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_tls_size(void)
|
||||
{
|
||||
size_t size_tls_info_s = sizeof(struct tls_info_s);
|
||||
size_t size_tsec = (_END_TBSS - _START_TDATA);
|
||||
|
||||
return size_tls_info_s + size_tsec;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_tls_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize thread local region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* info - The TLS structure to initialize.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_tls_initialize(struct tls_info_s *info)
|
||||
{
|
||||
uint8_t *tls_data = (uint8_t *)(info + 1);
|
||||
|
||||
uint32_t tdata_len = (_END_TDATA - _START_TDATA);
|
||||
uint32_t tbss_len = (_END_TBSS - _START_TBSS);
|
||||
|
||||
memcpy(tls_data, _START_TDATA, tdata_len);
|
||||
memset(tls_data + tdata_len, 0, tbss_len);
|
||||
}
|
|
@ -126,6 +126,7 @@ typedef struct
|
|||
unsigned int ram_block: 16;
|
||||
} rangeblock_t;
|
||||
|
||||
static spinlock_t g_descriptor_lock = SP_UNLOCKED;
|
||||
static ramblock_t *g_ram_descriptor = NULL;
|
||||
static rangeblock_t *g_range_descriptor = NULL;
|
||||
static int g_ramblockcnt = 0;
|
||||
|
@ -325,11 +326,11 @@ int esp_himem_alloc(size_t size, esp_himem_handle_t *handle_out)
|
|||
goto nomem;
|
||||
}
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
ok = allocate_blocks(blocks, r->block);
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
if (!ok)
|
||||
{
|
||||
goto nomem;
|
||||
|
@ -365,13 +366,13 @@ int esp_himem_free(esp_himem_handle_t handle)
|
|||
|
||||
/* Mark blocks as free */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
for (i = 0; i < handle->block_ct; i++)
|
||||
{
|
||||
g_ram_descriptor[handle->block[i]].is_alloced = false;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* Free handle */
|
||||
|
||||
|
@ -407,7 +408,7 @@ int esp_himem_alloc_map_range(size_t size,
|
|||
r->block_start = -1;
|
||||
|
||||
start_free = 0;
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < g_rangeblockcnt; i++)
|
||||
{
|
||||
|
@ -431,10 +432,11 @@ int esp_himem_alloc_map_range(size_t size,
|
|||
|
||||
if (r->block_start == -1)
|
||||
{
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* Couldn't find enough free blocks */
|
||||
|
||||
kmm_free(r);
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -445,7 +447,7 @@ int esp_himem_alloc_map_range(size_t size,
|
|||
g_range_descriptor[r->block_start + i].is_alloced = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* All done. */
|
||||
|
||||
|
@ -474,14 +476,14 @@ int esp_himem_free_map_range(esp_himem_rangehandle_t handle)
|
|||
|
||||
/* We should be good to free this. Mark blocks as free. */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < handle->block_ct; i++)
|
||||
{
|
||||
g_range_descriptor[i + handle->block_start].is_alloced = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
kmm_free(handle);
|
||||
return OK;
|
||||
}
|
||||
|
@ -537,7 +539,7 @@ int esp_himem_map(esp_himem_handle_t handle,
|
|||
|
||||
/* Map and mark as mapped */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
|
@ -548,7 +550,7 @@ int esp_himem_map(esp_himem_handle_t handle,
|
|||
handle->block[i + ram_block];
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
|
@ -589,7 +591,7 @@ int esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr,
|
|||
HIMEM_CHECK(range_block + blockcount > range->block_ct,
|
||||
"range out of bounds for handle", -EINVAL);
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
|
@ -602,7 +604,7 @@ int esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr,
|
|||
}
|
||||
|
||||
esp_spiram_writeback_cache();
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,13 @@
|
|||
#define EXPECTED_IDLE_TIME_US (800)
|
||||
#define EARLY_WAKEUP_US (200)
|
||||
|
||||
#endif
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static spinlock_t g_esp32_idle_lock = SP_UNLOCKED;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -109,7 +116,7 @@ static void esp32_idlepm(void)
|
|||
irqstate_t flags;
|
||||
|
||||
#ifdef CONFIG_ESP32_AUTO_SLEEP
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_esp32_idle_lock);
|
||||
if (esp32_pm_lockstatus() == 0)
|
||||
{
|
||||
uint64_t os_start_us;
|
||||
|
@ -155,7 +162,7 @@ static void esp32_idlepm(void)
|
|||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_esp32_idle_lock, flags);
|
||||
#else /* CONFIG_ESP32_AUTO_SLEEP */
|
||||
static enum pm_state_e oldstate = PM_NORMAL;
|
||||
enum pm_state_e newstate;
|
||||
|
@ -169,7 +176,7 @@ static void esp32_idlepm(void)
|
|||
|
||||
if (newstate != oldstate)
|
||||
{
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_esp32_idle_lock);
|
||||
|
||||
/* Perform board-specific, state-dependent logic here */
|
||||
|
||||
|
@ -191,7 +198,7 @@ static void esp32_idlepm(void)
|
|||
oldstate = newstate;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_esp32_idle_lock, flags);
|
||||
|
||||
/* MCU-specific power management logic */
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ struct esp32_lowerhalf_s
|
|||
*/
|
||||
|
||||
const struct rtc_ops_s *ops;
|
||||
spinlock_t lock;
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* Alarm callback information */
|
||||
|
||||
|
@ -116,6 +117,7 @@ static const struct rtc_ops_s g_rtc_ops =
|
|||
static struct esp32_lowerhalf_s g_rtc_lowerhalf =
|
||||
{
|
||||
.ops = &g_rtc_ops,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -376,6 +378,7 @@ static int rtc_lh_setalarm(struct rtc_lowerhalf_s *lower,
|
|||
static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
||||
const struct lower_setrelative_s *alarminfo)
|
||||
{
|
||||
struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
|
||||
struct lower_setalarm_s setalarm;
|
||||
time_t seconds;
|
||||
int ret = -EINVAL;
|
||||
|
@ -387,7 +390,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
|||
|
||||
if (alarminfo->reltime > 0)
|
||||
{
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
seconds = alarminfo->reltime;
|
||||
gmtime_r(&seconds, (struct tm *)&setalarm.time);
|
||||
|
@ -399,7 +402,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
|||
setalarm.priv = alarminfo->priv;
|
||||
ret = rtc_lh_setalarm(lower, &setalarm);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -466,6 +469,7 @@ static int rtc_lh_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
|
|||
static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower,
|
||||
struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
irqstate_t flags;
|
||||
|
@ -474,13 +478,13 @@ static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower,
|
|||
DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) &&
|
||||
(alarminfo->id < RTC_ALARM_LAST));
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
ret = up_rtc_rdalarm(&ts, alarminfo->id);
|
||||
localtime_r((const time_t *)&ts.tv_sec,
|
||||
(struct tm *)alarminfo->time);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,14 @@
|
|||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static spinlock_t g_esp32s2_idle_lock = SP_UNLOCKED;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -86,7 +94,7 @@ static void up_idlepm(void)
|
|||
|
||||
if (newstate != oldstate)
|
||||
{
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_esp32s2_idle_lock);
|
||||
|
||||
/* Perform board-specific, state-dependent logic here */
|
||||
|
||||
|
@ -108,7 +116,7 @@ static void up_idlepm(void)
|
|||
oldstate = newstate;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_esp32s2_idle_lock, flags);
|
||||
|
||||
/* MCU-specific power management logic */
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ struct esp32s2_uart_s g_uart0_config =
|
|||
.rs485_dir_polarity = true,
|
||||
#endif
|
||||
#endif
|
||||
.lock = SP_UNLOCKED;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ESP32S2_UART0 */
|
||||
|
@ -146,6 +147,7 @@ struct esp32s2_uart_s g_uart1_config =
|
|||
.rs485_dir_polarity = true,
|
||||
#endif
|
||||
#endif
|
||||
.lock = SP_UNLOCKED;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ESP32S2_UART1 */
|
||||
|
@ -654,7 +656,7 @@ void esp32s2_lowputc_disable_all_uart_int(const struct esp32s2_uart_s *priv,
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
if (current_status != NULL)
|
||||
{
|
||||
|
@ -671,7 +673,7 @@ void esp32s2_lowputc_disable_all_uart_int(const struct esp32s2_uart_s *priv,
|
|||
|
||||
putreg32(UINT32_MAX, UART_INT_CLR_REG(priv->id));
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -106,6 +106,7 @@ struct esp32s2_uart_s
|
|||
uint8_t rs485_dir_gpio; /* UART RS-485 DIR GPIO pin cfg */
|
||||
bool rs485_dir_polarity; /* UART RS-485 DIR TXEN polarity */
|
||||
#endif
|
||||
spinlock_t lock; /* Spinlock */
|
||||
};
|
||||
|
||||
extern struct esp32s2_uart_s g_uart0_config;
|
||||
|
|
|
@ -61,6 +61,7 @@ struct esp32s2_lowerhalf_s
|
|||
*/
|
||||
|
||||
const struct rtc_ops_s *ops;
|
||||
spinlock_t lock;
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* Alarm callback information */
|
||||
|
||||
|
@ -115,6 +116,7 @@ static const struct rtc_ops_s g_rtc_ops =
|
|||
static struct esp32s2_lowerhalf_s g_rtc_lowerhalf =
|
||||
{
|
||||
.ops = &g_rtc_ops,
|
||||
.lock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -375,6 +377,7 @@ static int rtc_lh_setalarm(struct rtc_lowerhalf_s *lower,
|
|||
static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
||||
const struct lower_setrelative_s *alarminfo)
|
||||
{
|
||||
struct esp32s2_lowerhalf_s *priv = (struct esp32s2_lowerhalf_s *)lower;
|
||||
struct lower_setalarm_s setalarm;
|
||||
time_t seconds;
|
||||
int ret = -EINVAL;
|
||||
|
@ -386,7 +389,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
|||
|
||||
if (alarminfo->reltime > 0)
|
||||
{
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
seconds = alarminfo->reltime;
|
||||
gmtime_r(&seconds, (struct tm *)&setalarm.time);
|
||||
|
@ -398,7 +401,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower,
|
|||
setalarm.priv = alarminfo->priv;
|
||||
ret = rtc_lh_setalarm(lower, &setalarm);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -465,6 +468,7 @@ static int rtc_lh_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
|
|||
static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower,
|
||||
struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
struct esp32s2_lowerhalf_s *priv = (struct esp32s2_lowerhalf_s *)lower;
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
irqstate_t flags;
|
||||
|
@ -473,13 +477,13 @@ static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower,
|
|||
DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) &&
|
||||
(alarminfo->id < RTC_ALARM_LAST));
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
ret = up_rtc_rdalarm(&ts, alarminfo->id);
|
||||
localtime_r((const time_t *)&ts.tv_sec,
|
||||
(struct tm *)alarminfo->time);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ static int himem_ioctl(struct file *filep, int cmd,
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_descriptor_lock = SP_UNLOCKED;
|
||||
static ramblock_t *g_ram_descriptor = NULL;
|
||||
static rangeblock_t *g_range_descriptor = NULL;
|
||||
static int g_ramblockcnt = 0;
|
||||
|
@ -626,11 +627,11 @@ int esp_himem_alloc(size_t size, esp_himem_handle_t *handle_out)
|
|||
goto nomem;
|
||||
}
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
ok = allocate_blocks(blocks, r->block);
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
if (!ok)
|
||||
{
|
||||
goto nomem;
|
||||
|
@ -682,13 +683,13 @@ int esp_himem_free(esp_himem_handle_t handle)
|
|||
|
||||
/* Mark blocks as free */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
for (i = 0; i < handle->block_ct; i++)
|
||||
{
|
||||
g_ram_descriptor[handle->block[i]].is_alloced = false;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* Free handle */
|
||||
|
||||
|
@ -742,7 +743,7 @@ int esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t
|
|||
r->block_start = -1;
|
||||
|
||||
start_free = 0;
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < g_rangeblockcnt; i++)
|
||||
{
|
||||
|
@ -766,10 +767,11 @@ int esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t
|
|||
|
||||
if (r->block_start == -1)
|
||||
{
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* Couldn't find enough free blocks */
|
||||
|
||||
kmm_free(r);
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -780,7 +782,7 @@ int esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t
|
|||
g_range_descriptor[r->block_start + i].is_alloced = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
|
||||
/* All done. */
|
||||
|
||||
|
@ -826,14 +828,14 @@ int esp_himem_free_map_range(esp_himem_rangehandle_t handle)
|
|||
|
||||
/* We should be good to free this. Mark blocks as free. */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < handle->block_ct; i++)
|
||||
{
|
||||
g_range_descriptor[i + handle->block_start].is_alloced = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
kmm_free(handle);
|
||||
return OK;
|
||||
}
|
||||
|
@ -917,7 +919,7 @@ int esp_himem_map(esp_himem_handle_t handle,
|
|||
|
||||
/* Map and mark as mapped */
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
|
@ -928,7 +930,7 @@ int esp_himem_map(esp_himem_handle_t handle,
|
|||
handle->block[i + ram_block];
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
virt_bank = himem_mmu_start + range->block_start + i + range_block;
|
||||
|
@ -983,7 +985,7 @@ int esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr, size_t len)
|
|||
HIMEM_CHECK(range_block + blockcount > range->block_ct,
|
||||
"range out of bounds for handle", -EINVAL);
|
||||
|
||||
spinlock_flags = spin_lock_irqsave(NULL);
|
||||
spinlock_flags = spin_lock_irqsave(&g_descriptor_lock);
|
||||
|
||||
for (i = 0; i < blockcount; i++)
|
||||
{
|
||||
|
@ -996,7 +998,7 @@ int esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr, size_t len)
|
|||
}
|
||||
|
||||
esp_spiram_writeback_cache();
|
||||
spin_unlock_irqrestore(NULL, spinlock_flags);
|
||||
spin_unlock_irqrestore(&g_descriptor_lock, spinlock_flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,14 @@
|
|||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static spinlock_t g_esp32s3_idle_lock = SP_UNLOCKED;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -91,7 +99,7 @@ static void up_idlepm(void)
|
|||
|
||||
if (newstate != oldstate)
|
||||
{
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_esp32s3_idle_lock);
|
||||
|
||||
/* Perform board-specific, state-dependent logic here */
|
||||
|
||||
|
@ -113,7 +121,7 @@ static void up_idlepm(void)
|
|||
oldstate = newstate;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_esp32s3_idle_lock, flags);
|
||||
|
||||
/* MCU-specific power management logic */
|
||||
|
||||
|
|
|
@ -403,6 +403,7 @@ SECTIONS
|
|||
|
||||
.flash.rodata :
|
||||
{
|
||||
_rodata_reserved_start = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
_srodata = ABSOLUTE(.);
|
||||
*(EXCLUDE_FILE (*libarch.a:esp32_spiflash.* *libarch.a:esp32_spicache.*
|
||||
|
@ -469,8 +470,24 @@ SECTIONS
|
|||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
|
||||
/* TLS data. */
|
||||
|
||||
. = ALIGN(4);
|
||||
_thread_local_start = ABSOLUTE(.);
|
||||
|
||||
_stdata = ABSOLUTE(.);
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||
_etdata = ABSOLUTE(.);
|
||||
_stbss = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||
_etbss = ABSOLUTE(.);
|
||||
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
} >default_rodata_seg AT>ROM
|
||||
_rodata_reserved_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
_image_irom_vma = ADDR(.flash.text);
|
||||
_image_irom_lma = LOADADDR(.flash.text);
|
||||
|
|
|
@ -38,6 +38,7 @@ CONFIG_PREALLOC_TIMERS=4
|
|||
CONFIG_RAM_SIZE=114688
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_THREAD_LOCAL=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_START_DAY=6
|
||||
|
|
|
@ -315,6 +315,8 @@ SECTIONS
|
|||
|
||||
.flash.rodata :
|
||||
{
|
||||
_rodata_reserved_start = ABSOLUTE(.);
|
||||
|
||||
_srodata = ABSOLUTE(.);
|
||||
*(EXCLUDE_FILE (esp32s2_start.*) .rodata)
|
||||
*(EXCLUDE_FILE (esp32s2_start.*) .rodata.*)
|
||||
|
@ -374,8 +376,23 @@ SECTIONS
|
|||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
/* TLS data. */
|
||||
|
||||
. = ALIGN(4);
|
||||
_thread_local_start = ABSOLUTE(.);
|
||||
|
||||
_stdata = ABSOLUTE(.);
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||
_etdata = ABSOLUTE(.);
|
||||
_stbss = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||
_etbss = ABSOLUTE(.);
|
||||
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
} >default_rodata_seg AT>ROM
|
||||
_rodata_reserved_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
_image_irom_vma = ADDR(.flash.text);
|
||||
_image_irom_lma = LOADADDR(.flash.text);
|
||||
|
|
|
@ -37,6 +37,7 @@ CONFIG_PREALLOC_TIMERS=4
|
|||
CONFIG_RAM_SIZE=114688
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_THREAD_LOCAL=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=6
|
||||
CONFIG_START_MONTH=12
|
||||
|
|
|
@ -523,9 +523,24 @@ SECTIONS
|
|||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
|
||||
/* TLS data. */
|
||||
|
||||
. = ALIGN(4);
|
||||
_thread_local_start = ABSOLUTE(.);
|
||||
|
||||
_stdata = ABSOLUTE(.);
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||
_etdata = ABSOLUTE(.);
|
||||
_stbss = ABSOLUTE(.);
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||
_etbss = ABSOLUTE(.);
|
||||
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
} >drom0_0_seg AT>ROM
|
||||
_rodata_reserved_align = ALIGNOF(.flash.rodata);
|
||||
|
||||
_image_irom_vma = ADDR(.flash.text);
|
||||
_image_irom_lma = LOADADDR(.flash.text);
|
||||
|
|
|
@ -40,6 +40,7 @@ CONFIG_PREALLOC_TIMERS=4
|
|||
CONFIG_RAM_SIZE=114688
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_THREAD_LOCAL=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SMP_NCPUS=2
|
||||
|
|
|
@ -69,6 +69,7 @@ set(DEQUOTELIST
|
|||
"CONFIG_TTY_LAUNCH_ENTRYPOINT" # Name of entry point from tty launch
|
||||
"CONFIG_TTY_LAUNCH_ARGS" # Argument list of entry point from tty launch
|
||||
"CONFIG_BOARD_MEMORY_RANGE" # Memory range for board
|
||||
"CONFIG_FAKE_AUDIO_DEVICE_PARAMS" # Arguments for the fake audio device
|
||||
# NxWidgets/NxWM
|
||||
"CONFIG_NXWM_BACKGROUND_IMAGE" # Name of bitmap image class
|
||||
"CONFIG_NXWM_CALIBRATION_ICON" # Name of bitmap image class
|
||||
|
|
|
@ -518,4 +518,52 @@ config AUDIO_DMA
|
|||
depends on AUDIO
|
||||
depends on DMA
|
||||
|
||||
config AUDIO_FAKE
|
||||
bool "Fake audio device"
|
||||
default n
|
||||
depends on AUDIO
|
||||
---help---
|
||||
A fake audio device driver to simplify testing of audio
|
||||
capture and playback.
|
||||
|
||||
if AUDIO_FAKE
|
||||
|
||||
config FAKE_AUDIO_DEVICE_PARAMS
|
||||
string "fake audio device params"
|
||||
default ""
|
||||
---help---
|
||||
This is a params for fake audio device. The format like:
|
||||
{dev_name, playback, sample_rates[4], channels, format[4], period_time, periods}.
|
||||
|
||||
- dev_name (string): pcm2c or pcm2p or others.
|
||||
- playback (bool): true or false.
|
||||
- sample_rates(uint32 array): {16000, 32000}.
|
||||
- channels (uint8, {min_chan, max_chan}): {1, 2}.
|
||||
- format(uint8 array): {8,16,32}.
|
||||
- period_time(uint32): 100, unit ms.
|
||||
- periods (uint32): 4, buffer cnt.
|
||||
e.g:
|
||||
{"pcm2c", false, {8000, 16000, 44100}, {1, 2}, {16}, 100, 4},
|
||||
{"pcm2p", true, {8000, 16000, 44100}, {1, 2}, {16}, 100, 4},
|
||||
|
||||
config FAKE_AUDIO_DATA_PATH
|
||||
string "fake audio device data path"
|
||||
default "/data/"
|
||||
---help---
|
||||
This dir is used to store the audio file for virtual capture or playback device.
|
||||
The filename for capture device should comply with the format "devname_samplerate_channels_format.pcm".
|
||||
e.g: pcm2c_16000_2_16.pcm.
|
||||
The filename format of playback device is the same as capture device.
|
||||
e.g: pcm2p_16000_2_16.pcm.
|
||||
|
||||
config AUDIO_FAKE_MSG_PRIO
|
||||
int "Fake audio device message priority"
|
||||
default 1
|
||||
|
||||
config AUDIO_FAKE_WORKER_STACKSIZE
|
||||
int "Fake audio device worker thread stack size"
|
||||
default 768
|
||||
|
||||
endif # AUDIO_FAKE
|
||||
|
||||
endif # DRIVERS_AUDIO
|
||||
|
|
|
@ -87,6 +87,10 @@ ifeq ($(CONFIG_AUDIO_NULL),y)
|
|||
CSRCS += audio_null.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_FAKE),y)
|
||||
CSRCS += audio_fake.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AUDIO_TONE),y)
|
||||
CSRCS += tone.c
|
||||
endif
|
||||
|
|
1149
drivers/audio/audio_fake.c
Normal file
1149
drivers/audio/audio_fake.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -130,6 +130,7 @@
|
|||
#define _POSIX_PIPE_BUF 512
|
||||
#define _POSIX_STREAM_MAX 16
|
||||
#define _POSIX_TZNAME_MAX 3
|
||||
#define _POSIX2_LINE_MAX 80
|
||||
|
||||
#ifdef CONFIG_SMALL_MEMORY
|
||||
|
||||
|
@ -202,6 +203,7 @@
|
|||
|
||||
#define ARG_MAX _POSIX_ARG_MAX
|
||||
#define CHILD_MAX _POSIX_CHILD_MAX
|
||||
#define LINE_MAX _POSIX2_LINE_MAX
|
||||
#define LINK_MAX _POSIX_LINK_MAX
|
||||
#define MAX_CANON _POSIX_MAX_CANON
|
||||
#define MAX_INPUT _POSIX_MAX_INPUT
|
||||
|
|
52
include/nuttx/audio/audio_fake.h
Normal file
52
include/nuttx/audio/audio_fake.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/audio/audio_fake.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_AUDIO_AUDIO_FAKE_H
|
||||
#define __INCLUDE_NUTTX_AUDIO_AUDIO_FAKE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef CONFIG_AUDIO_FAKE
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
int audio_fake_initialize(void);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_AUDIO_FAKE */
|
||||
#endif /* __INCLUDE_NUTTX_AUDIO_AUDIO_FAKE_H */
|
|
@ -914,6 +914,8 @@ struct sensor_gnss_satellite
|
|||
|
||||
uint32_t constellation;
|
||||
|
||||
float cf; /* Carrier Frequency(Hz), GSV.signal_id */
|
||||
|
||||
struct satellite
|
||||
{
|
||||
uint32_t svid; /* Space vehicle ID */
|
||||
|
|
|
@ -172,6 +172,8 @@
|
|||
|
||||
#define SIGSYS 31
|
||||
|
||||
#define SIGIOT SIGABRT
|
||||
|
||||
/* sigprocmask() "how" definitions.
|
||||
* Only one of the following can be specified:
|
||||
*/
|
||||
|
@ -199,6 +201,10 @@
|
|||
* is delivered */
|
||||
#define SA_KERNELHAND (1 << 7) /* Invoke the handler in kernel space directly */
|
||||
|
||||
/* SA_NOMASK is a nonstandard synonym of SA_NODEFER */
|
||||
|
||||
#define SA_NOMASK SA_NODEFER
|
||||
|
||||
/* These are the possible values of the siginfo si_code field */
|
||||
|
||||
#define SI_USER 0 /* Signal sent from kill, raise, or abort */
|
||||
|
@ -410,7 +416,11 @@ struct sigaction
|
|||
} sa_u;
|
||||
sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
FAR void *sa_user; /* Passed to siginfo.si_user (non-standard) */
|
||||
union
|
||||
{
|
||||
CODE void (*sa_restorer)(void);
|
||||
FAR void *sa_user; /* Passed to siginfo.si_user (non-standard) */
|
||||
};
|
||||
};
|
||||
|
||||
/* Definitions that adjust the non-standard naming */
|
||||
|
@ -427,6 +437,8 @@ typedef struct
|
|||
size_t ss_size;
|
||||
} stack_t;
|
||||
|
||||
typedef CODE void (*sig_t)(int);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/arm_modifyreg16.c
|
||||
* include/sys/fcntl.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -20,46 +20,25 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_SYS_FCNTL_H
|
||||
#define __INCLUDE_SYS_FCNTL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg16
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint16_t regval;
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg16(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg16(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
||||
#endif /* __INCLUDE_SYS_FCNTL_H */
|
|
@ -39,7 +39,16 @@
|
|||
|
||||
/* Mount flags */
|
||||
|
||||
#define MS_RDONLY 1 /* Mount file system read-only */
|
||||
#define MS_RDONLY 1 /* Mount file system read-only */
|
||||
#define MS_NOSUID 2 /* Ignore suid and sgid bits */
|
||||
#define MS_NODEV 4 /* Disallow access to device special files */
|
||||
#define MS_NOEXEC 8 /* Disallow program execution */
|
||||
#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
|
||||
#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
|
||||
#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
|
||||
#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
|
||||
#define MS_NOSYMFOLLOW 256 /* Do not follow symlinks */
|
||||
#define MS_NOATIME 1024 /* Do not update access times. */
|
||||
|
||||
/* Un-mount flags
|
||||
*
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
#define PR_SET_NAME_EXT 3
|
||||
#define PR_GET_NAME_EXT 4
|
||||
|
||||
#define PR_SET_DUMPABLE 5
|
||||
#define PR_GET_DUMPABLE 6
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#define RLIMIT_STACK 6 /* Limit on stack size */
|
||||
#define RLIMIT_AS 7 /* Limit on address space size */
|
||||
#define RLIMIT_MEMLOCK 8 /* Limit on memory use */
|
||||
#define RLIMIT_NICE 10 /* Limit on nice level */
|
||||
|
||||
/* Below are not implemented yet: */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/arm_modifyreg8.c
|
||||
* include/sys/sem.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -20,46 +20,25 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_SYS_SEM_H
|
||||
#define __INCLUDE_SYS_SEM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg8
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint8_t regval;
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg8(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg8(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
||||
#endif /* __INCLUDE_SYS_SEM_H */
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/arm_modifyreg32.c
|
||||
* include/sys/signal.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -20,46 +20,25 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_SYS_SIGNAL_H
|
||||
#define __INCLUDE_SYS_SIGNAL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_modifyreg_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modifyreg32
|
||||
*
|
||||
* Description:
|
||||
* Atomically modify the specified bits in a memory mapped register
|
||||
*
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
flags = spin_lock_irqsave(&g_modifyreg_lock);
|
||||
regval = getreg32(addr);
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
putreg32(regval, addr);
|
||||
spin_unlock_irqrestore(&g_modifyreg_lock, flags);
|
||||
}
|
||||
#endif /* __INCLUDE_SYS_VFS_H */
|
|
@ -242,6 +242,8 @@
|
|||
#define SOL_SCO 17 /* See options in include/netpacket/bluetooth.h */
|
||||
#define SOL_RFCOMM 18 /* See options in include/netpacket/bluetooth.h */
|
||||
|
||||
#define SOL_PACKET 19
|
||||
|
||||
/* Protocol-level socket options may begin with this value */
|
||||
|
||||
#define __SO_PROTOCOL 16
|
||||
|
|
|
@ -232,6 +232,8 @@ typedef int32_t off_t;
|
|||
typedef int32_t fpos_t;
|
||||
#endif
|
||||
|
||||
typedef off_t loff_t;
|
||||
|
||||
/* blksize_t is a signed integer value used for file block sizes */
|
||||
|
||||
typedef int16_t blksize_t;
|
||||
|
|
44
include/wait.h
Normal file
44
include/wait.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/****************************************************************************
|
||||
* include/wait.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_WAIT_H
|
||||
#define __INCLUDE_WAIT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __INCLUDE_WAIT_H */
|
|
@ -62,8 +62,8 @@ config IOB_NCHAINS
|
|||
I/O buffer chain containers that also carry a payload of usage
|
||||
specific information.
|
||||
|
||||
Note: TCP doesn't use this.
|
||||
Note: UDP and CAN use this.
|
||||
Note: TCP and UDP don't use this.
|
||||
Note: ICMP/ICMPv6 and CAN use this.
|
||||
|
||||
config IOB_THROTTLE
|
||||
int "I/O buffer throttle value"
|
||||
|
|
|
@ -37,7 +37,7 @@ config NET_ICMP_PMTU_TIMEOUT
|
|||
config NET_ICMP_SOCKET
|
||||
bool "IPPROTO_ICMP socket support"
|
||||
default n
|
||||
select MM_IOB
|
||||
select NET_READAHEAD
|
||||
---help---
|
||||
Enable support for IPPROTO_ICMP sockets. These sockets are needed
|
||||
for application level support for sending ECHO (ping) requests and
|
||||
|
|
|
@ -39,7 +39,7 @@ config NET_ICMPv6_PMTU_TIMEOUT
|
|||
config NET_ICMPv6_SOCKET
|
||||
bool "IPPROTO_ICMP6 socket support"
|
||||
default n
|
||||
select MM_IOB
|
||||
select NET_READAHEAD
|
||||
---help---
|
||||
Enable support for IPPROTO_ICMP6 sockets. These sockets are needed
|
||||
for application level support for sending ICMPv7 ECHO requests and
|
||||
|
|
|
@ -65,6 +65,7 @@ static const char *dequote_list[] =
|
|||
"CONFIG_TTY_LAUNCH_ENTRYPOINT", /* Name of entry point from tty launch */
|
||||
"CONFIG_TTY_LAUNCH_ARGS", /* Argument list of entry point from tty launch */
|
||||
"CONFIG_BOARD_MEMORY_RANGE", /* Memory range for board */
|
||||
"CONFIG_FAKE_AUDIO_DEVICE_PARAMS", /* Arguments for the fake audio device */
|
||||
|
||||
/* NxWidgets/NxWM */
|
||||
|
||||
|
|
204
tools/gcov.py
Executable file
204
tools/gcov.py
Executable file
|
@ -0,0 +1,204 @@
|
|||
#!/usr/bin/env python3
|
||||
# tools/gcov.py
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def parse_gcda_data(path):
|
||||
with open(path, "r") as file:
|
||||
lines = file.read().strip().splitlines()
|
||||
|
||||
started = False
|
||||
filename = ""
|
||||
output = ""
|
||||
size = 0
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("gcov start"):
|
||||
started = True
|
||||
match = re.search(r"filename:(.*?)\s+size:\s*(\d+)Byte", line)
|
||||
if match:
|
||||
filename = match.group(1)
|
||||
size = int(match.group(2))
|
||||
continue
|
||||
|
||||
if not started:
|
||||
continue
|
||||
|
||||
if line.startswith("gcov end"):
|
||||
started = False
|
||||
if size != len(output) // 2:
|
||||
print(
|
||||
f"Size mismatch for {filename}: expected {size} bytes, got {len(output) // 2} bytes"
|
||||
)
|
||||
|
||||
match = re.search(r"checksum:\s*(0x[0-9a-fA-F]+)", line)
|
||||
if match:
|
||||
checksum = int(match.group(1), 16)
|
||||
output = bytearray.fromhex(output)
|
||||
expected = sum(output) % 65536
|
||||
if checksum != expected:
|
||||
print(
|
||||
f"Checksum mismatch for {filename}: expected {checksum}, got {expected}"
|
||||
)
|
||||
continue
|
||||
|
||||
with open(filename, "wb") as fp:
|
||||
fp.write(output)
|
||||
print(f"write {filename} success")
|
||||
output = ""
|
||||
else:
|
||||
output += line.strip()
|
||||
|
||||
|
||||
def copy_file_endswith(endswith, source_dir, target_dir):
|
||||
print(f"Collect {endswith} files {source_dir} -> {target_dir}")
|
||||
|
||||
if not os.path.exists(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
|
||||
for root, _, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
if file.endswith(endswith):
|
||||
source_file = os.path.join(root, file)
|
||||
target_file = os.path.join(target_dir, file)
|
||||
shutil.copy2(source_file, target_file)
|
||||
|
||||
|
||||
def arg_parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Code coverage generation tool.", add_help=False
|
||||
)
|
||||
parser.add_argument("-i", "--input", help="Input dump data")
|
||||
parser.add_argument("-t", dest="gcov_tool", help="Path to gcov tool")
|
||||
parser.add_argument("-s", dest="gcno_dir", help="Directory containing gcno files")
|
||||
parser.add_argument("-a", dest="gcda_dir", help="Directory containing gcda files")
|
||||
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
||||
parser.add_argument(
|
||||
"-x",
|
||||
dest="only_copy",
|
||||
action="store_true",
|
||||
help="Only copy *.gcno and *.gcda files",
|
||||
)
|
||||
parser.add_argument(
|
||||
"gcov_dir",
|
||||
nargs="?",
|
||||
default=os.getcwd(),
|
||||
help="Directory to store gcov data and report",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = arg_parser()
|
||||
|
||||
root_dir = os.getcwd()
|
||||
gcov_dir = os.path.abspath(args.gcov_dir)
|
||||
gcno_dir = os.path.abspath(args.gcno_dir) if args.gcno_dir else root_dir
|
||||
gcda_dir = os.path.abspath(args.gcda_dir) if args.gcda_dir else root_dir
|
||||
|
||||
coverage_file = os.path.join(gcov_dir, "coverage.info")
|
||||
result_dir = os.path.join(gcov_dir, "result")
|
||||
gcov_data_dir = os.path.join(gcov_dir, "data")
|
||||
|
||||
if args.debug:
|
||||
debug_file = os.path.join(gcov_dir, "debug.log")
|
||||
sys.stdout = open(debug_file, "w+")
|
||||
|
||||
if args.input:
|
||||
parse_gcda_data(os.path.join(root_dir, args.input))
|
||||
|
||||
os.makedirs(os.path.join(gcov_dir, "data"), exist_ok=True)
|
||||
|
||||
# Collect gcno, gcda files
|
||||
copy_file_endswith(".gcno", gcno_dir, gcov_data_dir)
|
||||
copy_file_endswith(".gcda", gcda_dir, gcov_data_dir)
|
||||
|
||||
# Only copy files
|
||||
if args.only_copy:
|
||||
sys.exit(0)
|
||||
|
||||
# lcov tool is required
|
||||
if shutil.which("lcov") is None:
|
||||
print(
|
||||
"Error: Code coverage generation tool is not detected, please install lcov."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
|
||||
# lcov collect coverage data to coverage_file
|
||||
subprocess.run(
|
||||
[
|
||||
"lcov",
|
||||
"-c",
|
||||
"-d",
|
||||
gcov_data_dir,
|
||||
"-o",
|
||||
coverage_file,
|
||||
"--rc",
|
||||
"lcov_branch_coverage=1",
|
||||
"--gcov-tool",
|
||||
args.gcov_tool,
|
||||
"--ignore-errors",
|
||||
"gcov",
|
||||
],
|
||||
check=True,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stdout,
|
||||
)
|
||||
|
||||
# genhtml generate coverage report
|
||||
subprocess.run(
|
||||
[
|
||||
"genhtml",
|
||||
"--branch-coverage",
|
||||
"-o",
|
||||
result_dir,
|
||||
coverage_file,
|
||||
"--ignore-errors",
|
||||
"source",
|
||||
],
|
||||
check=True,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stdout,
|
||||
)
|
||||
|
||||
print(
|
||||
"Copy the following link and open it in the browser to view the coverage report:"
|
||||
)
|
||||
print(f"file://{os.path.join(result_dir, 'index.html')}")
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
print("Failed to generate coverage file.")
|
||||
sys.exit(1)
|
||||
|
||||
shutil.rmtree(gcov_data_dir)
|
||||
os.remove(coverage_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
147
tools/gcov.sh
147
tools/gcov.sh
|
@ -1,147 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# tools/gcov.sh
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
ROOT_DIR=$(pwd)
|
||||
GCNO_DIR=$ROOT_DIR
|
||||
GCDA_DIR=$ROOT_DIR
|
||||
|
||||
show_help() {
|
||||
echo "Usage: $0 [-t gcov_tool] [-s gcno_dir] [-a gcda_dir] [-x] [gcov_dir]"
|
||||
echo " -t gcov_tool: path to gcov tool, e.g. ./nuttx/tools/gcov.sh -t arm-none-eabi-gcov"
|
||||
echo " -s gcno_dir: directory containing gcno files (relative or absolute path allowed)"
|
||||
echo " -a gcda_dir: directory containing gcda files (relative or absolute path allowed)"
|
||||
echo " -x: only copy *.gcno and *.gcda files"
|
||||
echo " gcov_dir: directory to store gcov data and report (optional)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
convert_to_absolute_path() {
|
||||
local dir_path=$1
|
||||
if [ -z "$dir_path" ]; then
|
||||
echo "Error: Directory path is empty."
|
||||
exit 1
|
||||
fi
|
||||
# Convert to absolute path if not already
|
||||
if [ ! "${dir_path:0:1}" = "/" ]; then
|
||||
dir_path=$(realpath "$dir_path" 2>/dev/null)
|
||||
fi
|
||||
echo "$dir_path"
|
||||
}
|
||||
|
||||
while getopts "a:s:t:xh" opt
|
||||
|
||||
do
|
||||
case $opt in
|
||||
a)
|
||||
GCDA_DIR=$(convert_to_absolute_path "$OPTARG")
|
||||
if [ ! -d "$GCDA_DIR" ]; then
|
||||
echo "Error: Invalid gcda directory: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
s)
|
||||
GCNO_DIR=$(convert_to_absolute_path "$OPTARG")
|
||||
if [ ! -d "$GCNO_DIR" ]; then
|
||||
echo "Error: Invalid gcno directory: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
t)
|
||||
GCOV_TOOL="--gcov-tool $OPTARG"
|
||||
;;
|
||||
x)
|
||||
ONLY_COPY=1
|
||||
;;
|
||||
h)
|
||||
show_help
|
||||
;;
|
||||
?)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
# Handle gcov_dir as the last positional argument
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "Error: Too many arguments."
|
||||
show_help
|
||||
fi
|
||||
|
||||
if [ $# -eq 1 ]; then
|
||||
GCOV_DIR=$(convert_to_absolute_path "$1")
|
||||
else
|
||||
GCOV_DIR=${ROOT_DIR}/gcov
|
||||
fi
|
||||
|
||||
mkdir -p ${GCOV_DIR} ${GCOV_DIR}/data
|
||||
cd ${GCOV_DIR}
|
||||
|
||||
# Collect gcno files
|
||||
|
||||
find ${GCNO_DIR}/ -name "*.gcno" -exec cp {} ${GCOV_DIR}/data > /dev/null 2>&1 \;
|
||||
|
||||
# Collect gcda files
|
||||
|
||||
find ${GCDA_DIR}/ -name "*.gcda" -exec cp {} ${GCOV_DIR}/data > /dev/null 2>&1 \;
|
||||
|
||||
# Ensure ONLY_COPY is initialized as an integer
|
||||
ONLY_COPY=${ONLY_COPY:-0}
|
||||
|
||||
if [ "$ONLY_COPY" -eq 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$GCOV_TOOL" ]; then
|
||||
echo "Error: -t is a required option."
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
type lcov > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Code coverage generation tool is not detected, please install lcov"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
files=$(find ${GCOV_DIR}/data -name "*.gcda" 2> /dev/null | wc -l)
|
||||
if [ "$files" == "0" ] ;then
|
||||
echo "gcda file not found in directory ${ROOT_DIR}"
|
||||
echo "Please run ./nuttx before using gcov.sh to generate the coverage report"
|
||||
echo "Or copy the gcda file in the device to ${ROOT_DIR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate coverage text report
|
||||
lcov -c -d ${GCOV_DIR}/data -o coverage.info --rc lcov_branch_coverage=1 ${GCOV_TOOL} --ignore-errors gcov
|
||||
|
||||
# Generate coverage page report
|
||||
genhtml --branch-coverage -o result coverage.info --ignore-errors source
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to generate coverage file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "Copy the following link and open it in the browser to view the coverage report"
|
||||
echo "file://${GCOV_DIR}/result/index.html"
|
|
@ -1,94 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
############################################################################
|
||||
# tools/gcov_convert.py
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
import argparse
|
||||
import re
|
||||
|
||||
# Parse gcda data from stdout dump format to binary format
|
||||
# The stdout dump format is:
|
||||
# gcov start filename:<filename> size: <size>Byte
|
||||
# <hex dump data>
|
||||
# gcov end filename:<filename> checksum: <checksum>
|
||||
#
|
||||
# The hex dump data will be converted to binary and written to <filename>
|
||||
# The checksum is calculated by summing all bytes and taking modulo 65536
|
||||
|
||||
|
||||
def parse_gcda_data(input_file):
|
||||
with open(input_file, "r") as file:
|
||||
lines = file.read().strip().splitlines()
|
||||
|
||||
for line in lines:
|
||||
if not line.startswith("gcov start"):
|
||||
continue
|
||||
|
||||
match = re.search(r"filename:(.*?)\s+size:\s*(\d+)Byte", line)
|
||||
if not match:
|
||||
continue
|
||||
|
||||
hex_dump = ""
|
||||
filename = match.group(1)
|
||||
size = int(match.group(2))
|
||||
|
||||
# Read the hex dump until the end of the file
|
||||
next_line_index = lines.index(line) + 1
|
||||
while next_line_index < len(lines) and not lines[next_line_index].startswith(
|
||||
"gcov end"
|
||||
):
|
||||
hex_dump += lines[next_line_index].strip()
|
||||
next_line_index += 1
|
||||
|
||||
if size != len(hex_dump) // 2:
|
||||
print(
|
||||
f"Size mismatch for {filename}: expected {size} bytes, got {len(hex_dump) // 2} bytes"
|
||||
)
|
||||
|
||||
checksum_match = (
|
||||
re.search(r"checksum:\s*(0x[0-9a-fA-F]+)", lines[next_line_index])
|
||||
if next_line_index < len(lines)
|
||||
else None
|
||||
)
|
||||
if not checksum_match:
|
||||
continue
|
||||
|
||||
checksum = int(checksum_match.group(1), 16)
|
||||
calculated_checksum = sum(bytearray.fromhex(hex_dump)) % 65536
|
||||
if calculated_checksum != checksum:
|
||||
print(
|
||||
f"Checksum mismatch for {filename}: expected {checksum}, got {calculated_checksum}"
|
||||
)
|
||||
continue
|
||||
|
||||
with open(filename, "wb") as fp:
|
||||
fp.write(bytes.fromhex(hex_dump))
|
||||
print(f"write {filename} success")
|
||||
|
||||
print(
|
||||
"Execute the 'nuttx/tools/gcov.sh -t arm-none-eabi-gcov' command to view the coverage report"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-i", "--input", required=True, help="Input dump data")
|
||||
args = parser.parse_args()
|
||||
|
||||
parse_gcda_data(args.input)
|
Loading…
Reference in a new issue