summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-02-21 15:15:51 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-02-21 15:15:51 -0600
commite3e07e56e21aea839b31f2a2ed77625cbea5bf15 (patch)
treec4c96dcb9bf0f98f12e122d8f2b3298e7673794f /nuttx
parent38eb8e9302bb4e86b8055073ca91e154c64a6802 (diff)
downloadnuttx-e3e07e56e21aea839b31f2a2ed77625cbea5bf15.tar.gz
nuttx-e3e07e56e21aea839b31f2a2ed77625cbea5bf15.tar.bz2
nuttx-e3e07e56e21aea839b31f2a2ed77625cbea5bf15.zip
Adds the ability to use the STM32F2 and STM32F4 Battery Backedup SRAM in the file system. With an option to Save Panic context to one of the files. From David Sidrane.
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig18
-rw-r--r--nuttx/arch/arm/src/stm32/Make.defs4
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_bbsram.c861
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_bbsram.h166
-rw-r--r--[-rwxr-xr-x]nuttx/arch/arm/src/stm32/stm32_ccm.c0
-rw-r--r--[-rwxr-xr-x]nuttx/arch/arm/src/stm32/stm32_ccm.h0
-rw-r--r--[-rwxr-xr-x]nuttx/arch/arm/src/stm32/stm32_i2c_alt.c0
-rw-r--r--[-rwxr-xr-x]nuttx/arch/arm/src/stm32/stm32_sdio.c0
-rw-r--r--[-rwxr-xr-x]nuttx/arch/arm/src/stm32/stm32_usbhost.c0
9 files changed, 1048 insertions, 1 deletions
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig
index 9a61e8e89..8740208e9 100644
--- a/nuttx/arch/arm/src/stm32/Kconfig
+++ b/nuttx/arch/arm/src/stm32/Kconfig
@@ -1134,7 +1134,7 @@ config STM32_BKP
depends on STM32_STM32F10XX
config STM32_BKPSRAM
- bool "BKP RAM"
+ bool "Enable BKP RAM Domain"
default n
depends on STM32_STM32F207 || STM32_STM32F40XX
@@ -3254,6 +3254,22 @@ config SDIO_WIDTH_D1_ONLY
endmenu
+if STM32_BKPSRAM
+
+config STM32_BBSRAM
+ bool "BBSRAM File Support"
+ default n
+
+config STM32_BBSRAM_FILES
+ int "Max Files to support in BBSRAM"
+ default 4
+
+config STM32_SAVE_CRASHDUMP
+ bool "Enable Saving Panic to BBSRAM"
+ default n
+
+endif # STM32_BKPSRAM
+
config STM32_HAVE_RTC_SUBSECONDS
bool
default n
diff --git a/nuttx/arch/arm/src/stm32/Make.defs b/nuttx/arch/arm/src/stm32/Make.defs
index a6b4e874e..a4ee123d3 100644
--- a/nuttx/arch/arm/src/stm32/Make.defs
+++ b/nuttx/arch/arm/src/stm32/Make.defs
@@ -233,3 +233,7 @@ endif
ifeq ($(CONFIG_STM32_AES),y)
CHIP_CSRCS += stm32_aes.c
endif
+
+ifeq ($(CONFIG_STM32_BBSRAM),y)
+CHIP_CSRCS += stm32_bbsram.c
+endif
diff --git a/nuttx/arch/arm/src/stm32/stm32_bbsram.c b/nuttx/arch/arm/src/stm32/stm32_bbsram.c
new file mode 100644
index 000000000..66f834966
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_bbsram.c
@@ -0,0 +1,861 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_bbsram.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * David Sidrane <david_s5@nscdg.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* This will driver create a set of files in the STM32's Battery backed up
+ * SRAM. That can be used to store data retained across power cycles.
+ *
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <poll.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <nuttx/fs/fs.h>
+
+#include <crc32.h>
+
+#include "stm32_bbsram.h"
+#include "chip.h"
+#include "stm32_pwr.h"
+#include "stm32_rtc.h"
+
+#ifdef CONFIG_STM32_BBSRAM
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+#if !defined(CONFIG_STM32_BKPSRAM)
+#error Driver Requires CONFIG_STM32_BKPSRAM to be enabled
+#endif
+
+#define MAX_OPENCNT (255) /* Limit of uint8_t */
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+# define BBSRAM_DEBUG_READ() stm32_bbsram_rd()
+# define BBSRAM_DUMP(p,s) stm32_bbsram_dump(p,s)
+#else
+# define BBSRAM_DEBUG_READ()
+# define BBSRAM_DUMP(p,s)
+#endif
+
+#define BBSRAM_HEADER_SIZE (sizeof(struct bbsramfh_s))
+#define BBSRAM_CRCED_OFFSET (sizeof(((struct bbsramfh_s *)0)->crc))
+#define BBSRAM_CRCED_SIZE(l) (BBSRAM_HEADER_SIZE-BBSRAM_CRCED_OFFSET+(l))
+#define BBSRAM_ALIGNMENT (sizeof(((struct bbsramfh_s *)0)->crc))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* File Header */
+
+struct bbsramfh_s
+{
+ uint32_t crc; /* CRC calculated over data and this struct
+ * starting at fileno */
+ uint8_t fileno; /* The minor number */
+ uint8_t dirty; /* Data has been written to the file */
+ uint16_t len; /* Total Bytes in this file*/
+ struct timespec lastwrite; /* Last write time */
+ uint8_t data[]; /* Data in the file */
+};
+
+struct stm32_bbsram_s
+{
+ sem_t exclsem; /* For atomic accesses to this structure */
+ uint8_t refs; /* Number of references */
+ FAR struct bbsramfh_s *bbf; /* File in bbram */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_bbsram_open(FAR struct file *filep);
+static int stm32_bbsram_close(FAR struct file *filep);
+static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset, int whence);
+static ssize_t stm32_bbsram_read(FAR struct file *, FAR char *, size_t);
+static ssize_t stm32_bbsram_write(FAR struct file *, FAR const char *, size_t);
+static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+#ifndef CONFIG_DISABLE_POLL
+static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup);
+#endif
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int stm32_bbsram_unlink(FAR struct inode *inode);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static uint8_t debug[STM32_BBSRAM_SIZE];
+#endif
+
+static const struct file_operations stm32_bbsram_fops =
+{
+ .open = stm32_bbsram_open,
+ .close = stm32_bbsram_close,
+ .read = stm32_bbsram_read,
+ .write = stm32_bbsram_write,
+ .seek = stm32_bbsram_seek,
+ .ioctl = stm32_bbsram_ioctl,
+#ifndef CONFIG_DISABLE_POLL
+ .poll = stm32_bbsram_poll,
+#endif
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ .unlink = stm32_bbsram_unlink,
+#endif
+};
+
+static struct stm32_bbsram_s g_bbsram[CONFIG_STM32_BBSRAM_FILES];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: stm32_bbsram_rd
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static void stm32_bbsram_rd(void)
+{
+ memcpy(&debug,(uint8_t*)STM32_BKPSRAM_BASE,sizeof debug);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_rd
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static void stm32_bbsram_dump(FAR struct bbsramfh_s *bbf, char *op)
+{
+ BBSRAM_DEBUG_READ();
+ lldbg("%s:\n",op);
+ lldbg(" File Address:0x%8x\n", bbf);
+ lldbg(" crc:0x%8x\n", bbf->crc);
+ lldbg(" fileno:%d\n", (int) bbf->fileno);
+ lldbg(" dirty:%d\n", (int) bbf->dirty);
+ lldbg(" length:%d\n", (int) bbf->len);
+ lldbg(" time:%ld:%ld\n", bbf->lastwrite.tv_sec, bbf->lastwrite.tv_nsec);
+ lldbg(" data: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
+ bbf->data[0], bbf->data[1], bbf->data[2], bbf->data[3], bbf->data[4]);
+}
+#endif
+
+/************************************************************************************
+ * Name: stm32_bbsram_semgive
+ ************************************************************************************/
+
+static void stm32_bbsram_semgive(FAR struct stm32_bbsram_s *priv)
+{
+ sem_post(&priv->exclsem);
+}
+
+/************************************************************************************
+ * Name: stm32_bbsram_semtake
+ *
+ * Description:
+ * Take a semaphore handling any exceptional conditions
+ *
+ * Input Parameters:
+ * priv - A reference to the CAN peripheral state
+ *
+ * Returned Value:
+ * None
+ *
+****************************************************************************/
+
+static void stm32_bbsram_semtake(FAR struct stm32_bbsram_s *priv)
+{
+ int ret;
+
+ /* Wait until we successfully get the semaphore. EINTR is the only
+ * expected 'failure' (meaning that the wait for the semaphore was
+ * interrupted by a signal.
+ */
+
+ do
+ {
+ ret = sem_wait(&priv->exclsem);
+ DEBUGASSERT(ret == 0 || errno == EINTR);
+ }
+ while (ret < 0);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_ulock
+ *
+ * Description:
+ * Unprotects RTC registers, RTC backup data registers and backup SRAM
+ * against parasitic write access
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_bbsram_unlock(void)
+{
+ stm32_pwr_enablebkp(true);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_lock
+ *
+ * Description:
+ * Protects RTC registers, RTC backup data registers and backup SRAM
+ * against parasitic write access
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_bbsram_lock(void)
+{
+ stm32_pwr_enablebkp(false);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_crc
+ *
+ * Description:
+ * Calculates the CRC of the block
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static uint32_t stm32_bbsram_crc(FAR struct bbsramfh_s *pf)
+{
+ return crc32((uint8_t*)pf + BBSRAM_CRCED_OFFSET, BBSRAM_CRCED_SIZE(pf->len));
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_open
+ *
+ * Description: Open the device
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_open(FAR struct file *filep)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ /* Increment the reference count */
+
+ stm32_bbsram_semtake(bbr);
+ if (bbr->refs == MAX_OPENCNT)
+ {
+ return -EMFILE;
+ }
+ else
+ {
+ bbr->refs++;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_internal_close
+ *
+ * Description:
+ * Close BBSRAM entry; Recalculate the time and crc
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_internal_close(FAR struct bbsramfh_s *bbf)
+{
+ bbf->dirty = 0;
+ (void)clock_gettime(CLOCK_REALTIME, &bbf->lastwrite);
+ bbf->crc = stm32_bbsram_crc(bbf);
+
+ BBSRAM_DUMP(bbf,"close done");
+ return bbf->len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_close
+ *
+ * Description: close the device
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_close(FAR struct file *filep)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = OK;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ BBSRAM_DUMP(bbr->bbf,"close");
+
+ if (bbr->refs == 0)
+ {
+ ret = -EIO;
+ }
+ else
+ {
+ bbr->refs--;
+
+ if (bbr->refs == 0)
+ {
+ if (bbr->bbf->dirty)
+ {
+ /* Recalculate the time and crc */
+
+ stm32_bbsram_unlock();
+ stm32_bbsram_internal_close(bbr->bbf);
+ stm32_bbsram_lock();
+ }
+ }
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_seek
+ ****************************************************************************/
+
+static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset,
+ int whence)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ off_t newpos;
+ int ret;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ /* Determine the new, requested file position */
+
+ switch (whence)
+ {
+ case SEEK_CUR:
+ newpos = filep->f_pos + offset;
+ break;
+
+ case SEEK_SET:
+ newpos = offset;
+ break;
+
+ case SEEK_END:
+ newpos = bbr->bbf->len + offset;
+ break;
+
+ default:
+ /* Return EINVAL if the whence argument is invalid */
+
+ stm32_bbsram_semgive(bbr);
+ return -EINVAL;
+ }
+
+ /* Opengroup.org:
+ *
+ * "The lseek() function shall allow the file offset to be set beyond the end
+ * of the existing data in the file. If data is later written at this point,
+ * subsequent reads of data in the gap shall return bytes with the value 0
+ * until data is actually written into the gap."
+ *
+ * We can conform to the first part, but not the second. But return EINVAL if
+ *
+ * "...the resulting file offset would be negative for a regular file, block
+ * special file, or directory."
+ */
+
+ if (newpos >= 0)
+ {
+ filep->f_pos = newpos;
+ ret = newpos;
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_read
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_read(FAR struct file *filep, FAR char *buffer,
+ size_t len)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ /* Trim len if read would go beyond end of device */
+
+ if ((filep->f_pos + len) > bbr->bbf->len)
+ {
+ len = bbr->bbf->len - filep->f_pos;
+ }
+
+ memcpy(buffer,&bbr->bbf->data[filep->f_pos], len);
+ filep->f_pos += len;
+ stm32_bbsram_semgive(bbr);
+ return len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_internal_write
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_internal_write(FAR struct bbsramfh_s *bbf,
+ FAR const char *buffer,
+ off_t offset, size_t len)
+{
+ bbf->dirty = 1;
+ memcpy(&bbf->data[offset], buffer, len);
+ return len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_write
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_write(FAR struct file *filep, FAR const char *buffer,
+ size_t len)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = -EFBIG;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ /* Forbid writes past the end of the device */
+
+ if (filep->f_pos < bbr->bbf->len)
+ {
+ /* Clamp len to avoid crossing the end of the memory */
+
+ if ((filep->f_pos + len) > bbr->bbf->len)
+ {
+ len = bbr->bbf->len - filep->f_pos;
+ }
+
+ ret = len; /* save number of bytes written */
+
+ stm32_bbsram_semtake(bbr);
+ BBSRAM_DUMP(bbr->bbf,"write");
+ stm32_bbsram_unlock();
+ stm32_bbsram_internal_write(bbr->bbf, buffer, filep->f_pos, len);
+ stm32_bbsram_lock();
+ filep->f_pos += len;
+ BBSRAM_DUMP(bbr->bbf,"write done");
+ stm32_bbsram_semgive(bbr);
+ }
+
+ BBSRAM_DEBUG_READ();
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_poll
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_POLL
+static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup)
+{
+ if (setup)
+ {
+ fds->revents |= (fds->events & (POLLIN|POLLOUT));
+ if (fds->revents != 0)
+ {
+ sem_post(fds->sem);
+ }
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_ioctl
+ *
+ * Description: Return device geometry
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd,
+ unsigned long arg)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = -ENOTTY;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ if (cmd == STM32_BBSRAM_GETDESC_IOCTL)
+ {
+ FAR struct bbsramd_s *bbrr = (FAR struct bbsramd_s *)((uintptr_t)arg);
+
+ stm32_bbsram_semtake(bbr);
+ if (!bbrr)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ bbrr->fileno = bbr->bbf->fileno;
+ bbrr->lastwrite = bbr->bbf->lastwrite;
+ bbrr->len = bbr->bbf->len;
+ bbrr->flags = (bbr->bbf->crc == stm32_bbsram_crc(bbr->bbf)) ? eCRCValid : 0;
+ bbrr->flags = (bbr->bbf->dirty) ? eDirty : 0;
+ ret = OK;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_unlink
+ *
+ * Description:
+ * This function will remove the remove the file from the file system
+ * it will zero the contents and time stamp. It will leave the fileno
+ * and pointer to the BBSRAM intact.
+ * It should be called called on the the file used for the crash dump
+ * to remove it from visibility in the file system after it is created or
+ * read thus arming it.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int stm32_bbsram_unlink(FAR struct inode *inode)
+{
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+ stm32_bbsram_unlock();
+ memset(bbr->bbf->data, 0, bbr->bbf->len);
+ bbr->bbf->lastwrite.tv_nsec = 0;
+ bbr->bbf->lastwrite.tv_sec = 0;
+ bbr->bbf->crc = stm32_bbsram_crc(bbr->bbf);
+ stm32_bbsram_lock();
+ bbr->refs = 0;
+ stm32_bbsram_semgive(bbr);
+ sem_destroy(&bbr->exclsem);
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_probe
+ *
+ * Description: Based on the number of files defined and their sizes
+ * Initializes the base pointers to the file entries.
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_probe(int *ent, struct stm32_bbsram_s pdev[])
+{
+ int i;
+ int avail = STM32_BBSRAM_SIZE;
+ int alloc;
+ int size;
+ int ret = -EFBIG;
+ struct bbsramfh_s *pf = (struct bbsramfh_s *) STM32_BKPSRAM_BASE;
+
+ for (i = 0; (i < CONFIG_STM32_BBSRAM_FILES) && ent[i] && (avail > 0); i++)
+ {
+ /* Validate the actual allocations against what is in the BBSRAM*/
+
+ size = ent[i];
+
+ /* Use all that is left */
+
+ if (size == -1)
+ {
+ size = avail - (BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT);
+ }
+
+ /* Add in header size and keep aligned */
+
+ alloc = size + BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT;
+ alloc &= ~(BBSRAM_ALIGNMENT-1);
+
+ /* Does it fit? */
+
+ if (alloc <= avail)
+ {
+ ret = i + 1;
+ BBSRAM_DUMP(pf, "probe");
+
+ if (pf->len != size ||
+ pf->fileno != i ||
+ pf->crc != stm32_bbsram_crc(pf))
+ {
+
+ /* Not Valid so wipe the file in BBSRAM */
+
+ memset((uint8_t*)pf, 0, alloc);
+ pf->fileno = i;
+ pf->len = size;
+ pf->crc = stm32_bbsram_crc(pf);
+ BBSRAM_DUMP(pf,"probe reset");
+ }
+
+ pdev[i].bbf = pf;
+ pf = (struct bbsramfh_s *)((uint8_t *)pf + alloc);
+ sem_init(&g_bbsram[i].exclsem, 0, 1);
+ }
+
+ avail -= alloc;
+ }
+
+ BBSRAM_DEBUG_READ();
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: stm32_bbsraminitialize
+ *
+ * Description:
+ * Initialize the Battery Backed up SRAM driver.
+ *
+ * Parameters:
+ * devpath - the path to instantiate the files.
+ * sizes - Pointer to a any array of file sizes to create
+ * the last entry should be 0
+ * A size of -1 will use all the remaining spaces
+ *
+ * If the length of sizes is greater then CONFIG_STM32_BBSRAM_FILES
+ * CONFIG_STM32_BBSRAM_FILES will be returned.
+ *
+ * Returned Value:
+ * Number of files created on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int stm32_bbsraminitialize(char *devpath, int *sizes)
+{
+ int i;
+ int fcnt;
+ char path[32];
+ char devname[32];
+
+ int ret = OK;
+
+ if (devpath == NULL)
+ {
+ return -EINVAL;
+ }
+
+ i = strlen(devpath);
+ if (i == 0 || i > sizeof(path) + 3)
+ {
+ return -EINVAL;
+ }
+
+ memset(g_bbsram, 0, sizeof(g_bbsram));
+
+ /* Clocking for the PWR block must be provided. However, this is done
+ * unconditionally in stm32f40xxx_rcc.c on power up. This done
+ * unconditionally because the PWR block is also needed to set the
+ * internal voltage regulator for maximum performance.
+ */
+
+ /* Enable backup SRAM clock is done in rcc_enableahb1() when
+ * CONFIG_STM32_BKPSRAM is defined.
+ */
+
+ /* Allow Access */
+
+ stm32_bbsram_unlock();
+
+ /* Enable backup regulator so that the data is retained in Standby and
+ * VBAT modes
+ */
+
+ stm32_pwr_enablebreg(true);
+
+ fcnt = stm32_bbsram_probe(sizes, g_bbsram);
+
+ strncpy(path,devpath,sizeof(path));
+ strcat(path,"%d");
+
+ for (i = 0; i < fcnt && ret >= OK; i++)
+ {
+ snprintf(devname, sizeof(devname), path, i);
+ ret = register_driver(devname, &stm32_bbsram_fops, 0666, &g_bbsram[i]);
+ }
+
+ /* Disallow Access */
+
+ stm32_bbsram_lock();
+ return ret < OK ? ret : fcnt;
+}
+
+/****************************************************************************
+* Function: stm32_bbsram_savepanic
+*
+* Description:
+* Saves the panic context in a previously allocated BBSRAM file
+*
+* Parameters:
+* fileno - the value returned by the ioctl STM32_BBSRAM_GETDESC_IOCTL
+* context - Pointer to a any array of bytes to save
+* length - The length of the data pointed to byt context
+*
+* Returned Value:
+* Length saved or negated errno.
+*
+* Assumptions:
+*
+****************************************************************************/
+
+#if defined(CONFIG_STM32_SAVE_CRASHDUMP)
+int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length)
+{
+ FAR struct bbsramfh_s *bbf;
+ int fill;
+
+ /* on a bad day we could panic while panicking, (and we debug assert)
+ * this is a potential feeble attempt at only writing the first
+ * panic's context to the file
+ */
+
+ static bool once = false;
+
+ if (!once)
+ {
+ once = true;
+
+ DEBUGASSERT(fileno > 0 && fileno < CONFIG_STM32_BBSRAM_FILES);
+
+ bbf = g_bbsram[fileno].bbf;
+
+ DEBUGASSERT(bbf);
+
+ if (bbf)
+ {
+ /* Clamp length if too big */
+
+ if (length > bbf->len)
+ {
+ length = bbf->len;
+ }
+
+ stm32_bbsram_unlock();
+
+ stm32_bbsram_internal_write(bbf, (char *) context, 0, length);
+
+ /* Fill with 0 if data is less then file size */
+
+ fill = (int) bbf->len - length;
+
+ if (fill > 0)
+ {
+ memset(&bbf->data[length], 0, fill);
+ }
+
+ /* Seal the file */
+
+ stm32_bbsram_internal_close(bbf);
+
+ stm32_bbsram_lock();
+ }
+ }
+
+ return length;
+}
+#endif
+
+#endif /* CONFIG_BBSRAM_DRIVER */
diff --git a/nuttx/arch/arm/src/stm32/stm32_bbsram.h b/nuttx/arch/arm/src/stm32/stm32_bbsram.h
new file mode 100644
index 000000000..69d0046f5
--- /dev/null
+++ b/nuttx/arch/arm/src/stm32/stm32_bbsram.h
@@ -0,0 +1,166 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_bbsram.h
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ * David Sidrane <david_s5@nscdg.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H
+#define __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H
+
+/****************************************************************************
+ * The purpose of this driver is to add battery backup file to the file
+ * system. There can be CONFIG_STM32_BBRSRAM_COUNT files defined.
+ * These files are of fixed size up to the maximum of the backing SRAM.
+ * In the care of the STM32F2 and STM32F4 this is a maximum of 4K Bytes.
+ *
+ * If CONFIG_SAVE_CRASHDUMP is defined The driver also supports a feature
+ * to save the context of a PANIC in one of these files.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
+# define STM32_BBSRAM_SIZE 4096
+#else
+# error No backup SRAM on this STM32
+#endif
+
+#if !defined(CONFIG_STM32_BBSRAM_FILES)
+# define CONFIG_STM32_BBSRAM_FILES 4
+#endif
+
+/* REVISIT: What guarantees that STM32_BBSRAM_GETDESC_IOCTL has a unique
+ * value among all over _DIOC() values?
+ */
+
+#define STM32_BBSRAM_GETDESC_IOCTL _DIOC(0x0010) /* Returns a bbsramd_s */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+enum bbsramdf_e
+{
+ eCRCValid = 1, /* The crc is valid */
+ eDirty = 2, /* The file was closed */
+
+};
+
+struct bbsramd_s
+{
+ uint8_t flags; /* The crc is valid and the file was closed */
+ uint8_t fileno; /* The minor number */
+ uint16_t len; /* Total Bytes in this file*/
+ struct timespec lastwrite; /* Last write time */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+# define EXTERN extern "C"
+extern "C"
+{
+#else
+# define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+/****************************************************************************
+ * Function: stm32_bbsraminitialize
+ *
+ * Description:
+ * Initialize the Battery Backed up SRAM driver.
+ *
+ * Parameters:
+ * devpath - the path to instantiate the files.
+ * sizes - Pointer to a any array of file sizes to create
+ * the last entry should be 0
+ * A size of -1 will use all the remaining spaces
+ *
+ * If the length of sizes is greater then CONFIG_STM32_BBSRAM_FILES
+ * CONFIG_STM32_BBSRAM_FILES will be returned.
+ *
+ * Returned Value:
+ * Number of files created on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int stm32_bbsraminitialize(char *devpath, int *sizes);
+
+/****************************************************************************
+* Function: stm32_bbsram_savepanic
+*
+* Description:
+* Saves the panic context in a previously allocated BBSRAM file
+*
+* Parameters:
+* fileno - the value returned by the ioctl STM32_BBSRAM_GETDESC_IOCTL
+* context - Pointer to a any array of bytes to save
+* length - The length of the data pointed to byt context
+*
+* Returned Value:
+* Length saved or negated errno.
+*
+* Assumptions:
+*
+****************************************************************************/
+
+#if defined(CONFIG_STM32_SAVE_CRASHDUMP)
+int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32_STM32_BBSRAM_H */
diff --git a/nuttx/arch/arm/src/stm32/stm32_ccm.c b/nuttx/arch/arm/src/stm32/stm32_ccm.c
index c3f72a398..c3f72a398 100755..100644
--- a/nuttx/arch/arm/src/stm32/stm32_ccm.c
+++ b/nuttx/arch/arm/src/stm32/stm32_ccm.c
diff --git a/nuttx/arch/arm/src/stm32/stm32_ccm.h b/nuttx/arch/arm/src/stm32/stm32_ccm.h
index 91b330387..91b330387 100755..100644
--- a/nuttx/arch/arm/src/stm32/stm32_ccm.h
+++ b/nuttx/arch/arm/src/stm32/stm32_ccm.h
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c b/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
index 592fb3290..592fb3290 100755..100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
diff --git a/nuttx/arch/arm/src/stm32/stm32_sdio.c b/nuttx/arch/arm/src/stm32/stm32_sdio.c
index 8d44f8e9b..8d44f8e9b 100755..100644
--- a/nuttx/arch/arm/src/stm32/stm32_sdio.c
+++ b/nuttx/arch/arm/src/stm32/stm32_sdio.c
diff --git a/nuttx/arch/arm/src/stm32/stm32_usbhost.c b/nuttx/arch/arm/src/stm32/stm32_usbhost.c
index cfd33c1d9..cfd33c1d9 100755..100644
--- a/nuttx/arch/arm/src/stm32/stm32_usbhost.c
+++ b/nuttx/arch/arm/src/stm32/stm32_usbhost.c