diff --git a/ChangeLog b/ChangeLog index 0b23207da5d..b15cac83e30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4178,3 +4178,21 @@ * configs/stm32f3discovery/nsh/defconfig: Disable SPI. It is nto used. * drivers/mtd/sst39vf: Add a driver for the SST29VF NOR FLASH parts. + * sched/os_start.c: Add an additional call-out to support board- + specific driver initialization during the start phase: If + CONFIG_BOARD_INITIALIZE is defined, then an additioinal + initialization function called board_initialize() will be called + just after up_initialize() is called and just before the initial + application is started. + * arch/arm/src/stm32/stm32_otgfsdev.c, drivers/usbdev/usbdev_trprintf.c, + and include/nuttx/usb/usbdev_trace.h: Add logic to support decoding + of device-specific trace events to make the trace ouput more readable. + From Petteri Aimonen. + * arch/arm/src/stm32/stm32_otgfsdev.c: Need to manually set CNAK in + the case where we are waiting for a SETUP command with DATA. Otherwise, + the core may NAK further transactions. From Petteri Aimonen. + * arch/arm/src/stm32/stm32_otgfsdev.c: Add logic to prevent premature + to IDLE state. This change (plus the previous) was necessary to get + the CDC/ACM driver working the certain STM32 F4 hardware (but not others). + These changes appear to prevent certain race conditions that may or may + not cause USB problems. From Petteri Aimonen. diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html index 3df2dfa9d22..a12e61335ae 100644 --- a/Documentation/NuttxUserGuide.html +++ b/Documentation/NuttxUserGuide.html @@ -13,7 +13,7 @@
User's Manual
by
Gregory Nutt
-
Last Updated: February 5, 2013
+Last Updated: February 13, 2013
@@ -1999,8 +1999,22 @@ priority of the calling task is returned.
- atexit() and on_exit() may be use to register callback functions that are executed when a task exits.
+ Task Exit Hooks.
+ atexit() and on_exit() may be use to register callback functions that are executed when a task group terminates.
+ A task group is the functional analog of a process:
+ It is a group that consists of the main task thread and of all of the pthreads created by the main task thread or any of the other pthreads within the task broup.
+ Members of a task group share certain resources such as environment variables, file descriptors, FILE streams, sockets, pthread keys and open message queues.
+
+ NOTE: + Behavior of features related to task groups depend of NuttX configuration settings. + See the discussion of "Parent and Child Tasks," below. + See also the NuttX Threading Wiki page and the Tasks vs. Threads FAQ for additional information on tasks and threads in NuttX. ++
+ A task group terminates when the last thread within the group exits.
+
+ NOTE: + Behavior of features related to task groups depend of NuttX configuration settings. See the NuttX Threading Wiki page and the Tasks vs. Threads FAQ for additional information on tasks and threads in NuttX. - +
Signalling Multi-threaded Task Groups. The behavior of signals in the multi-thread task group is complex. @@ -5326,68 +5342,114 @@ be sent.
NuttX does not support processes in the way that, say, Linux does.
NuttX only supports simple threads or tasks running within the same address space.
- For the most part, threads and tasks are interchangeable and differ primarily
- only in such things as the inheritance of file descriptors.
- Basically, threads are initialized and uninitialized differently and share a
- few more resources than tasks.
+ However, NuttX does support the concept of a task group.
+ A task group is the functional analog of a process:
+ It is a group that consists of the main task thread and of all of the pthreads created by the main thread or any of the other pthreads within the task broup.
+ Members of a task group share certain resources such as environment variables, file descriptors, FILE streams, sockets, pthread keys and open message queues.
+
+ NOTE: + Behavior of features related to task groups depend of NuttX configuration settings. + See the NuttX Threading Wiki page and the Tasks vs. Threads FAQ for additional information on tasks and threads in NuttX. +
The following pthread interfaces are supported in some form by NuttX:
+ pthread control interfaces. + Interfaces that allow you to create and manage pthreads. +
++ Thread Specific Data. + These interfaces can be used to create pthread keys and then to access thread-specific data using these keys. + Each task group has its own set of pthread keys. + NOTES: (1) pthread keys create in one task group are not accessible in other task groups. + (2) The main task thread does not had thread-specific data. +
++ pthread Mutexes. +
++ Condition Variables. +
++ Barriers. +
++ Initialization. +
+ ++ Signals. +
+
No support for the following pthread interfaces is provided by NuttX:
diff --git a/arch/arm/src/stm32/stm32_otgfsdev.c b/arch/arm/src/stm32/stm32_otgfsdev.c
index bcce3ce608c..1496dc5a826 100644
--- a/arch/arm/src/stm32/stm32_otgfsdev.c
+++ b/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -679,6 +679,99 @@ static const struct usbdev_ops_s g_devops =
.pullup = stm32_pullup,
};
+/* Device error strings that may be enabled for more desciptive USB trace
+ * output.
+ */
+
+#ifdef CONFIG_USBDEV_TRACE_STRINGS
+const struct trace_msg_t g_usb_trace_strings_deverror[] =
+{
+ TRACE_STR(STM32_TRACEERR_ALLOCFAIL ),
+ TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ),
+ TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADEPNO ),
+ TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADGETCONFIG ),
+ TRACE_STR(STM32_TRACEERR_BADGETSETDESC ),
+ TRACE_STR(STM32_TRACEERR_BADGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADSETADDRESS ),
+ TRACE_STR(STM32_TRACEERR_BADSETCONFIG ),
+ TRACE_STR(STM32_TRACEERR_BADSETFEATURE ),
+ TRACE_STR(STM32_TRACEERR_BADTESTMODE ),
+ TRACE_STR(STM32_TRACEERR_BINDFAILED ),
+ TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ),
+ TRACE_STR(STM32_TRACEERR_DRIVER ),
+ TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED),
+ TRACE_STR(STM32_TRACEERR_EP0NOSETUP ),
+ TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ),
+ TRACE_STR(STM32_TRACEERR_EPINNULLPACKET ),
+ TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ),
+ TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ),
+ TRACE_STR(STM32_TRACEERR_INVALIDPARMS ),
+ TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ),
+ TRACE_STR(STM32_TRACEERR_NOEP ),
+ TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ),
+ TRACE_STR(STM32_TRACEERR_EPOUTQEMPTY ),
+ TRACE_STR(STM32_TRACEERR_EPINREQEMPTY ),
+ TRACE_STR(STM32_TRACEERR_NOOUTSETUP ),
+ TRACE_STR(STM32_TRACEERR_POLLTIMEOUT ),
+ TRACE_STR_END
+};
+#endif
+
+/* Interrupt event strings that may be enabled for more desciptive USB trace
+ * output.
+ */
+
+#ifdef CONFIG_USBDEV_TRACE_STRINGS
+const struct trace_msg_t g_usb_trace_strings_intdecode[] =
+{
+ TRACE_STR(STM32_TRACEINTID_USB ),
+ TRACE_STR(STM32_TRACEINTID_INTPENDING ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT ),
+ TRACE_STR(STM32_TRACEINTID_EPIN ),
+ TRACE_STR(STM32_TRACEINTID_MISMATCH ),
+ TRACE_STR(STM32_TRACEINTID_WAKEUP ),
+ TRACE_STR(STM32_TRACEINTID_SUSPEND ),
+ TRACE_STR(STM32_TRACEINTID_SOF ),
+ TRACE_STR(STM32_TRACEINTID_RXFIFO ),
+ TRACE_STR(STM32_TRACEINTID_DEVRESET ),
+ TRACE_STR(STM32_TRACEINTID_ENUMDNE ),
+ TRACE_STR(STM32_TRACEINTID_IISOIXFR ),
+ TRACE_STR(STM32_TRACEINTID_IISOOXFR ),
+ TRACE_STR(STM32_TRACEINTID_SRQ ),
+ TRACE_STR(STM32_TRACEINTID_OTG ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_XFRC ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_EPDISD),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_SETUP ),
+ TRACE_STR(STM32_TRACEINTID_DISPATCH ),
+ TRACE_STR(STM32_TRACEINTID_GETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS),
+ TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_CLEARFEATURE),
+ TRACE_STR(STM32_TRACEINTID_SETFEATURE ),
+ TRACE_STR(STM32_TRACEINTID_SETADDRESS ),
+ TRACE_STR(STM32_TRACEINTID_GETSETDESC ),
+ TRACE_STR(STM32_TRACEINTID_GETCONFIG ),
+ TRACE_STR(STM32_TRACEINTID_SETCONFIG ),
+ TRACE_STR(STM32_TRACEINTID_GETSETIF ),
+ TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_XFRC ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_TOC ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_ITTXFE ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_EPDISD ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_TXFE ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_EMPWAIT),
+ TRACE_STR(STM32_TRACEINTID_OUTNAK ),
+ TRACE_STR(STM32_TRACEINTID_OUTRECVD ),
+ TRACE_STR(STM32_TRACEINTID_OUTDONE ),
+ TRACE_STR(STM32_TRACEINTID_SETUPDONE ),
+ TRACE_STR(STM32_TRACEINTID_SETUPRECVD ),
+ TRACE_STR_END
+};
+#endif
+
/*******************************************************************************
* Public Data
*******************************************************************************/
@@ -1142,7 +1235,7 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
/* Add one more packet to the TxFIFO. We will wait for the transfer
* complete event before we add the next packet (or part of a packet
* to the TxFIFO).
- *
+ *
* The documentation says that we can can multiple packets to the TxFIFO,
* but it seems that we need to get the transfer complete event before
* we can add the next (or maybe I have got something wrong?)
@@ -2459,16 +2552,16 @@ static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno)
/* Continue processing data from the EP0 OUT request queue */
stm32_epout_complete(priv, privep);
- }
- /* If we are not actively processing an OUT request, then we
- * need to setup to receive the next control request.
- */
+ /* If we are not actively processing an OUT request, then we
+ * need to setup to receive the next control request.
+ */
- if (!privep->active)
- {
- stm32_ep0out_ctrlsetup(priv);
- priv->ep0state = EP0STATE_IDLE;
+ if (!privep->active)
+ {
+ stm32_ep0out_ctrlsetup(priv);
+ priv->ep0state = EP0STATE_IDLE;
+ }
}
}
@@ -2626,16 +2719,16 @@ static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno)
/* Continue processing data from the EP0 OUT request queue */
stm32_epin_request(priv, privep);
- }
- /* If we are not actively processing an OUT request, then we
- * need to setup to receive the next control request.
- */
+ /* If we are not actively processing an OUT request, then we
+ * need to setup to receive the next control request.
+ */
- if (!privep->active)
- {
- stm32_ep0out_ctrlsetup(priv);
- priv->ep0state = EP0STATE_IDLE;
+ if (!privep->active)
+ {
+ stm32_ep0out_ctrlsetup(priv);
+ priv->ep0state = EP0STATE_IDLE;
+ }
}
/* Test mode is another special case */
@@ -2754,7 +2847,7 @@ static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv)
* interrupt here; it will be re-enabled if there is still
* insufficient space in the TxFIFO.
*/
-
+
empty &= ~OTGFS_DIEPEMPMSK(epno);
stm32_putreg(empty, STM32_OTGFS_DIEPEMPMSK);
stm32_putreg(OTGFS_DIEPINT_XFRC, STM32_OTGFS_DIEPINT(epno));
@@ -3063,6 +3156,12 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
datlen = GETUINT16(priv->ctrlreq.len);
if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0)
{
+ /* Clear NAKSTS so that we can receive the data */
+
+ regval = stm32_getreg(STM32_OTGFS_DOEPCTL0);
+ regval |= OTGFS_DOEPCTL0_CNAK;
+ stm32_putreg(regval, STM32_OTGFS_DOEPCTL0);
+
/* Wait for the data phase. */
priv->ep0state = EP0STATE_SETUP_OUT;
@@ -3654,7 +3753,7 @@ static int stm32_epout_configure(FAR struct stm32_ep_s *privep, uint8_t eptype,
{
regval |= OTGFS_DOEPCTL_CNAK;
}
-
+
regval &= ~(OTGFS_DOEPCTL_MPSIZ_MASK | OTGFS_DOEPCTL_EPTYP_MASK);
regval |= mpsiz;
regval |= (eptype << OTGFS_DOEPCTL_EPTYP_SHIFT);
@@ -3750,7 +3849,7 @@ static int stm32_epin_configure(FAR struct stm32_ep_s *privep, uint8_t eptype,
{
regval |= OTGFS_DIEPCTL_CNAK;
}
-
+
regval &= ~(OTGFS_DIEPCTL_MPSIZ_MASK | OTGFS_DIEPCTL_EPTYP_MASK | OTGFS_DIEPCTL_TXFNUM_MASK);
regval |= mpsiz;
regval |= (eptype << OTGFS_DIEPCTL_EPTYP_SHIFT);
diff --git a/drivers/usbdev/Kconfig b/drivers/usbdev/Kconfig
index 0752bb7910a..f8e21c14377 100644
--- a/drivers/usbdev/Kconfig
+++ b/drivers/usbdev/Kconfig
@@ -83,6 +83,21 @@ config USBDEV_TRACE_NRECORDS
---help---
Number of trace entries to remember
+config USBDEV_TRACE_STRINGS
+bool "Decode device controller events"
+ default n
+ depends on USBDEV_TRACE
+ ---help---
+ If USBDEV_TRACE_STRINGS is defined, then the USB device controller
+ driver must provide arrays of strings to support decoding of device-
+ specific trace events. These arrays of strings (and the type struct
+ trace_msg_t) are defined in include/nuttx/usb/usbdev_trace.h:
+
+ #ifdef CONFIG_USBDEV_TRACE_STRINGS
+ extern const struct trace_msg_t g_usb_trace_strings_deverror[];
+ extern const struct trace_msg_t g_usb_trace_strings_intdecode[];
+ #endif
+
endmenu
menuconfig USBDEV_COMPOSITE
diff --git a/drivers/usbdev/usbdev_trprintf.c b/drivers/usbdev/usbdev_trprintf.c
index 2a9921f985c..edaa8968587 100644
--- a/drivers/usbdev/usbdev_trprintf.c
+++ b/drivers/usbdev/usbdev_trprintf.c
@@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/usbdev_trprintf.c
*
- * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008-2010, 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt