mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
arch: cxd56xx: Fix deadlock by using GNSS CEP file on SPI-Flash
If you specify a file path on SPI-Flash in CONFIG_CXD56_GNSS_CEP_FILENAME, it causes a deadlock issue in the inter-CPU communication. To resolve it, introduce a new CONFIG_CXD56_GNSS_CEP_ON_SPIFLASH and then use pre-read buffers during checking CEP file. So this needs the large of free memory.
This commit is contained in:
@@ -1312,6 +1312,12 @@ config CXD56_GNSS_CEP_FILENAME
|
|||||||
---help---
|
---help---
|
||||||
Specify the path and file name of cep data.
|
Specify the path and file name of cep data.
|
||||||
|
|
||||||
|
config CXD56_GNSS_CEP_ON_SPIFLASH
|
||||||
|
bool "GNSS CEP file on SPI-Flash"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Use a cep file on SPI-Flash.
|
||||||
|
|
||||||
config CXD56_GNSS_FW_RTK
|
config CXD56_GNSS_FW_RTK
|
||||||
bool "Support carrier-phase data output for Real-Time Kinematic"
|
bool "Support carrier-phase data output for Real-Time Kinematic"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/mutex.h>
|
#include <nuttx/mutex.h>
|
||||||
@@ -394,6 +395,14 @@ static struct pm_cpu_freqlock_s g_lv_lock =
|
|||||||
static struct pm_cpu_freqlock_s g_hold_lock =
|
static struct pm_cpu_freqlock_s g_hold_lock =
|
||||||
PM_CPUFREQLOCK_INIT(0, PM_CPUFREQLOCK_FLAG_HOLD);
|
PM_CPUFREQLOCK_INIT(0, PM_CPUFREQLOCK_FLAG_HOLD);
|
||||||
|
|
||||||
|
#ifdef CONFIG_CXD56_GNSS_CEP_ON_SPIFLASH
|
||||||
|
/* Buffer and length for CEP data on SPI-Flash */
|
||||||
|
|
||||||
|
static int g_check_cep_flag = 0;
|
||||||
|
static char *g_cepdata = NULL;
|
||||||
|
static size_t g_ceplen = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -1013,6 +1022,82 @@ static int cxd56_gnss_close_cep_data(struct file *filep,
|
|||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#ifdef CONFIG_CXD56_GNSS_CEP_ON_SPIFLASH
|
||||||
|
static int cxd56_gnss_check_cep_data(struct file *filep, unsigned long arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct stat statbuf;
|
||||||
|
struct inode *inode;
|
||||||
|
struct cxd56_gnss_dev_s *priv;
|
||||||
|
|
||||||
|
inode = filep->f_inode;
|
||||||
|
priv = (struct cxd56_gnss_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Set a flag for checking CEP data */
|
||||||
|
|
||||||
|
g_check_cep_flag = 1;
|
||||||
|
|
||||||
|
/* Allocate a buffer and read all of CEP data to it */
|
||||||
|
|
||||||
|
g_cepdata = NULL;
|
||||||
|
g_ceplen = 0;
|
||||||
|
|
||||||
|
ret = file_fstat(&priv->cepfp, &statbuf);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
g_ceplen = (size_t)statbuf.st_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ceplen > 0)
|
||||||
|
{
|
||||||
|
g_cepdata = (char *)kmm_malloc(g_ceplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_cepdata)
|
||||||
|
{
|
||||||
|
gnsserr("Failed to allocate cep data\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the file position to the beginning before reading */
|
||||||
|
|
||||||
|
ret = file_seek(&priv->cepfp, 0, SEEK_SET);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = file_read(&priv->cepfp, g_cepdata, g_ceplen);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fw_gd_cepcheckassistdata();
|
||||||
|
|
||||||
|
errout:
|
||||||
|
|
||||||
|
/* Free an allocated buffer */
|
||||||
|
|
||||||
|
if (g_cepdata)
|
||||||
|
{
|
||||||
|
kmm_free(g_cepdata);
|
||||||
|
g_cepdata = NULL;
|
||||||
|
g_ceplen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear a flag for checking CEP data */
|
||||||
|
|
||||||
|
g_check_cep_flag = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !CONFIG_CXD56_GNSS_CEP_ON_SPIFLASH */
|
||||||
|
|
||||||
static int cxd56_gnss_check_cep_data(struct file *filep,
|
static int cxd56_gnss_check_cep_data(struct file *filep,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
@@ -1020,6 +1105,8 @@ static int cxd56_gnss_check_cep_data(struct file *filep,
|
|||||||
return fw_gd_cepcheckassistdata();
|
return fw_gd_cepcheckassistdata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: cxd56_gnss_get_cep_age
|
* Name: cxd56_gnss_get_cep_age
|
||||||
*
|
*
|
||||||
@@ -2136,6 +2223,27 @@ cxd56_gnss_read_cep_file(struct file *fp, int32_t offset,
|
|||||||
char *buf;
|
char *buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CXD56_GNSS_CEP_ON_SPIFLASH
|
||||||
|
if (g_check_cep_flag)
|
||||||
|
{
|
||||||
|
/* If checking CEP data, use a pre-read buffer in advance */
|
||||||
|
|
||||||
|
if (offset + len > g_ceplen)
|
||||||
|
{
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto _err0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = &g_cepdata[offset];
|
||||||
|
|
||||||
|
*retval = len;
|
||||||
|
|
||||||
|
cxd56_cpu1sigsend(CXD56_CPU1_DATA_TYPE_CEP, (uint32_t)buf);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
|
|||||||
Reference in New Issue
Block a user