diff --git a/ChangeLog b/ChangeLog index 7e92de8a31dbec3167b9a5f318c7b7b05f2e1c8d..423290c841e341e027364a6286f18a0380833cec 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1233,7 +1233,7 @@ macros definitions (patch submitted by Tiago Maluta). * Documents/NuttxPortingGuide.html, configs/README.txt, etc. - Replaced CONFIG_EXAMPLE with CONFIG_APP_DIR (see documents for - desciption). This allows NuttX application code to be built + description). This allows NuttX application code to be built outside of the examples/ directory. For people who have their own configurations and/or Makefiles, @@ -1325,7 +1325,7 @@ * configs/avr32dev1/nsh: Added a configuration to support the NuttShell (NSH). As of this writing, here is a problem receiving serial data (this is, very likely, my hardware setup). - * lib/lib_open.c: Fix an error in fdopen when a valid file desciptor does + * lib/lib_open.c: Fix an error in fdopen when a valid file descriptor does not refer to an open file. * configs/olimex-lpc1766stk: Add support for the Olimex LPC1766-STK development board. The OS test and NSH configurations (only) have been @@ -1654,7 +1654,7 @@ * arch/*/include/*/type.h: On some compilers, char defaults as unsigned. Explicitly add signed to integer types if signed is what is required. * arch/*: For all architectures -- Global register state save structure - (usually called current_regs) should be marked volatile; Added general + (usually called g_current_regs) should be marked volatile; Added general capability to support nested interrupts (not fully realized for all architectures). * sched/task_create.c: Add support for starting kernel-mode thread. @@ -2741,7 +2741,7 @@ the worker thread, disabling interrupts does not provide protected; Need to disable pre-emption. (2) Fix handling of touch ID and (2) add some logic to prevent certain kinds of data overrun. - * include/nx/nxtk.h and graphics/nx/nxtk/nxtk_internal.h: Move setting + * include/nx/nxtk.h and graphics/nx/nxtk/nxtk.h: Move setting of configuration defaults from the internal header file to a place where other logic can use the defaults. * graphics/nxtk/nxtk_events.c: Fixed an important but in the logic that @@ -4114,7 +4114,7 @@ group exits. * sched/waitpid.c, task_exithook.c and include/nuttx/sched.h: Move waitpid data data structures to task group. Callers of - of waitpid() are now only awakened whent he final thread of the + of waitpid() are now only awakened when the final thread of the task group exits. * sched/mq_descreate.c, mq_open.c, mq_remove.c, group_leave.c, and include/nuttx/sched.h: Move list of opened message queues to @@ -4533,7 +4533,7 @@ * arch/arm/src/lpc17_lcd.c: Rommel Marcelo got the LPC1788 framebuffer-based LCD working. Very nice! (2013-4-08). * arch/arm/src/lm/lm_clockconfig.c and configs/lm4f120-launchpad: - Fix handling of the RCC SYSDIV2 field whent the PLL output is + Fix handling of the RCC SYSDIV2 field when the PLL output is 400MHz. Don't forget to set the USERCC2 bit in the register or all is for naught (2013-4-09). * configs/zkit-arm-1769/src/up_lcd.c, up_ssp.c, and up_spi.c: @@ -4680,7 +4680,7 @@ * arch/arm/src/kl/kl_gpio.c and .h, configs/freedom-kl25z/src/freedom-kl25z.h, and configs/freedom-kl25z/src/kl_led.c: Fixes LEDs on the Freedom KL25Z board (2013-5-6). - * arch/arm/src/kinetis/kinetis_pin.c and arch/arm/src/kinetis/kinetis_internal.h: + * arch/arm/src/kinetis/kinetis_pin.c and arch/arm/src/kinetis/kinetis.h: The Kinetis GPIO logic had some of the same issues as did the Kinetis L (2013-5-6). * arch/arm/src/stm32/stm32_idle.c: Add an option to conditionally disable @@ -5333,7 +5333,7 @@ * arch/arm/src/sama5/sam_memories.c and .h: Centralize logic for conversions between physical and virtual addresses (2013-8-9). * arch/arm/src/sama5/sam_hsmci.c and sam34/sam_hsmci.c: Correct a - race condition in the SAMA5 HSCMI driver: The tranfer done + race condition in the SAMA5 HSCMI driver: The transfer done interrupt was firing before the wait was started. Fix this and also backported the changes to SAM3/4 (untested). Now HSCMI is functional on the SAMA5 with DMA! (2013-8-10). @@ -9175,7 +9175,7 @@ build framework and skeleton files for Tiva I2C driver. Initial commit is just the STM32 I2C driver with name changes and STM32- specific logic removed (2014-12-9). - * fs/procfs/fs_procfs.c: Add procfs write support. From Ken Petit + * fs/procfs/fs_procfs.c: Add procfs write support. From Ken Pettit (2014-12-9). * include/crc8.h, libc/misc/lib_crc8.c, and Make.defs: Add CRC8 support. From Ken Pettit (2014-12-9). @@ -10045,7 +10045,7 @@ stm32_rtcc.c, stm32_rtcounter.c, and stm32f*_rcc.c: The STM32F4Discovery board doesn't come with a Low speed external oscillator so the default LSE source for the RTC doesn't work. In - stm32_rtcc.c the up_rtcinitialize() logic doesn't work with the LSI. + stm32_rtcc.c the up_rtc_initialize() logic doesn't work with the LSI. The check on RTC_MAGIC on the BK0R register lead to rtc_setup() call that rightfully enables the lsi clock; but the next times, when the rtc is already setup, the rtc_resume() call does NOT start the lsi @@ -10383,7 +10383,7 @@ corrected implementation of pthread_kill() will direct the signal specifically to the specific pthread and no other (2015-05-13). * arch/arm/include/samdl, arch/arm/src/samdl, configs/samd20-xplained: - Rename the samd/ directories and configuratino varialbes to samdl to + Rename the samd/ directories and configuration varialbes to samdl to all the same directory structure to support the SAML21 (2015-05-14). * arch/arm/include/samdl and arch/arm/src/samdl: And chip definitions, configuration framework, and placeholder memory map and pin @@ -10559,7 +10559,7 @@ * arch/arm/src/sama5/sam_can.c: Fix SAMA5 CAN frame construction. From Max Holtzberg (2015-06-07). -7.11 2015-xx-xx Gregory Nutt +7.11 2015-08-13 Gregory Nutt * arch/arm/src/efm32/efm32_spi.c: Correct write to incorrect register in EFM32 SPI driver. From Pierre-noel Bouteville (2015-06-09). @@ -10600,7 +10600,7 @@ * arch/arm/include/samdl and arch/arm/src/samdl: Add architecture support for the SAMD21 family (2015-06-19). * configs/samd21-xplained: Board configuration for the SAMD21 Xplained - bord (2015-06-21). + board (2015-06-21). * arch/arm/src/sam34/sam_lowputc.c: Back out an error introduced with commit 02c33f66c5a8be774034cd40e4125e9323c7b4d8. Causes an infinite loop in up_lowputc(). From Max Neklyudov (2015-06-22). @@ -10618,8 +10618,8 @@ * SAM3/4: Add a TWI driver for the SAM4CM. From Max Neklyudov (2015-06-22). * SAMV7 Xplained: In clock configuration, divider was set to 25 to get - 25*12MHz=300MHz CPU clock. The correct multiplier is 24 becaue the - calculatin if (24+1)*12MHz. So the board was running at 312MHz. + 25*12MHz=300MHz CPU clock. The correct multiplier is 24 because the + calculation if (24+1)*12MHz. So the board was running at 312MHz. From Efim Monjak (2015-06-26). * NFS client: Fix prototype of unbind method. The function prototype was not updated for NFS after a recent change to the file system @@ -10729,7 +10729,7 @@ for the STMicro STM32 F7 (2015-07-15). * drivers/can.c: Fix an issue in the CAN driver where the rx_sem count can grow beyond bounds (2015-07-15). - * configs/stm32f762g-disco/: Add initialize support for the STMicor + * configs/stm32f762g-disco/: Add initialize support for the STMicro STM32 F7 Discovery board. This is a work in progress and will be a while before it is fully functional (2015-07-16). * arch/../up_etherstub.c, arch/../up_initialize, and other files: Add @@ -10787,17 +10787,784 @@ * arch/arm/src/samv7: Add an MCAN driver for the SAMV7 platform (2015-08-06). * drivers/sensors/lm92.c and include/nuttx/sensors/lm92.h: Add a driver - for the LM92 temperature sensor. Contributed by Paul Patience + for the LM92 temperature sensor. Contributed by Paul Alexander Patience (2015-08-06). * drivers/sensors/as5048b.c and include/nuttx/sensors/as5048b.h: Add - support for an AS5048B rotary magnetic sensor. From Paul Patience - (2015-08-06). + support for an AS5048B rotary magnetic sensor. From Paul Alexander + Patience (2015-08-07). * include/nuttx/spi/slave.h: Add a definition of an SPI slave interface (2015-08-08). - * arch/arm/src/samv7: Add the framework for an SPI slave drvier. This + * arch/arm/src/samv7: Add the framework for an SPI slave driver. This driver has a lot of missing logic on initial commit (2015-08-09). * arch/arm/src/samv7: Basic, no-DMA SPI slave driver is in place - (2015-080=-10). + (2015-08-10). * fs/vfs/epoll.c and include/sys/epoll.h: Add a very simple epoll layer just around poll calls. To satisfy build app requirements. From Anton - D. Kachalov. + D. Kachalov (2015-08-10). + * drivers/mtd/ramtron.c: Update to include supportf for newer + RAMTRON parts. From David Sidrane (2015-08-10). + * Networking: Allow receipt of empty UDP packets. From Max Neklyudov + (2015-08-11). + * drivers/sensors/mb7040.c and include/nuttx/sensors/mb7040.h: Add + support for a MB7040 sonar driver. From Paul Alexander Patience + (2015-08-11). + * net/udp: Add support for send() for connected UDP sockets + (2015-08-11). + * drivers/sensors/ms5805.c and include/nuttx/sensors/ms5805.h: Add + support for an MS5805 altimeter. From Paul Alexander Patience + (2015-08-12). + +7.12 2015-10-01 Gregory Nutt + + * fs/vfs/fs_poll.c: Use sem_tickwait() instead of sem_timedwait() + From Macs Neklyudov (2015-08-13). + * fs/vfs/fs_poll.c: If we fail to setup the poll for any file + descriptor, for any reason, set the POLLERR bit (2015-08-13). + * libc/stdlib: Add support for div() to the C library. From + OrbitalFox (2015-08-14). + * libc/stdlib: Might as well add ldiv() and lldiv() to since + these are equivalent to div() with long and long long types, + respectively, instead of int (2015-08-14). + * include/signal.h and files that include it: Add si_errno to + siginfo_t (2015-08-14). + * drivers/sensors/mx58xx.c and include/nuttx/sensors/ms58xx.h: + Generalize the MS5805 altimeter driver to support other family + members and rename to ms58xx. From Paul Alexander Patience + (2015-08-14). + * Network drivers. Fix bug in tun interface driver. From Max + Neklyudov (2015-08-17). + * STM32: Added definitions for STM32F303K6, STM32F303K8, STM32F303C6, + STM32F303C8, STM32F303RD, and STM32F303RE devices. From Paul + Alexander Patience (2015-08-17). + * include/nuttx/can.h and all CAN drivers: Add an error indication + bit to the CAN message report. This indication must then be cleared + in all existing drivers. More to come (2015-08-18). + * arch/arm/src/lpc17/lpc17_irq.c: Set NVIC vector address so that + code can execute with a bootloader or can execute from RAM. From + Pavel Pisa (2015-08-20). + * All ARMV7-M IRQ setup: Always set the NVIC vector table address + unconditionally. This is needed in cases where the code is running + with a bootload and when the code is running from RAM. It is also + needed by the logic of up_ramvec_initialize() which gets the vector + base address from the NVIC. Suggested by Pavel Pisa (2015-08-21). + * SAMV7 USBHS DCD: The device controller driver is (finally) functional + (2015-08-21). + * recvfrom(): Correct wait for new data when NET_UDP_READAHEAD is + enabled. Fix size accounting when recvfrom_udpreadahead() sets + state.rf_recvlen == -1. I have not checked if data are accumulated + to the right position in the buffer however. From Pavel Pisa + (2015-08-21). + * sched/wdog/wd_create.c: Correct a counting error in the number + of available watchdog timers. When the number of free timers is + low, the counter could be incremented below zero (2015-08-21). + * arch/arm/src/stm32: Add OTG support for STM32F44x. From David + Sidrane (2015-08-21). + * arch/arm/src/lpc17: Actually implement options to use external + SDRAM and or SRAM for the heap. From Pavel Pisa (2015-08-21). + * gethostbyname(): correct returned address format when DNS is used. + The hostent.h_addr_list should point to raw in_addr or in6_addr + as defined in the standard. Original implementation used that + for numeric addresses but for DNS lookup returned pointer to + whole sockaddr_in or sockaddr_in6. From Pavel Pisa (2015-08-21). + * tools/mksymtab: declare g_symtab array as const to occupy RO + section (Flash). From Pavel Pisa (2015-08-23). + * libc/libc.csv and syscalls/syscalls.csv: Define some symbol + export conditions, correct errno and add sleep and usleep. From + Pavel Pisa (2015-08-23). + * net/ and include/nuttx/net: Remove references to PPP as a + link layer protocol (2015-08-24). + * net/, drivers/net, and include/net: Add definitions to support + a local loopback device and link layer (2015-08-24). + * libc/netdb, net/loopback, include/nuttx/net: Add NetDB support + for the local loopback device (2015-08-24). + * drivers/net/loopback.c: Add basic prototype of a local loopback + device (2015-08-24). + * networking: Correct return value from psock_tcp_accept(). From + SaeHie Park (2015-08-25). + * drivers/mtd/s25fl1.c: Add a driver for ST25L1*K QuadSPI parts + (2015-08-25). + * include/nuttx/spi/qspi.h: Develop a new interface for QSPI, at + least the way that QSPI is implemented on the SAMV71. Originally + planned to use the SPI interface, but it is just now compatible + with the SAMV71 QSPI hardware (2015-08-25). + * drivers/rwbuffer.c: Fix some logic errors. From Dmitry Nikolaev + via Juha Niskanen (2015-08-26). + * net/socket and net/tcp: Fix a problem in when there are multiple + network devices. Polls were being sent to all TCP sockets before. + This is not good because it means that packets may sometimes be + sent out on the wrong device. That is inefficient because it + will cause retransmissions and bad performance. But, worse, when + one of the devices is not Ethernet, it will have a different MSS + and, as a result, incorrect data transfers can cause crashes. + The fix is to lock into a single device once the MSS is locked + locked down (2015-08-27). + * drivers/lcd and include/nuttx/lcd: Add SSD1351 OLED controller + support. Contributed by Paul Alexander Patience (2015-08-28). + * include/nuttx/mtd/mtd.h: Move MTD ioctl command definitions from + include/nuttx/fs/fs.h to include/nuttx/mtd.h. Add ioctl commands + to protect and unprotect memory (2015-08-29). + * binfmt/builtin.c: Fix a memory leak: File was not being closed. + From Bruno Herrera (2015-08-30). + * fs/romfs: One allocation was not being freed if there was a + subsequent failure to allocation I/O buffers resulting in a memory + leak on certain error conditions. From Bruno Herrera (2015-08-30). + * arch/arm/src/up_internal.h and several ARM Make.defs files: In the + original implementation, !defined(CONFIG_ARMV7M_CMNVECTOR) was a + sufficient test to determine if lazy floating point register saving + was being used. But recents changes added common lazy register as + well so now that test must be (!defined(CONFIG_ARMV7M_CMNVECTOR) || + defined(CONFIG_ARMV7M_LAZYFPU)) (2015-08-31). + * arch/arm/include/sama5 and src/sama5: Add basic chip description, + configuration support and interrupt definitions for the SAMA5D2 + (2015-08-31). + * LPC43xx: Fix NVIC_SYSH_PRIORITY_STEP define. From Ilya Averyanov + (2015-09-01). + * LPC43xx: Fix missing #define in eeprom. From Ilya Averyanov + (2015-09-01). + * libc/math/lib_asin.c: The function did not convert for some input + values. Asin did not convert for values which do not belong to the + domain of the function. But aside of that the function also did not + converge for some allowed values. I achieved a conversion of the + function by reducing the DBL_EPSION and by checking if the input + value is in the domain of the function. This is a fix for the + problem but the function should always terminate after a given + number of iterations. From Stefan Kolb (2015-09-01). + * arch/arm/src/lpc43xx/lpc43_spi.c: Fix SPI driver. From Ilya + Averyanov (2015-09-02). + * arch/arm/src/lpc43xx/lpc43_ethernet.c: Add Ethernet support. From + Ilya Averyanov (2015-09-02). + * net/tcp: The logic that binds a specific network device to + a connection was faulty for the case of multiple network + devices. On bind(), the local address should be used to associate + a device with the connection (if the local address is not INADDR_ANY); + On connect(), the remote address should be used (in case the local + address is INADDR_ANY). On accept(), it does not matter but the + remote address is the one guaranteed to be available (2015-09-02). + * configs/Board.mk and configs/*/src/Makefile: Simplify configs/ + Makefiles by combining common logic into a new Board.mk Makefile + fragment. From Paul Alexander Patience (2015-09-04). + * configs/sama5d2-xult: Add a very basic configuration for the SAMAD2 + Xplained Ultra board. This configuration is incomplete and only + intended to support the initial board bring-up (2015-09-05). + * up_initialize() all architectures: Automatically initialize all + the TUN device if it is in the configuration (2015-09-06). + * Change all references from avsprintf to vasprintf. From Sebastien + Lorquet (2015-09-07). + * net/tcp: Fix unbuffered send compilation error when Ethernet is not + enabled. From Alan Cavalho de Assis (2015-09-07). + * LPC31 and SAMA5D EHCI: Fix qh_ioccheck to move bp to next QH. From + Ilya Averyanov (2015-09-07). + * LPC31 and SAMA5D EHCI: Performance improvement: Do not disable the + asynchronous queue when adding a new QH structure. From Ilya + Averyanov (2015-09-07). + * arch/arm/src/sama5: Separate memory mapping tables for SAMA5D2, 3, + and 4 (2015-09-08). + * libc/net/lib_shutdown.c: Add an empty implementation of the + standard shutdown function. This provides only the framework for + the shutdown function; the internal logic is not included + (2015-09-09). + * configs/nucleo-f303re: Support for the STMicro Nucleo F303RE board + from Paul Alexander Patience (2015-09-10). + * arch/arm/src/lpc43xx/lpc32_ehci.c and .h: LPC43xx EHCI driver from + Ilya Averyanov (2015-09-10). + * ARMv7-M, all "lazy" interrupt stack logic. Assembly instruction + that fetches the saved value is incorrect; replace with more + traditional push and pop. This is an important fix. Noted by + Stefan Kolb (2015-09-14). + * All ARMV7-M: Force 8-byte stack alignment when calling from assembly + to C to interrupt handling (2015-09-15). + * drivers/power/battery_gauge.c and include/nuttx/power/battery_gauge.h: + battery.c/h renamed to batter_gauge.c/.h since it really only + implements a battery fuel gauge. From Alan Carvalho de Assis (2015-09-19). + * drivers/power/battery_charger.c and include/nuttx/power/batter_charger.h: + Add a new framework to support a batter charger interface. From Alan + Carvalho de Assis (2015-09-19). + * drivers/power/bq2425x.c and .h: Battery Charger: Add BQ24250 driver. + From Alan Carvalho de Assis (2015-09-20). + * fs/mqueue/mq_open.c: When message queue is opened, inode_reserve() + leaves the reference count at zero. mq_open() logic must assure + that the reference count of the newly created inode is one (2015-09-23). + * arch/sim/src/Kconfig, Makefile, up_setjmp64.S: Modern Cygwin X86_64 + machines follow the Microsoft ABI for parameter passing. The older, + Linux System 5 ABI will not work on X86_64-based Cygwin machines. Also, + the newer Cygwin tool chains do nor pre-pend symbol names with the + underscore character. With these changes the simulator agains works + with the newer Cygwin64 platform (2015-09-24). + * arch/arm/src/lpc43xx: Extensive I2C and clocking updates from Lok Tep + (2015-09-29). + * configs/lpc4370-link2: Support for the NXP LPC4370-Link2 development + board from Lok Tep (2015-09-29). + * configs/nucleo-f303re: Add SSD1351 SPI 4-wire interface. From Paul + Alexander Patience (2015-09-29). + * arch/arm/src/armv7-m/up_schedulesigaction.c: Fix logic that determines + if there is a pending signal action before scheduling the next signal + action. Both the test and the scheduling action need to be atomic + (2015-09-30). + * sched/wqueue/kwork_queue.c and libc/wqueue/work_queue.c: Logic that + sets the queued indication and the logic that does the actual queuing + must be atomic (2015-09-20). + +7.13 2015-12-05 Gregory Nutt + + * libc/stdlib/lib_bsearch.c and include/stdlib.h: Add the bsearch() + function from NetBSD (2015-10-02). + * libc/stdlib/lib_qsort.c and include/stdlib.h: Make coding style + more conformant, take description from OpenGroup.org, rename formal + parameters to match names used on OpenGroup.org (2015-10-02). + * drivers/lcd/st7565.c: Extend to include support for the ERC12864-3. + From Pierre-noel Bouteville (2015-10-07). + * fs/tmpfs: Created a directory that will eventually hold a trivial + temporary RAM file file system (2015-10-0i8). + * tools/: Add crappy style checking tool nxstyle.c. See thee tools/ + README file for more info (2015-10-08). + * stm32 F4: Fix some TIM12 pin mappings. From Max Kriegleder + (2015-10-9). + * fs/tmpfs: TMPFS file system is code complete and bascially functional + although it has not been heavily tested (2015-10-9). + * drivers/input/button_upper.c and include/nuttx/input/buttons.h: Add a + driver to support application access to board buttons (2015-10-12). + * drivers/input/button_lower.c: Add a generic lower half button driver. + This lower half driver is only usable in a limited number of + situations, but can still serve as a module for the lower half button + driver. (2015-10-13). + * drivers/sensors/zerocross.c and include/nuttx/sensors/zerocross.h: + Add Zero Cross device driver support. From Alan Carvalho de Assis + (2015-10-13). + * configs/stm32f4discovery/src/stm32_zerocross.c: Add low level support + for the Zero Cross driver for the STM32F4-Discovery. From Alan + Carvalho de Assis (2015-10-13). + * drivers/sensors/max6675.c and include/nuttx/sensors/max6675.h: Add + support to Thermocouple-to-Digital converter MAX6675. From Alan + Carvalho de Assis (2015-10-18). + * configs/stm32f4discovery/src: Add board config to support MAX6675. + From Alan Carvalho de Assis (2015-10-18). + * arch/arm/src/samv7/sam_lowputc.c: Reconfigure System I/O when using + USART1. From Frank Benkert (2015-10-20). + * fs/semaphore: Named semaphores: Bad cast in sem_close(). Fixed by + reordering fields of struct nsem_inode_s so that the cast will work + (2015-10-22). + * Many files: Rename board_led_* functions to board_autoled_* functions. + This makes room in the namespace to handler user LED functions + (2015-11-01). + * Many files: Standardize naming of the user LED interface functions. + The new user LED interface functions are now prototyped in only in + include/nuttx/board.h and have name like board_userled_* (2015-11-01). + * drivers/leds/usersled_upper.c and include/leds/usersled.h: Add + a generic character driver that may be used by applications to write + to board LEDs (2015-11-01). + * drivers/leds/usersled_lower.c: Add a generic lower-half user LED + driver that may be used by any board that supports the standard + board user LED interfaces (2015-11-01). + * sched/clock: Fix error in clock_timespec_subtract(). Found by Lok + (2015-11-03). + * drivers/can.c and include/nuttx/can.h: Fix a problem in the CAN + upper-half driver that occurs only for CAN hardware that support a + H/W FIFO of outgoing CAN messages. In this case, there can be a + hang condition if both the H/W and S/W FIFOs are both full. In that + case, there may be no event to awaken the upper half driver. Add a + new (conditional) CAN upper half interface called can_txready() that + can be used by the lower half driver to avoid this hang condition + (2015-11-03). + * arch/arm/src/samv7: Add a call to can_txready() to the MCAN driver + (2015-11-03). + * arch/arm/src/samv7: Add MPU and protected build support (2015-11-06). + * arch/arm/src/samv7: The QSPI FLASH driver is now functional. This + driver operates in the memory-mapped, Serial Memory Mode (SMM) + (2015-11-07). + * drivers/bch: Block-to-character (BCH) driver should forward ioctl() + calls to the contained block driver (2015-11-09). + * arch/arm/samv7/sam_qspi.c: The QuadSPI driver is now functional + (2015-11-10). + * drivers/mtd/s25fl1.c: The S25FL1xx QuadSPI FLASH driver is now + functional (2015-10-11). + * arch/arm/samv7: Add an on-chip FLASH driver (2015-11-12). + * drivers/mtd/mtd_progmem.c: Add an upper half MTD device that can + use the interfaces defined in included/nuttx/progmem.h to provide + a standard MTD interface (2015-11-12). + * drivers/serial/serial.c, serialirq.c and include/nuttx/serial/serial.h: + Implement high level DMA infrastructure for serial devices. From + Max Neklyudov (2015-11-12). + * arch/arm/src/samv7 and arch/arm/include/samv7: Add support for the + SAME70 family of chips (2015-11-14). + * configs/stm32f429i-disco: configs/stm32f429i-disco/src/stm32_nsh.c + file calculated partition boundries based on page block sizes but + mtd_partition() is expecting calculations based on erase block size. + From Alan Carvalho de Assis (2015-11-16). + * Move rivers/wireless/cc3000/security.c to crypto/aes.c; move + include/nuttx/wireless/cc3000/security.h to include/nuttx/crypto/aes.h + (2015-11-16). + * drivers/mtd/at24xx.c: Add support for multiple AT24xx EEPROM parts, + each with unique I2C addresses, but otherwise identical (2015-11-17). + * drivers/timers/ds3231.c: Add support for the DS3231 I2C RTC. Untested + on the initial commit (2015-11-17). + * arch/arm/src/stm32/stm32_tim_lowerhalf.c: Add a compatible lower-half + timer driver for use with drivers/timers/timer.c. From Wail Khemir + (2015-11-17). + * drivers/sensors/ms58xx.c: Fix some issues with initialization and with + CRC calculation. From Karim Keddam (2015-11-17). + * drivers/mtd/w25.c: Fix W25 FLASH driver page read/write logic. From + Ken Pettit (2015-11-18). + * drivers/mtd/smart.c: Fix a Smart wear-leveling bug. From Ken Pettit + (2015-11-18). + * arch/sim/src/up_spiflash.c: Add support for W25 FLASH simulation. + From Ken Pettit (2015-11-18). + * configs/boardctl.h, Kconfig, include/sys/boardctl.h, and nuttx/board.h: + Add a command to the boardctl() interface to obtain a board unique ID + (2015-11-18). + * drivers/timers/ds3231.c: Driver extended to include support for the + DS1307 RTC (2015-11-18). + * configs/same70-xplained: Add basic NSH configuration for the SAME70 + Xplained board. Initial commit is just the SAMV71-XULT files with + names changed appropriately (2015-11-18). + * drivers/mtd/smart.c: Fixed SmartFS wear level error that occurs when + the logical sector size is too small to save all wear level status + bytes in a single sector. Logical sectors 1 and 2 were simply not + being allocated and then the read_sector and write_sector routines + were failing. From Ken Pettit (2015-11-18). + * drivers/timers/ds3231.c: Untested support for DS1302 and DS3232. + Also definitions for the DS3234, but that is an unsupported SPI RTC + (2015-11-19). + * drivers/mtd/w25.c: Add support for byte write mode. From Ken Pettit + (2015-11-20). + * drivers/timers/pcf85263.c and include/nuttx/times/pcf85263.h: Add + a driver for the NXP PCF85263 I2C RTC. Untested on initial commit + (2015-11-20). + * fs/driver/fs_blockproxy.c: Add logic to create a temporary char driver + using drivers/bch to mediate character oriented accessed to a block + driver (2015-11-21). + * fs/vfs/open.c: If the use attempts to open a block driver, use + block_proxy() to insert a character driver conversion layer in front + of the block driver (2015-11-21). + * libc/stdio/lib_freopen.c and include/stdio.h: Add support for + freopen() (2015-11-22). + * include/sys/types.h and include/nuttx/mm.h: When building on a 64-bit + machine, the size of size_t should be 64-bits. In general, I believe + that sizeof(size_t) should be the same as sizeof(uinptr_t). mmsize_t + should always be 32-bits in any event. The last change to stddef has + been backed out. With these changes, the simulator builds without + * fs/hostfs and arch/sim/src: Add a special file system for use with + simulator that supports access to the host file system from the + simulation. From Ken Pettit (2015-11-25). + * libc/time/lib_strftime.c: Add day-of-week support. (2015-11-25). + * drivers/lcd/ili9432.c: Fixed errors in orientation. Portrait, + RPortrait, and RLandscript should work correly now. They were + displayed mirrored. From Marco Krahl (2015-11-25). + * drivers/mtd/mtd/mtd_procfs/c and include/nuttx/mtd/mtd.h: Add an + interface to un-register an MTD procfs entry. From Ken Pettit + (2015-11-25). + * drivers/mtd/filemtd.c: A new MTD conversion layer that will + convert a regular file (or driver file) to an MTD device. This is + useful for testing on the simulation using the hostfs. From Ken + Pettit (2015-11-25). + * drivers/loop: Add a loop character device. losetup() and + loteardown() should not be called directory from applications. + Rather, these functions are now available as IOCTL commands to the + loop driver (2015-11-25). + * include/nuttx/net/netdev.h and several Ethernet drivers in arch/: + Most network drivers do not support statistics. Those that do only + support them when DEBUG is enabled. Each driver collects an + architecture specific set of statistics and there is no mechanism in + place to view those statistics. Thus, the driver feature was mostly + useless. This change standardizes the driver statistics and puts the + definition in the common network device structure defined in netdev.h + where they can be accessed by network applications. All Ethernet + drivers that collect statistics have been adapted to use these common + statistics (2015-11-26). + * net/net_procfs.c: Add basic support for networking entries in the + procfs (2015-11-27). + * mtd/filemtd.c and smart.c: Add support for a /dev/smart loop device. + From Ken Pettit (2015-11-28). + * sched/pthread/: CRITICAL BUGFIX: Logic was wiping out the indication + that of the type of a pthread. Hence, it could be confused as a + task. Found because this was causing a crash when /proc/nnn/cmdline + was printed (2015-11-29). + * configs/same70-xplained/nsh: The NSH configuration now seems fully + functional: serial console, LEDs, buttons, SDRAM, and HSMCI SD card + (2015-11-30). + * configs/same70-xplained/netnsh: Added and verified a network-enabled + NSH configuration for the SAME70-Xplained board (2015-11-20). + * net/: Remove CONFIG_NET_PINGADDRCONF. This was a uIP way of assigning + IP addresses, but is not standard and not a appropriate feature in + general (2015-12-01). + * fs/procfs: The procfs file system can now be configured so that it + supports a runtime registration of procfs entries with + CONFIG_FS_PROCFS_REGISTER=y (2015-12-01). + * arch/arm/src/stm32/stm32_ccm_procfs.c: Is no longer a part of the + 'base' procfs entries and can now only be supported via run time + registration with CONFIG_FS_PROCFS_REGISTER=y (2015-12-01). + * arch/arm/src/samv7/sam_tc.c: Port the SAMA5 timer/counter driver + to the SAMV7 (2015-12-02). + * arm/arm/src/samv7/sam_tickless.c: Port the SAMA5/SAM4CM tickless + logic to the SAMV7 (2015-12-02). + * fs/semaphore: Named semaphores: Back out "fix" of 2015-10-22. It was + correct before. The change of 2015-10-22 probably broke named + semaphores (2015-12-02). + * arch/arm/src/samv7: Bring programmable clock logic from SAMA5 into + SAMV7 (2015-12-03). + * arch/arm/src/samv7: Add PCK6 as an optional source for the timer/ + counter clock (2015-12-04). + * configs/samv7-xult/: If Tickless mode is selected then enable PCK6 + as a timer/counter clock source (2015-12-04). + +7.14 2016-01-28 Gregory Nutt + + * arch/arm/src/samv7: Port the TRNG driver from the SAMA5D3/4 to the + SAMV7 (2015-12-06). + * arch/arm/src/samv7: Port the WDT driver from the SAMA5D3/4 to the + SAMV7 (2015-12-06). + * arch/arm/src/samv7: Add an RSWDT driver (2015-12-06). + * drivers/net/telnet.c: Move the Telnet driver from apps/netutils/telnetd + to drivers/net. It is a driver a belongs in the OS. There are still + some interface related issues, however (2015-12-07). + * configs/: Update all configurations that use the Telnet daemon; those + configurations now need to separately enable the Telnet drvier + (2015-12-07). + * drivers/net/telnet.c: Now works like the loop device. A new interface + called telnet_initialize() registers a telnet session "factory" + device at /dev/telnet. Via ioctl, the factory device can create + instances of the telnet character devices at /dev/telnetN to support + Telnet sessions (2015-12-07). + * arch/arm/src/samv7: In USBHS device driver, fix check if zero length + packet is needed (2015-12-08). + * sched/pthread/: CRITICAL BUGFIX: Logic was wiping out the indication + that of the type of a pthread. Hence, it could be confused as a + task. Same problem as fixed on 2015-11-29, but in different location + (2015-12-09). + * sched/module: Add support for kernel modules. Initial commit is + just the ELF module support with name changes (2015-12-10). + * configs/samv71-xult/module: Add configuration for testing OS + modules (2015-12-12). + * sched/module: Add an implementation of rmmod() (2015-12-12). + * sched/module and fs/procfs: Add some basic module procfs support + (2015-12-12), + * arch/arm/src/armv7-r: Add basic architecture support for the ARMv7-R + processor family (2015-12-13). + * drivers/led: Adds a driver for the PCA9635PW I2C LED driver IC which + can be used to control the intensity of up to 16 LEDs. From Alexander + Entinger (2015-12-15). + * configs/launchxl-tms57004: Add basic board support for TI LaunchXL- + TMS57004. Not much to see there yet (2015-12-15). + * waitpid: CRITICAL BUGFIX. Add a reference count to prevent waitpid + from using stale memory released by the waited-for task group + (2015-12-22). + * sys/time.h: Add timeradd(), timersub(), timerclear(), timerisset(), + and timercmp() as macros. These are non-POSIX interfaces, but + included in most BSD deriviatives, including Linux. From Manuel Stühn + (2015-12-23). + * arch/arm/src/stm32: Add timer input capture driver. From Pierre-Noel + Bouteville (2015-12-24). + * arch/avr: Add support for the Atmega2560. From Dimitry Kloper + (2015-12-19). + * configs/arduino-mega2560: Add support for the Arduino-Mega2560. From + Dimitry Koper (2015-12-29). + * sched/signal, sched/mqueue, sched/timer, include/signal.h, + include/nuttx/signal, fs/aio, libc/aio, and probably other + directories: Add support for the SIGEV_THREAD notification method in + struct sigevent. This initial implementation will only work in the + FLAT build. See the top-level TODO file for additional details + (2015-12-30). + * include/nuttx/compiler.h, include/nuttx/streams.h include/stdio.h + include/syslog.h libc/stdio/, and libc/syslog: introduce support for + Atmel toolchain in-flash strings. Atmel toolchain AVR compiler + provides a transparent in-flash object support using __flash and + __memx symbols. The former indicates to compiler that this is a flash- + based object. The later used with pointer indicates that the referenced + object may reside either in flash or in RAM. The compiler automatically + makes 32-bit pointer with flag indicating whether referenced object is + in flash or RAM and generates code to access either in run-time. Thus, + any function that accepts __memx object can transparently work with RAM + and flash objects. + For platforms with a Harvard architecture and a very small RAM like AVR + this allows to move all constant strings used in trace messages to flash + in the instruction address space, releasing resources for other things. + This change introduces IOBJ and IPTR type qualifiers. The 'I' indicates + that the object may lie in instruction space on a Harvard architecture + machine. For platforms that do not have __flash and __memx or similar + symbols IOBJ and IPTR are empty, making the types equivalent to, for + example, 'const char' and 'const char*'. For Atmel compiler these will + become 'const __flash char' and 'const __memx char*'. All printf() + functions and syslog() functions are changed so that the qualifier is + used with the format parameter. From Dimitry Kloper (2016-01-05). + * drivers/net/tun.c: Fix a compile time error in the TUN driver. From + Vladimir Komendantskiy (2016-01-05). + * Kconfig and include/debug.h: Add configuration to support an + architecture-specific debug.h header file. From Dimitri Kloper + (2016-01-09). + * arch/avr/include/debug.h: Add an AVR-specific header file used when + the AVR MEMX pointer is used. From Dimitri Kloper (2016-01-09). + * tools/cnvwindeps.c: Add a tool that will convert paths in + dependencies generated by a Windows compiler so that they can be + used with the Cygwin make (2016-01-09). + * tools/mkwindeps.sh: A script that coordinates use of cnvwindeps.exe + (2016-01-09). + * tools/mkdeps.c: Deleted mkdeps.sh and mkdeps.bat. The mkdeps + executable generated from mkdeps.c is now that the only supported + way to make dependencies (2016-01-09). + * tools/mkdeps.c: Extended/fixed support for --winpath option. + Dependencies now work under Cygwin with a native Windows toolchain + (2016-01-10). + * libc/netdb: Add support for the use of a DNS resolver file like + /etc/resolv.conf (2016-01-14). + * drivers/sensors/mcp9844.c and include/nuttx/sensors/mcp9844.h: Driver + for the MCP9844 I2C digital temperature sensor with a selectable + resolution. From Alexander Entinger (2016-01-15). + * arch/arm/src/lpc43xx: Numerous LPC43 improvements to SPIFI and ADC + from Lok Tep (2016-01-15). + * configs/lpc4337-ws: Support for the WaveShare LPC4337-WS board. From + Lok Tep (2016-01-15). + * drivers/wireless/pn532.c: Add driver for the NXP pn532 NFC-chip. From + Janne Rosberg and others at Offcode Ltd (2016-01-17). + * drivers/sensors/lsm9ds1.c: Add driver for the STMicro LSM9DS1 chip. + The LSM9DS1 is a system-in-package featuring a 3D digital linear + acceleration sensor, a 3D digital angular rate sensor, and a 3D + digital magnetic sensor. From Paul Alexander Patience (2016-01-17). + * configs/olimex-stm32-h407: Added a port to the Olimex STM32 H407 + board. This board features the STMicro STM32F407ZGT6 (144 pins). + Contributed by Neil Hancock. (2016-01-18) + * arch/arm/src/stm32/stm32_otgfs/hs/host.c: Fix some backward + arguments to stm32_putreg(). Note by Hang Xu (2016-01-18). + * include/nuttx/can.h and several CAN drivers: Add more extensive + error reporting capaibility to the CAN interface. From Frank + Benkert (2016-01-18). + * libc/misc/lib_tea.h and include/nuttx/crypto/tea.h: Add an + implementation of the Tiny Encryption Algorithm (2016-01-19). + * sim/include: Now supports a customizable startup script with a + read-only passwd file (2016-01-20). + * sim/nsh: Uses the custom start up script, includes hooks for + an MOTD message. (2016-01-20). + * include/clock.h and lots of other files: If the 64-bit timer is + selected, then use it whenever clock_systimer() is called rather + then chopping the 64-bit timer down to 32-bits. Add a new type, + systime_t to represent the 32- or 64-bit system timer (2016-01-21). + * sched/clock/clock_systimespec.c: Fix an error in a time + conversion (2016-01-21). + * include/nuttx/clock.h: Get rid of clock_systimer32() and + clock_systime64(). There is now only clock_systimer() (2016-01-21). + * arch/arm/src/kinetis: Numerous updates to the Kinetis ENET driver. + From Andrew Webster (2016-01-21). + * arch/arm/src/kinetis: Add support for the MK60N512VLL100 Kinetis part. + From Andrew Webster (2016-01-21). + * net/tcp and net/iob: Numerous fixes, mostly relate to TCP and IOB + buffering and race conditions. These were necessary for for the + NuttX networking later to be stable in some stress testing. From + Andrew Webster (2016-01-22). + * include/spi/spi.h: Add an optional hwfeatures() method to the + SPI interface (2016-01-23). + * drivers/spi/Kconfig and many other files: Remove CONFIG_SPI_OWNBUS: + Now its not just a good idea, its the law (2015-01-23). + * include/nuttx/math32.h and libc/misc: Add some utilities to support + 64-bit arithmetic operations for platforms that do not support long + long types. Not yet used anywhere (2015-01-25). + * arch/arm/src/samv7/chip: Add an AFEC header file (2016-01-25). + * net/iob: iob_alloc_qentry() has the same issues as did iob_alloc() + fixed on 2016-01-23. (2016-01-26). + * drivers/usbhost/hid_parser.c: Wrong size used in memcpy(). From Hang + Xu (2016-01-25). + * drivers/ioexpander/pca9555.c: Fixed a bug in the function pca9555_setbit + which occurs if someone tries to set one of the pins 8-15. The problem is + that after the check if the pin is greater than 7 the variable addr is + incremented and used in the Call I2C_WRITEREAD. But later in the call to + the I2C_WRITE buf[0] is used as address but this address is not incremented + as it should be. Note address does mean the address to the register in the + ioexpander and not the I2C address. From Stefan Kolb (2016-01-26). + * drivers/ioexpander/pca9555: Convert to use I2C_TRANSFER vs. I2C_WRITEREAD, + the former is thread safe while the latter is deprecated (2016-01-26). + * drivers/i2c/i2c_writeread.c: Create a wrapper that uses I2C_TRANSFER + to implement I2C_WRITEREAD functionality (2016-01-26). + * I2C: Eliminate the I2C_WRITEREAD method (2016-01-26). + * drivers/i2c/i2c_read.c and i2c_write.c: Convert to use I2C_TRANSFER vs. + I2C_READ and I2C_WRITE which are not thread safe (2016-01-26). + * SPI: Rename the STM32 up_spiinitialize() to stm32_spibus_initialize() + (2016-01-26). + * SPI: Rename the SAM up_spiinitialize() to stm32_spibus_initialize() + (2016-01-26). + * SPI: Rename the Tiva up_spiinitialize() to tiva_spibus_intialize() + (2016-01-26). + * SPI: Rename the PIC32MX/MZ up_spiinitialize() to pic32mx/mz_spibus_intialize() + (2016-01-26). + * SPI: Rename EFM32's efm32_spi_initialize to efm32_spibus_initialize() + for compatibility with these other changes (2016-01-26). + * SPI: Rename the KL up_spiinitialize() to kl_spibus_intialize() (2016-01-26). + * SPI: Rename the Kinetis up_spiinitialize() to kinetis_spibus_intialize() + (2016-01-26). + * SPI: Rename the LPC31xx up_spiinitialize() to lpc31_spibus_intialize(), + Rename the LPC17xx lpc17_spiinitialize() to lpc31_spibus_intialize(), + Rename the LPC43xx up_spiinitialize() to lpc43_spibus_intialize() + (2016-01-26). + * SPI: Rename the AVR up_spiinitialize() to avr_spibus_intialize(), + Rename the LPC2148 up_spiinitialize() to lpc214x_spibus_intialize(), + Rename the Calypso up_spiinitialize() to calypso_spibus_intialize(), + Rename the ez80 up_spiinitialize() to ez80_spibus_intialize(), + Rename the STR71xx up_spiinitialize() to str71_spibus_intialize(), + Rename the i.MX1 up_spiinitialize() to imx_spibus_intialize(), + Rename the LPC2378 up_spiinitialize() to lpc23_spibus_intialize(), + Rename the M9S12 up_spiinitialize() to hcs12_spibus_intialize(), + Rename the x86 up_spiinitialize() to i486_spibus_intialize(), + Rename the z16f up_spiinitialize() to z16_spibus_intialize(). + up_spiinitialize() has been completely eliminated. (2016-01-27). + * fs/vfs/fs_poll.c: Fix handling of sem_tickwait() return value + sem_tickwait() does not return an -1+errno, it returns a negated + errno value. Noted by Freddie Chopin. + +7.15 2016-xx-xx Gregory Nutt + + * drivers/analog/adc1242.c and include/nuttx/analog/adc1242.h: Driver + for the 24-Bit Differential Input ADC ADS1242 that communicates via + SPI with a MCU. Reading the ADC conversion result as well as configuring + the ADC, setting the input channel, etc. is implemented via ioctl calls. + However, it does not yet implement the standard ADC interface. From + * configs/board/src/xyz_cxxinitialize.c: Move CXX initialization logic + out of the RTOS and into the application space, specifically to + apps/platform/board, where it belongs (2016-01-29). + * drivers/modem/u-blox.c and include/nuttx/drivers/u-blox.h: Add an upper + half driver for the U-Blox Modem. From Vladimir Komendantskiy + (2018-01-30). + * arch/arm/src/lpc17xx: Backport lpc43xx I2C driver, replacing the + lpc17xx I2C driver. This gives us the I2C_TRANSFER method (2016-01-30). + * arch/arm/src/lpc11xx: Backport the lpc17xx I2C driver, replacing the + lpc11xx I2C driver. This gives us the I2C_TRANSFER method (2019-01-30). + * arch/arm/src/lpc2378: Backo the Lpc17xx I2C driver, replacing the + lpc2378 I2C driver. This gives us the I2C_TRANSFER method (2019-01-30). + * confgs/u-blox-c027: Support for the u-blox GSM and GPS module evaluation + board with NXP LPCExpresso LPC1768. The GSM module is one of LISA-C200, + LISA-U200 or SARA-G350. The GPS module is one of MAX-M7 or MAX-M8. From + Vladimir Komendantskiy (2016-01-31). + * drivers/, arch/, include/, numerous files: May restructuring of the I2C + interface necessary to eliminate some thread-safety issues inherent in + the legacy I2C interface design. This effects the interface definition, + all I2C clients, and all low-level I2C drivers. I have used caution, + but I still expect a change of this magnitude to introduce some errors. + Any bug reports of bug fixes will be much appreciated (2016-02-01). + * drivers/i2c/i2c_driver.c: Add an I2C character drivers to support + raw I2C data transfers for test applications (2016-02-02). + * I2C_RESET: Eliminate up_i2creset(). It should not be a global function; + Now it is an I2C interface method (2016-02-02). + * I2C: Rename up_i2cinitialize and up_i2cuninitilize to follow the correct + naming convention. These are not common interfaces used by the OS; + these are MCU-specific interfaces used only be MCU-specific code. The + the correct naming is xyz_i2cbus_initialize and xzy_i2cbus_uninitialize + where xzy is the MCU mnemonic (2016-02-02). + * Networking drivers that support CONFIG_NET_NOINTS: Fix a race condition + that can cause the TX poll timer to stop running. From Manuel Stuhn + (2016-02-03). + * All Network drivers: Remove the hsec parameter from devif_timer(). + We can get better timing accuracy without it (2016-02-03). + * drivers/ioexpander/pca555.c: Add logic to make the PCA555 driver + thread safe (2016-02-03). + * sched/init/os_start.c and include/nuttx/init.h: Add a state variable + that provides the current level of OS initialization. This is needed by + some logic that may attempt to run early in the start-up sequence but + cannot run if a sufficient level of initialization has not yet occurred + (2016-02-05). + * libc/syslog/lib_syslog.c: If syslog timestamping is enabled, don't try to + get the time if the timer hardware has not yet been initialized + (2016-02-05). + * fs/procfs/fs_procfskmm.c: Add /proc/kmm entry that shows that state of + the kernel heap. Only useful in PROTECTED and KERNEL build modes where + there is a kernel heap (2016-02-06). + * sched/ and arch/: Replace explicit access to the OS internal data structure + g_readytorun() with the wrapper this_task() which hides the implementation + and will permit such things as more scalable representations of task queues + and SMP (2016-02-06). + * include/nuttx/net/arp.h, include/nuttx/net/ioctl.h, net/netdev/netdev_ioctl.c, + and ARP-related files: Add support for IOCTL commands to manage the + ARP table (2016-02-08). + * ARMv7-A, ARMv7-R, and ARMv7-A: Add test-and-set logic and definitions + needed to supports spinlocks (2016-02-09). + * include/nuttx/spinlock.h: Add basic definitions for spinlocks. Not yet + used by NuttX (2016-02-09). + * include/nuttx/arch.h, sched/sched/sched.h: Add some basic definitions + that may be needed for SMP support (2016-02-10). + * sched/init/os_start.c, sched/init/os_smpstart.c, and include/nuttx/arch.h: + Add some tentative SMP start-up logic (2016-02-10). + * arch/arm/sim/up_head.c and up_simsmp.c: Add multi-CPU support to the + simulation to support SMP investigation.. Currently crashes when CONFIG_SMP + is enabled as expected (2016-02-10). + * sched/sched.h and other files: Replace the bool 'prioritized' in the task + list table with a uint8_t bit set so that additional attributes of a task + list can be provided without adding more booleans (2016-10-11). + * Everywhere: Replace irqsave() with enter_critical_section(); replace + irqrestore() with leave_critical_section(). This is part of the onging + development of SMP support (2016-02-13). + * Conform to naming convention: Rename irqsave() to up_irq_save(); rename + irqrestore() to up_irq_restore(). These should no longer be used. If + your code still uses them, please switch to enter_critical_section() + and leave_critical_section() (2016-02-14). + * Also rename irqdisable() and irqenable() to up_irq_disable() and + up_irq_enable() (2016-02-14). + * sched/signal and include/nuttx/sched.h: Move the list of signal + actions from the TCB to the group structure. Signal handlers are not + per thread but, rather, per task group. I know, I preferred it the + other way too, but this is more compliant with POSIX (2016-02-18). + * fs/ procfs/fs_procfsproc.c: Add support for showing CPU if SMP is + is enabled (2016-02-19). + * include/pthread.h, sched.h, sys/types.h and other files: Rename + cpuset_t to cpu_set_t which is the type used in some non-standard + Linux/GNU interfaces. Move definitions of cpu_set_t to include/sys/types.h. + Add prototypes for sched_setaffinity(), sched_getaffinity(), + pthread_attr_setaffinity_np(), pthread_attr_getaffinity_np(), + pthread_setaffinity_np(), and pthread_getaffinity_np(). No implementation + is yet in place (2016-02-19). + * sched/sched_cpuselect.c, include/nuttx/sched.h, and other files. Add + a CPU affinity set to the TCB if SMP is enabled and use this CPU set as + a mask for determining which CPUs the thread may run on (2016-02-19). + * libc/pthread, sched/pthread/pthread_start.c, and include/pthread.h: + Add an affinity field to the attrributes to permit controlling + which CPUs a pthread may run on. Implements pthread_att_setaffinity_np() + and pthread_attr_getaffinity_np() (2016-02-19). + * sched/pthread: Add pthread_setaffinity() and pthread_getaffinity() + (2016-02-19). + * sched/sched: Add sched_setaffinity() and sched_getaffinity() (2016-02-19). + * drivers/leds/rgbled.c: Add a driver to manage a RGB LED via PWM. From + Alan Carvalho de Assis (2016-02-22). + * arch/arm/src/stm32fcdiscovery: Add PWM support for the onboard RGB LED + From Alan Carvalho de Assis (2016-02-22). + * arch/arm/src/samv7: HSMCI driver can now be configured to handle unaligned + data buffers (2016-02-22). + * fs/fat: Add an option to force all transfers to be performed indirectly + using the FAT file system's internal sector buffers (2016-02-22). + * drivers/wireless/ieee802154: New directory. Nothing there yet (2016-02-25). + * wireless/: New top level directory. Nothing there yet (2015-02-26). + * wireless/ieee802154: Add an new directory to the build. Nothing there + yet (2016-02-26). + * include/nuttx/wireless/ieee802154: Add directory (and dummy header file) + (2016-02-16). + * arch/arm/include and src: Rename the imx directories to imx1 to make room + in the namespace for other members of the i.MX family (2016-02-27). + * arch/arm/include/imx6 and src/imx6: Evolving support for the NXP/Freescale + i.MX6Q (2016-02-28). + * configs/sabre-6quad: Placeholder that will eventually become board support + for the NXP/Freescale Sabre 6Quad board (2016-02-28). + * arch/arm/src/stm32: Support for STM32F46xx from Paul Alexander Patience + * sched/semaphore/sem_reset.c and include/nuttx/semaphore.h: Add an internal, + non-standard interface to reset a semaphore count. This is sometimes + needed by drivers in order to recover from error conditions (2016-03-05) + * AT24xx driver: Correct missing address calculation logic. From Frank + Benkert (2016-03-08). + * arch/ renaming: current_regs renamed to g_current_regs in all + architectures. For ARM which is slowly developing SMP capability, + g_current_regs is now an array of dimension 1 in most case but of higher + dimension of the architecuture supports multiple CPUs (2016-03-09). + * MTD: Increase block size in mtd_geometry_s to 32-bits (2016-03-09). + * include/nuttx/clock.h: Missing parenteses in MSEC2TICK macro can + cause wrong calculations. From Stefan Kolb (2016-03-09). + * Build system: Added a 'make olddefconfig' target that will refresh + a .config file without interaction. tools/refesh.sh no has a --silent + option so that it can be used in batch modes without human input + (2016-03-09). + * tools/testbuild.sh: .config files were not being updated because (a) + kconfig-conf was being called in the wrong directory and (b) apps/Kconfig + had not yet been created. Now uses 'make olddefconfig' (2016-03-09). + * arch/arm/src/stm32l4 and include/stm32l4: Add support for the STM32L4 + family. From Sebastien Lorquet (2016-03-10). + * configs/nucleo-l476: Add support for the Nucleo-L476 board. From + Sebastien Lorquet (2016-03-10). + * sched/tls and include/nuttx/tls.h: Basic definitions needed to support + thread local storage (TLS). Not used anywhere yet (and may not be used + in the near future either) (2016-03-10). + * sched/sched_note.c and include/nuttx/sched_note.c: Add a configuration + option to buffer RTOS instrumentation data in an in-memory buffer + (2016-03-17). + * drivers/syslog/note_driver.c: Add a character driver that will allow + an appliation to read buffered scheduler instrumentation data (2016-03-17). + diff --git a/Directories.mk b/Directories.mk index 83cbb5f1ab8ffa26a67e94ba2c8e75d3bfa5ee15..6eeedc79e8a484095ca15f31ccaf20cb9212bad9 100644 --- a/Directories.mk +++ b/Directories.mk @@ -1,7 +1,7 @@ ############################################################################ # Directories.mk # -# Copyright (C) 2007-2012, 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2012, 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -124,6 +124,12 @@ else OTHERDIRS += audio endif +ifeq ($(CONFIG_DRIVERS_WIRELESS),y) +NONFSDIRS += wireless +else +OTHERDIRS += wireless +endif + # CLEANDIRS are the directories that will clean in. These are # all directories that we know about. # KERNDEPDIRS are the directories in which we will build target dependencies. diff --git a/Documentation b/Documentation index 429e6427da4453da9342f52f57cf87bddafdb6e5..35343cbe6660bb07d9fee4c2e5af0dd450313c14 160000 --- a/Documentation +++ b/Documentation @@ -1 +1 @@ -Subproject commit 429e6427da4453da9342f52f57cf87bddafdb6e5 +Subproject commit 35343cbe6660bb07d9fee4c2e5af0dd450313c14 diff --git a/FlatLibs.mk b/FlatLibs.mk index ebe69cbb6184839d816237fa72c05324fe73108a..13dcc6c3400f0b24f52fe5bfd140265af0a8c6f3 100644 --- a/FlatLibs.mk +++ b/FlatLibs.mk @@ -1,7 +1,7 @@ ############################################################################ # FlatLibs.mk # -# Copyright (C) 2007-2012, 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2012, 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -109,6 +109,12 @@ ifeq ($(CONFIG_AUDIO),y) NUTTXLIBS += lib$(DELIM)libaudio$(LIBEXT) endif +# Add libraries for the Wireless sub-system + +ifeq ($(CONFIG_WIRELESS),y) +NUTTXLIBS += lib$(DELIM)libwireless$(LIBEXT) +endif + # Export all libraries EXPORTLIBS = $(NUTTXLIBS) diff --git a/Kconfig b/Kconfig index e57918a0ff4d33b37349529435dd3a2d3b45cdcb..4584b62546719d970737c7616b0e7db45b926776 100644 --- a/Kconfig +++ b/Kconfig @@ -165,7 +165,7 @@ config BUILD_PROTECTED config BUILD_KERNEL bool "NuttX kernel build" - depends on ARCH_USE_MMU && ARCH_ADDRENV && EXPERIMENTAL + depends on ARCH_USE_MMU && ARCH_ADDRENV select LIB_SYSCALL ---help--- Builds NuttX as a separately compiled kernel. No applications are @@ -376,6 +376,12 @@ config ARCH_STDARG_H ARCH_STDARG_H=y and providing. If ARCH_STDARG_H, is not defined, then the stdarg.h header file will stay out-of-the-way in include/nuttx/. +config ARCH_DEBUG_H + bool "debug.h" + default n + ---help--- + The debug.h contains architecture dependent debugging primitives + endmenu # Customize Header Files menu "Debug Options" @@ -412,6 +418,7 @@ comment "Subsystem Debug Options" config DEBUG_AUDIO bool "Audio Device Debug Output" default n + depends on AUDIO ---help--- Enable low level debug SYSLOG output from the audio subsystem and device drivers. (disabled by default). Support for this debug option @@ -420,6 +427,7 @@ config DEBUG_AUDIO config DEBUG_BINFMT bool "Binary Loader Debug Output" default n + depends on !BINFMT_DISABLE ---help--- Enable binary loader debug SYSLOG output (disabled by default) @@ -482,6 +490,15 @@ config DEBUG_SYSCALL Enable very low level output related to system calls. This gives you basically a poor man's version of strace. +config DEBUG_WIRELESS + bool "Wireless Device Debug Output" + default n + depends on WIRELESS + ---help--- + Enable low level debug SYSLOG output from the wireless subsystem and + device drivers. (disabled by default). Support for this debug option + is architecture-specific and may not be available for some MCUs. + comment "OS Function Debug Options" config DEBUG_DMA @@ -548,6 +565,16 @@ config DEBUG_INPUT this debug option is board-specific and may not be available for some boards. +config DEBUG_DISCRETE + bool "Discrete I/O Debug Output" + default n + depends on DISCRETE_IO + ---help--- + Enable low level debug SYSLOG output from the discrete I/O device + drivers such as LEDs and I/O expanders (disabled by default). + Support for this debug option is board-specific and may not be + available for some boards. + config DEBUG_ANALOG bool "Analog Device Debug Output" default n @@ -766,6 +793,10 @@ menu "Audio Support" source audio/Kconfig endmenu +menu "Wireless Support" +source wireless/Kconfig +endmenu + menu "Binary Loader" source binfmt/Kconfig endmenu diff --git a/KernelLibs.mk b/KernelLibs.mk index 02f9f8aa9011aa32648cbc6e5feba7abbd2279d6..a7888d714dceec8e15641311fc2fe46a6886d748 100644 --- a/KernelLibs.mk +++ b/KernelLibs.mk @@ -1,7 +1,7 @@ ############################################################################ # KernalLibs.mk # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -104,6 +104,12 @@ ifeq ($(CONFIG_AUDIO),y) NUTTXLIBS += lib$(DELIM)libaudio$(LIBEXT) endif +# Add libraries for the Wireless sub-system + +ifeq ($(CONFIG_WIRELESS),y) +NUTTXLIBS += lib$(DELIM)libwireless$(LIBEXT) +endif + # Export only the user libraries EXPORTLIBS = $(USERLIBS) diff --git a/LibTargets.mk b/LibTargets.mk index 757a9cb1b7cddbdedeb82919e38f86971ebaf667..873958f00a3775f917b70ecee2382ff9f5bccc73 100755 --- a/LibTargets.mk +++ b/LibTargets.mk @@ -64,7 +64,6 @@ $(ARCH_SRC)$(DELIM)libkarch$(LIBEXT): context lib$(DELIM)libkarch$(LIBEXT): $(ARCH_SRC)$(DELIM)libkarch$(LIBEXT) $(Q) install $(ARCH_SRC)$(DELIM)libkarch$(LIBEXT) lib$(DELIM)libkarch$(LIBEXT) - sched$(DELIM)libsched$(LIBEXT): context $(Q) $(MAKE) -C sched TOPDIR="$(TOPDIR)" libsched$(LIBEXT) KERNEL=y EXTRADEFINES=$(KDEFINE) @@ -119,6 +118,18 @@ audio$(DELIM)libaudio$(LIBEXT): context lib$(DELIM)libaudio$(LIBEXT): audio$(DELIM)libaudio$(LIBEXT) $(Q) install audio$(DELIM)libaudio$(LIBEXT) lib$(DELIM)libaudio$(LIBEXT) +wireless$(DELIM)libwireless$(LIBEXT): context + $(Q) $(MAKE) -C wireless TOPDIR="$(TOPDIR)" libwireless$(LIBEXT) KERNEL=y EXTRADEFINES=$(KDEFINE) + +lib$(DELIM)libwireless$(LIBEXT): wireless$(DELIM)libwireless$(LIBEXT) + $(Q) install wireless$(DELIM)libwireless$(LIBEXT) lib$(DELIM)libwireless$(LIBEXT) + +$(ARCH_SRC)$(DELIM)libarch$(LIBEXT): context + $(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT) KERNEL=y EXTRADEFINES=$(KDEFINE) + +lib$(DELIM)libarch$(LIBEXT): $(ARCH_SRC)$(DELIM)libarch$(LIBEXT) + $(Q) install $(ARCH_SRC)$(DELIM)libarch$(LIBEXT) lib$(DELIM)libarch$(LIBEXT) + # Special case syscall$(DELIM)libstubs$(LIBEXT): context @@ -190,9 +201,3 @@ mm$(DELIM)libmm$(LIBEXT): context lib$(DELIM)libmm$(LIBEXT): mm$(DELIM)libmm$(LIBEXT) $(Q) install mm$(DELIM)libmm$(LIBEXT) lib$(DELIM)libmm$(LIBEXT) - -$(ARCH_SRC)$(DELIM)libarch$(LIBEXT): context - $(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT) - -lib$(DELIM)libarch$(LIBEXT): $(ARCH_SRC)$(DELIM)libarch$(LIBEXT) - $(Q) install $(ARCH_SRC)$(DELIM)libarch$(LIBEXT) lib$(DELIM)libarch$(LIBEXT) diff --git a/Makefile.unix b/Makefile.unix index 3e6442bb56e87782a6b6824cfa173ca228c1dfa2..96179c419bc79387d7bfe5fc41d126a98bc014d7 100644 --- a/Makefile.unix +++ b/Makefile.unix @@ -1,7 +1,7 @@ ############################################################################ # Makefile.unix # -# Copyright (C) 2007-2012, 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2012, 2014-2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -72,9 +72,13 @@ ARCH_SRC = $(ARCH_DIR)/src ARCH_INC = $(ARCH_DIR)/include ifeq ($(CONFIG_ARCH_BOARD_CUSTOM),y) - BOARD_DIR = $(CONFIG_ARCH_BOARD_CUSTOM_DIR) +ifeq ($(CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH),y) +BOARD_DIR = $(TOPDIR)$(DELIM)$(CONFIG_ARCH_BOARD_CUSTOM_DIR) else - BOARD_DIR = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD) +BOARD_DIR = $(CONFIG_ARCH_BOARD_CUSTOM_DIR) +endif +else +BOARD_DIR = $(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD) endif # CONFIG_APPS_DIR can be over-ridden from the command line or in the .config file. @@ -265,7 +269,10 @@ include/nuttx/config.h: $(TOPDIR)/.config tools/mkconfig$(HOSTEXEEXT) # Targets used to create dependencies tools/mkdeps$(HOSTEXEEXT): - $(Q) $(MAKE) -C tools -f Makefile.host TOPDIR="$(TOPDIR)" mkdeps$(HOSTEXEEXT) + $(Q) $(MAKE) -C tools -f Makefile.host TOPDIR="$(TOPDIR)" mkdeps$(HOSTEXEEXT) + +tools/cnvwindeps$(HOSTEXEEXT): + $(Q) $(MAKE) -C tools -f Makefile.host TOPDIR="$(TOPDIR)" cnvwindeps$(HOSTEXEEXT) # dirlinks, and helpers # @@ -456,12 +463,12 @@ download: $(BIN) # pass1dep: Create pass1 build dependencies # pass2dep: Create pass2 build dependencies -pass1dep: context tools/mkdeps$(HOSTEXEEXT) +pass1dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT) $(Q) for dir in $(USERDEPDIRS) ; do \ $(MAKE) -C $$dir TOPDIR="$(TOPDIR)" depend ; \ done -pass2dep: context tools/mkdeps$(HOSTEXEEXT) +pass2dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT) $(Q) for dir in $(KERNDEPDIRS) ; do \ $(MAKE) -C $$dir TOPDIR="$(TOPDIR)" EXTRADEFINES=$(KDEFINE) depend; \ done @@ -473,19 +480,22 @@ pass2dep: context tools/mkdeps$(HOSTEXEEXT) # location: http://ymorin.is-a-geek.org/projects/kconfig-frontends. See # README.txt file in the NuttX tools GIT repository for additional information. -config: +config: apps_preconfig $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf Kconfig -oldconfig: +oldconfig: apps_preconfig $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --oldconfig Kconfig -menuconfig: +olddefconfig: apps_preconfig + $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --olddefconfig Kconfig + +menuconfig: apps_preconfig $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-mconf Kconfig -qconfig: +qconfig: apps_preconfig $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-qconf Kconfig -gconfig: +gconfig: apps_preconfig $(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-gconf Kconfig # export @@ -556,11 +566,17 @@ endif # as a convenience, the following targets are included to support housekeeping # functions in the user application directory from the NuttX build directory. # +# apps_preconfig: Prepare applications to be configured # apps_clean: Perform the clean operation only in the user application # directory # apps_distclean: Perform the distclean operation only in the user application # directory. +apps_preconfig: +ifneq ($(APPDIR),) + $(Q) $(MAKE) -C "$(TOPDIR)/$(APPDIR)" TOPDIR="$(TOPDIR)" preconfig +endif + apps_clean: ifneq ($(APPDIR),) $(Q) $(MAKE) -C "$(TOPDIR)/$(APPDIR)" TOPDIR="$(TOPDIR)" clean diff --git a/Makefile.win b/Makefile.win index 1ff9ceefc1cdc8f4be23a9765d720d9ed3f392c0..5a71a42122b76d51fa96d2422549c6f45480c04a 100644 --- a/Makefile.win +++ b/Makefile.win @@ -1,7 +1,7 @@ ############################################################################ # Makefile.win # -# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -65,9 +65,13 @@ ARCH_SRC = $(ARCH_DIR)\src ARCH_INC = $(ARCH_DIR)\include ifeq ($(CONFIG_ARCH_BOARD_CUSTOM),y) - BOARD_DIR = $(CONFIG_ARCH_BOARD_CUSTOM_DIR) +ifeq ($(CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH),y) +BOARD_DIR = $(TOPDIR)$(DELIM)$(CONFIG_ARCH_BOARD_CUSTOM_DIR) else - BOARD_DIR = $(TOPDIR)${DELIM}configs$(DELIM)$(CONFIG_ARCH_BOARD) +BOARD_DIR = $(CONFIG_ARCH_BOARD_CUSTOM_DIR) +endif +else +BOARD_DIR = $(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD) endif # CONFIG_APPS_DIR can be over-ridden from the command line or in the .config file. @@ -476,13 +480,16 @@ pass2dep: context tools\mkdeps$(HOSTEXEEXT) # location: http://ymorin.is-a-geek.org/projects/kconfig-frontends. See # misc\tools\README.txt for additional information. -config: +config: apps_preconfig $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf Kconfig -oldconfig: +oldconfig: apps_preconfig $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --oldconfig Kconfig -menuconfig: configenv +olddefconfig: apps_preconfig + $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --olddefconfig Kconfig + +menuconfig: configenv apps_preconfig $(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-mconf Kconfig # export @@ -545,11 +552,17 @@ endif # as a convenience, the following targets are included to support housekeeping # functions in the user application directory from the NuttX build directory. # +# apps_preconfig: Prepare applications to be configured # apps_clean: Perform the clean operation only in the user application # directory # apps_distclean: Perform the distclean operation only in the user application # directory. +apps_preconfig: +ifneq ($(APPDIR),) + $(Q) $(MAKE) -C "$(APPDIR)" TOPDIR="$(TOPDIR)" preconfig +endif + apps_clean: ifneq ($(APPDIR),) $(Q) $(MAKE) -C "$(APPDIR)" TOPDIR="$(TOPDIR)" clean diff --git a/ProtectedLibs.mk b/ProtectedLibs.mk index 3abd390848590991f4b15a24efa786f118d9c2d4..70185eacf47162a4f850a36919d398786f3f97b2 100644 --- a/ProtectedLibs.mk +++ b/ProtectedLibs.mk @@ -1,7 +1,7 @@ ############################################################################ # ProtectedLibs.mk # -# Copyright (C) 2007-2012, 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2012, 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -114,6 +114,12 @@ ifeq ($(CONFIG_AUDIO),y) NUTTXLIBS += lib$(DELIM)libaudio$(LIBEXT) endif +# Add libraries for the Wireless sub-system + +ifeq ($(CONFIG_WIRELESS),y) +NUTTXLIBS += lib$(DELIM)libwireless$(LIBEXT) +endif + # Export only the user libraries EXPORTLIBS = $(USERLIBS) diff --git a/README.txt b/README.txt index 4f8b3643534ad4907e9d2d2bee34152ed077598f..90c264446e529b88bb0558e94331065660d380ef 100644 --- a/README.txt +++ b/README.txt @@ -79,6 +79,10 @@ Installing Cygwin the answer to that and so will continue to recommend installing EVERYTHING. + You should certainly be able to omit "Science", "Math", and + "Publishing". You can try omitting KDE, Gnome, GTK, and other + graphics packages if you don't plan to use them. + After installing Cygwin, you will get lots of links for installed tools and shells. I use the RXVT native shell. It is fast and reliable and does not require you to run the Cygwin X server (which is neither @@ -472,6 +476,16 @@ Refreshing Configurations be? Enter ? in response to the 'make oldconfig' prompt and it will show you the help text that goes with the option. + If you don't want to make any decisions are are willing to just accep the + recommended default value for each new configuration item, an even easier + way is: + + make oldefconfig + + The olddefconfig target will simply bring you configuration up to date with + the current Kconfig files, setting any new options to the default value. + No questions asked. + NuttX Configuration Tool ------------------------ @@ -1107,17 +1121,6 @@ Window Native Toolchain Issues is not a long as you might think because there is no dependency checking if you are using a native Windows toolchain. That bring us to #3: - 3. Dependencies are not made when using Windows versions of the GCC on a POSIX - platform (i.e., Cygwin). This is because the dependencies are generated - using Windows paths which do not work with the Cygwin make. - - MKDEP = $(TOPDIR)/tools/mknulldeps.sh - - If you are building natively on Windows, then no such conflict exists - and the best selection is: - - MKDEP = $(TOPDIR)/tools/mkdeps.exe - General Pre-built Toolchain Issues To continue with the list of "Window Native Toolchain Issues" we can add @@ -1251,6 +1254,8 @@ nuttx/ |- configs/ | |- amber/ | | `- README.txt + | |- arduino-mega2560/ + | | `- README.txt | |- arduino-due/ | | `- README.txt | |- avr32dev1/ @@ -1304,6 +1309,8 @@ nuttx/ | | `- README.txt | |- kwikstik-k40/ | | `- README.txt + | |- launchxl-tms57004/ + | | `- README.txt | |- lincoln60/ | | `- README.txt | |- lm3s6432-s2e/ @@ -1314,8 +1321,12 @@ nuttx/ | | `- README.txt | |- lpc4330-xplorer/ | | `- README.txt + | |- lpc4337-ws/ + | | `- README.txt | |- lpc4357-evb/ | | `- README.txt + | |- lpc4370-link2/ + | | `- README.txt | |- lpcxpresso-lpc1115/ | | `- README.txt | |- lpcxpresso-lpc1768/ @@ -1359,6 +1370,8 @@ nuttx/ | | `- README.txt | |- olimex-stm32-h405/ | | `- README.txt + | |- olimex-stm32-h407/ + | | `- README.txt | |- olimex-stm32-p107/ | | `- README.txt | |- olimex-stm32-p207/ @@ -1385,6 +1398,10 @@ nuttx/ | | `- README.txt | |- rgmp/ | | `- README.txt + | |- sabre-6quad/ + | | `- README.txt + | |- sama5d2-xult/ + | | `- README.txt | |- sama5d3x-ek/ | | `- README.txt | |- sama5d3-xplained/ @@ -1407,9 +1424,12 @@ nuttx/ | | `- README.txt | |- sam4s-xplained-pro/ | | `- README.txt - | |- samv7i-xult/ + | |- same70-xplained/ + | | `- README.txt + | |- samv71-xult/ | | `- README.txt | |- sim/ + | | |- include/README.txt | | `- README.txt | |- shenzhou/ | | `- README.txt @@ -1453,6 +1473,8 @@ nuttx/ | | `- README.txt | |- twr-k60n512/ | | `- README.txt + | |- u-blox-co27/ + | | `- README.txt | |- ubw32/ | | `- README.txt | |- us7032evb1/ @@ -1538,6 +1560,8 @@ apps/ | |- json/README.txt | |- pashello/README.txt | `- README.txt + |- gpsutils/ + | `- minmea/README.txt |- graphics/ | `- tiff/README.txt |- interpreters/ @@ -1573,6 +1597,8 @@ apps/ | | `- README.txt | |- nxplayer | | `- README.txt + | |- symtab/ + | | `- README.txt | |- usbmsc | | `- README.txt | |- zmodem diff --git a/ReleaseNotes b/ReleaseNotes index 711b03e677da3ac5be7b84486611382c6df1b5e5..376f4e4f6da133bb630e2c99cbe94b95f77ed1a2 100644 --- a/ReleaseNotes +++ b/ReleaseNotes @@ -8777,7 +8777,7 @@ detailed bugfix information): Jussi Kivilinna. - STM32 RTC and clock control: The STM32F4Discovery board doesn't come with a Low speed external oscillator so the default LSE source - for the RTC doesn't work. In stm32_rtcc.c the up_rtcinitialize() + for the RTC doesn't work. In stm32_rtcc.c the up_rtc_initialize() logic doesn't work with the LSI. The check on RTC_MAGIC on the BK0R register lead to rtc_setup() call that rightfully enables the LSI clock; but the next times, when the rtc is already setup, the @@ -9239,3 +9239,1211 @@ detailed bugfix information): returned value which will always be -1. - apps/examples: Correct use of the BOARDIOC_GRAPHICS_SETUP boardctl() call. + +NuttX-7.11 Release Notes +------------------------ + +The 111th release of NuttX, Version 7.11, was made on August 13 2015, +and is available for download from the Bitbucket.org website. Note +that release consists of two tarballs: nuttx-7.11.tar.gz and +apps-7.11.tar.gz. These are available from: + + https://bitbucket.org/patacongo/nuttx/downloads + https://bitbucket.org/nuttx/apps/downloads + +Both may be needed (see the top-level nuttx/README.txt file for build +information). + +Additional new features and extended functionality: + + * Core OS: + + - clock_gettime(): Use up_timer_gettime for CLOCK_MONOTONIC in + tickless mode. From Max Neklyudov. + - waitpid(): Implement WNOHANG for waitpid() only and for the case of + CONFIG_SCHED_HAVE_PARENT not selected. From Max Neklyudov. + - SCHED_SPORADIC: Add a sporadic scheduler to NuttX. + - Extend the processor-specific interface to include information to + support the Sporadic Scheduler. + - sem_tickwait(): Added this function for internal use within the OS. + It is a non-standard but more efficient version of sem_timedwait() + for use in higher performance device drivers. + + * Binary Loader: + + * Graphics/Graphic Drivers: + + - Graphics: Implement anti-aliasing in order to clean the drawing of + all edges. Anti-aliasing is supported in the horizontal, raster + direction only. + - SSD1306 LCD Driver: Modify the SSD1306 LCD driver to support either + the SPI or I2C interface. From Alan Carvalho de Assis. + + * File Systems/Block Drivers/MTD: + + - mount: Add the ability to mount a file system on top of en existing + node in the psuedo-file system. + - epoll(): Add a very simple epoll layer just around poll calls. To + satisfy build app requirements. From Anton D. Kachalov. + + * Common Device Drivers: + + - IOCTL: Add relay IOCTL definitions. From Max Neklyudov. + - I/O Expander Framework: Add an I/O expander driver framework. From + Sebastien Lorquet + - NXP PCA9555 I/O Explander. Add PCA9555 driver.From Sebastien + Lorquet + - BMP180 Barameter: Add support to Bosch BMP180 barometer. From + Alan Carvalho de Assis. + - CAN IOCTLs: Add CAN IOCTL command definitions to manage CAN message + filtering + - CAN Driver: Add configuration to support DLC to byte conversions + needed for CAN FD mode. + - SPI Slave Interface: Add a definition of an SPI slave interface. + - LM92 Temperature Sensor: Add a driver for the LM92 temperature + sensor. Contributed by Paul Alexander Patience. + - AS5048B Rotary Magnetic Sensor: Add support for an AS5048B rotary + magnetic sensor. From Paul Alexander Patience. + - Ramtron Driver: Update to include supportf for newer RAMTRON parts. + From David Sidrane. + - MB7040 Sonar Driver: Add support for a MB7040 sonar driver. From + Paul Alexander Patience. + - ms5805 Altimeter Driver: Add support for an MS5805 altimeter. From + Paul Alexander Patience. + + * Networking: + + - DNS Client: Implement the low-level network DNS packet protocol to + request and receive IPv6 address mappings. + - NetDB: Add support for a DNS host name resolution cache. This can + save a lot of DNS name server lookups (but might also have the + negative consequence of using stale IP address mappings. + - NetDB: Name resolution logic now supports lookups from a file like + /etc/hosts. + - Network Initialization: Add CONFIG_NETDEV_LATEINIT that can be + used to suppress calls to up_netinitialize() from early in + initialization. + - FTMAC100 Ethernet MAC Driver. Add support for Faraday FTMCA100 + Ethernet MAC/ From Anton D. Kachalov. + - UDP Networking: Add support for send() for connected UDP sockets. + + * Crypto: + + - Add CFB and MAC AES modes. From Max Neklyudov. + + * Simulation Platform: + + - Simulation: Implement board_power_off() for the simulation platform. + This allows for a graceful exit from the simulation. + + * MoxaRT: + + - MoxaRT SoC: Add support for MoxaRT SoC found in the most Moxa serial + converters such as NP51x0, NP66xx, UC72xx. From Anton D. Kachalov. + + * MoxaRT Boards: + + - Moxa NP51x0: Moxa NP51x0 series of 2-port advanced RS-232/422/485 + serial device servers. From Anton D. Kachalov. + + * ARMv6-M: + + - ARMv6-M Assertions: Port some per-process stack dumping logic from + ARMv7-M to ARMv6-M. From Alan Carvalho de Assis. + + * Atmel SAMD/L Boards: + + - SAML21: DMA: Add SAML21 DMA support. + - SAMD21: Add architecture support for the SAMD21 family. + - SAMD21-Xplained: Board configuration for the SAMD21 Xplained board. + + * Atmel SAM3/4 Drivers: + + - SAM4E: Add default loop optimization if EEFC_FMR is available in the + configuration (i.e., for SAM4S and 4E). From Marco Aurélio da Cruz. + - crypto/ and SAM4CM: Add CFB and MAC AES modes. From Max Neklyudov. + - SAM3/4: Add a TWI driver for the SAM4CM. From Max Neklyudov. + + * Freescale (NXP) Kinetis: + + - Kinetis: Add support for MK20DN--VLH5 and MK20DX---VLH5. Needed + for backward compatible support for Teensy-3.0. + + * Freescale (NXP) Kinetis Boards: + + - Teensy 3.x: Add board support for the PJRC Teensy-3.0 and + Teensy-3.1 boards. + + * Atmel SAMV7 Drivers: + + - SAMV7: Add an MCAN driver for the SAMV7 platform. + - SAMV7 SPI Slave Driver: Add the an SPI slave driver. + + * STMicro STM32: + + - STMicro STM32 F7: Add architecture support for the STMicro STM32 + F7. + - STM32 F446: Add support for the STMicro STM32 F446. From David + Sidrane. + + * STMicro STM32 Drivers: + + - STM32 F7: Add an STM32 F7 Ethernet driver. + - STM32 F7: Port the STM32 F4 DMA driver. + - STM32 F4 ADC: Add DMA support to the ADC driver for STM32 F4. From + Max Kriegler. + + * STMicro STM32 Boards: + + - STM32F762G-Disco: Add support for the STMicro STM32 F7 Discovery + board. + - STM32F4-Disco: Add support to BMP180 driver on the STM32F4 Discovery. + From Alan Carvalho de Assis. + + * C Library/Header Files: + + - Add asctime(), asctime_r(), ctime(), and ctime_r(). + - sethostname(): Add support for sethostname(). + - gethostbyname() and gethostbyaddr(): Add support for + gethostbyname() and gethostbyaddr(). Also support included for the + non-standard gethostbyname_r() and gethostbyaddr_r(). This moves + the DNS client logic from apps/ into the NuttX libc implementation. + + * Tools: + + - testbuild.sh: Add a script that can be used to perform building + testing for several board configurations. + + * Build/Configuration System: + + - apps/ Build System: No longer depends on hardcoded lists of + directories. Instead, it does a wildcard search to find all + appropriate directories. This means that to install a new + application, you simply have to copy the directory (or link it) into + the apps/ directory. If the new directory includes a Makefile and + Make.defs file, then it will automatically be included in the build. + - mkkonfig.sh: Add the tool mkkconfig.sh that dynamically builds the + apps/Kconfig file at configuration time. The hardcoded + configuration file has been removed and now the top-level Makefile + executes tools/mkkconfig.sh to auto-generate the top-level Kconfig + file. A new apps/ make target call preconfig: was added to support + this operation. Now you do not have to modify the top-level Kconfig + file to add a new directory into the configuration; the top-level + subdirectory simply needs to include a Kconfig file and it will + automatically be included in the configuration. The native Windows + build is temporarily broken until a new apps/tools/mkconfig.bat + script is generated. + - mkkconfig.bat: Add the Windows script corresponding to + apps/tools/mkkconfig.sh. Needed for a Windows native build. + + * Applications: apps/nshlib: + + - NSH shutdown command: NSH will now support an (optional) shutdown + command if the board provides the option CONFIG_BOARDCTL_POWEROFF. + The command can also be used to reset the system if + CONFIG_BOARDCTL_RESET=y. + - NSH uname command: Add support for a uname command. + - NSH nslookup command: Add an nslookup command. + + * Applications: apps/system: + + - NetDB: Add a system command to access the network database. + - readline(): Add support for Unix-style tab complete to readline. + Contributed by Nghia Ho. + - readline(): Extended the tab-completion support to also expand NSH + command names. + - readline(): Add support for an in-memory command line history that + can be retrieved using the up and down arrows. Contributed by Nghia + Ho. + + * Applications: apps/netutils: + + - DNS client: Moved the DNS client logic into the NuttX C library. + It is a necessary part for the full implementation of the netdb logic + and provides more flexibility in that location. + - Replace calls to the non-standard dns_gethotip() with calls to + standard gethostbyname(). + - NetLib: Create netlib wrapper functions around dns_getserver() and + dns_setserver() to isolate application code from changes to those + interfaces. + + * Applications: apps/examples: + + - OS test: Extend the OS test to include a test of + pthread_mutex_trylock() for recursive mutexes. From Juha Niskanen. + - OS test: Add a test for the sporadic scheduler. + +Bugfixes. Only the most critical bugfixes are listed here (see the +ChangeLog for the complete list of bugfixes and for additional, more +detailed bugfix information): + + * Core OS: + + - pthreads: Use -1 instead of 0 as PID for unclaimed mutexes. From + Juha Niskanen. + - pthreads: Implement pthread_mutex_trylock() for recursive mutexes. + From Juha Niskanen. + - pthread_create(): Group binding needs to be cleared before + sched_releasetcb(), as otherwise group_leave() will be called and + group->tg_nmembers decremented or group being released. group_leave() + should be called only after group_join() is called, not after + group_bind(). From Jussi Kivilinna. + - Protected Mode User Memory Allocator: Redesigned how the user space + heap is accessed from the kernel code in protected mode. It used to + call memory management functions in user space via function pointers + in the userspace interface. That is inefficient because the first + thing that those memory management functions do is to trap back into + the kernel to get the current PID. Worse, that operation can be + fatal is certain fragile situations such as when a task is exiting. + The solution is to remove all of the memory management function + calls from the interface. Instead, the interface exports the users + pace heap structure and then kernel size implementations of those + memory management functions will operate on the userspace heap + structure. This avoids the unnecessary system calls and, more + importantly, failures do to freeing memory when a test exits. + - pthread_create(): Fix an (unlikely) error in fallback value in the + event of a failure (which should never occur). + + * Common Drivers: + + - STMPE811 Driver: In stmpe811_instanciate() when + CONFIG_STMPE811_MULTIPLE is enabled, and the call to + stmpe811_checkid() fails, then the linked device list is not + restored to its previous state. From Sebastien Lorquet. + - CAN driver: Fix an issue in the CAN driver where the rx_sem count + can grow beyond bounds. + + * File System/Block Drivers: + + - NFS client: Fix prototype of unbind method. The function prototype + was not updated for NFS after a recent change to the file system + interface. From Manuel St??. + + * Networking/Network Drivers: + + - netconfig.h: Fix some backward compilation that was emitting #error + in the wrong condition when SLIP was enabled. + - SLIP Driver: Fix a missed name change when many of network + interface names changed sometime back but were apparently never + updated for SLIP. + - Networking: Allow receipt of empty UDP packets. From Max Neklyudov. + + * ARMv6-M: + + - ARMv6-M: Fix Cortex-M0 assembly error when the interrupt stack is + enabled. From Alan Carvalho de Assis. + + * Atmel SAMD/L Drivers: + + - SAMD20, D21, L21: In the SAML21, SERCOM5 uses a different SLOW clock + channel (and, hence, also a different SLOW GCLK generator). This + means that the channel selection cannot be a global definition but + must be a per SERCOM configuration setting. + - SAMD/L: Several fixes to register definitions and types. From + Janne Rosberg. + + * Atmel SAM3/4 Drivers: + + - SAM3/4 UART: Back out an error introduced with commit + 02c33f66c5a8be774034cd40e4125e9323c7b4d8. Causes an infinite loop in + up_lowputc(). From Max Neklyudov. + - SAM4CM: Fix SUPC register definitions. From Max Neklyudov. + - SAM3/4 WDT: Correct some problems with SAM3/4 watchdog driver. + Includes some small improvements. From Max Neklyudov. + + * Atmel SAMV7 Drivers: + + - SAMV7 UART: Also back the bad cloned change o sam_lowputc.c for + SAMV7 platform. + + * NXP LPC43xx Drivers: + + - LPC4350: Correct some LPC4350 GPIO pin configurations. From + Alessandro Temil. + + * SiLabs EMF32 Drivers: + + - EFM32 SPI: Correct write to incorrect register in EFM32 SPI driver. + From Pierre-noel Bouteville. + + * STMicro STM32 Drivers: + + - STM32 F15x: STM322 F15x stm32_stdclockconfig() was calling + stm32_pw_setvos() which accessed PWR_CR via an inactive APB From + Juha Niskaneni. + - STM32 Ethernet: Extend STM32 Ethernet operating frequency to 180MHz. + From Sebastien Lorquet. + + * STMicro STM32 Boards: + + - SAMV7 Xplained: In clock configuration, divider was set to 25 to get + 25*12MHz=300MHz CPU clock. The correct multiplier is 24 because the + calculation if (24+1)*12MHz. So the board was running at 312MHz. + From Efim Monjak. + + * ARMv7-A: + + - Cortex-A5 vfork(): Fix a Cortex-A compilation error when system + calls are enabled in modes other than CONFIG_BUILD_KERNEL. + + * Atmel SAMA5 Drivers: + + - SAMA5Dx EHCI: Fix some bad conditional compilation that left a + function undefined if CONFIG_USBHOST_ASYNCH is not selected. + + * C Library/Header Files: + + - getopt(): Uninitialized variable can cause hardfault from getopt() + if required argument is missing. From George McWilliams. + + * Applications: apps/nshlib: + + - NSH/THHPD: Change decoding to handle the increased size of the + scheduling policy field in the TCB. + + * Applications: apps/netutils: + + - THTTPD: Fix compilation problems when + CONFIG_THTTPD_GENERATE_INDICES is defined. + - THTTPD: Missing gci-src as a dependency path when building with + BINFS enabled. + + * Applications: apps/examples: + + - poll() example: Fix a few bit-rot compilation errors. + - Nx Lines example: If CONFIG_NX_ANTIALIASING=y, then the nxlines + example now erases a line that is 2 pixels longer and 2 pixels wider + than the line it drew. That eliminates edges effects due to + applying the anti-aliasing algorithm twice. A better solution + would be to make anti-aliasing an option for each graphics call so + you would rend the line with anti-aliasing ON and clear it with + anti-aliasing OFF. but I don't have the wherewithal for that change + today. + - OS test: Improve synchronization in round robin tests. On very fast + processors, there are race conditions that make the test fail. + Need better interlocking to assure that the threads actually do start + at the same time. + +NuttX-7.12 Release Notes +------------------------ + +The 112th release of NuttX, Version 7.12, was made on October 1, 2015, +and is available for download from the Bitbucket.org website. Note +that release consists of two tarballs: nuttx-7.12.tar.gz and +apps-7.12.tar.gz. These are available from: + + https://bitbucket.org/patacongo/nuttx/downloads + https://bitbucket.org/nuttx/apps/downloads + +Both may be needed (see the top-level nuttx/README.txt file for build +information). + +Additional new features and extended functionality: + + * Graphics/Graphic Drivers: + + - Added SSD1351 OLED controller support. Contributed by Paul + Alexander Patience. + + * Common Device Drivers: + + - MS58xx: Generalize the MS5805 altimeter driver to support other + family members. From Paul Alexander Patience. + - CAN driver interface: Add an error indication bit to the CAN + message report. + - Developed a new interface for QSPI. Most QSPI hardware (such as the + SAMV71) used a programmed interface to access the QuadSPI FLASH. + That programmed interface is no compatible with the simpler NuttX + SPI data transfer interface. + - Added a driver for ST25L1*K QuadSPI parts. + - Renamed the battery driver interface to battery_gauge since it + really only implements a battery fuel gauge. From Alan Carvalho de + Assis. + - Added a new framework to support a batter charger interface. From + Alan Carvalho de Assis. + - Added a BQ24250 battery charger driver. From Alan Carvalho de Assis. + + * Networking: + + - Added support for the local loopback device (dev lo, hostname localhost). + - Added NetDB support for the local loopback device. + - Network initialization: Automatically initialize all the TUN and + loopback devices if they arein the configuration. + + * Simulation Platform: + + - The simulation now runs under Cygwin64. Modern Cygwin X86_64 + machines follow the Microsoft ABI for parameter passing. The Linux + System 5 ABI would not work on X86_64-based Cygwin machines. Newer + Cygwin tool chains do nor pre-pend symbol names with the underscore + character. + + * Atmel SAMA5Dx: + + - Added architectural support for the Atmel SAMA5D2 parts. Not fully + verified in this NuttX release. + + * Atmel SAMA5Dx Boards: + + - Added support for the Atmel SAMA45D2 Xplained Ultra board. Not + fully verified in this NuttX release. + + * Atmel SAMV7 Drivers: + + - SAMV7 USBHS DCD: The device controller driver is (finally) + functional. + + * NXP LPC17xx: + + - Implement options to use external SDRAM and or SRAM for the heap. + From Pavel Pisa. + + * NXP LPC43x: + + - Added architectural support for the LPC4370. From Lok Tep. + + * NXP LPC43xx Drivers: + + - Added Ethernet support. From Ilya Averyanov. + - Added LPC43xx EHCI driver from Ilya Averyanov. + + * NXP LPC43xx Drivers: + + - Added support for the NXP LPC4370-Link2 development board from Lok + Tep. + + * STMicro STM32: + + - Added architectural for STM32F303K6, STM32F303K8, STM32F303C6, + STM32F303C8, STM32F303RD, and STM32F303RE devices. From Paul + Alexander Patience. + + * STMicro STM32 Drivers: + + - Added OTG support for STM32F44x. From David Sidrane. + + * STMicro STM32 Boards: + + - Added support for the STMicro Nucleo F303ERE board from Paul + Alexander Patience. + + * C Library/Header Files: + + - stdlib: Add support for div() to the C library. From OrbitalFox. + Also added ldiv() and lldiv() which are equivalent to div() with + long and long long types, respectively, instead of int. + - Added an implementation of the standard shutdown function. + + * Tools: + + - tools/mksymtab: declare g_symtab array as const to occupy RO section + (Flash). From Pavel Pisa. + + * Build/Configuration System: + + - Simplify configs/ Makefiles by combining common logic into a new + Board.mk Makefile fragment. From Paul Alexander Patience. + + * Applications: apps/system: + + - apps/system/symtab: Optional canned symtab inclusion to the build. + When option CONFIG_SYSTEM_SYMTAB is selected and symbol table file + libc/symtab/canned_symtab.inc is prepared then application can use + system provided complete symbol table. The option has substantial + effect on system image size. Mainly code/text. If loading of + applications at runtime is not planned do not select this. From + Pavel Pisa. + + * Applications: apps/canutils: + + - apps/canutils/uavcan: Add support for libuavcan. From Paul Alexander Patience. + + * Applications: apps/examples: + + - apps/examples/can: Extend the CAN loopback test by adding more + command line options. + - apps/examples/usbserial: Can now be run as an NSH builtin-function. + Now uses a configurable IO buffer size. + - apps/examples/nettest: Add option to suppress network initialization. + This is necessary if the nettest is run from NSH which has already + initialized the network. + - apps/examples/nettest: Extend test so that can be performed using + the local loopback device. + - apps/examples/netloop: Add a test of the local loopback device. + - apps/examples/udpblaster: Add a test to stress the network by + sending UDP packets at a very high rate. . + - apps/examples/uavcan: libuavcan example from Paul Alexander Patience. + +Bugfixes. Only the most critical bugfixes are listed here (see the +ChangeLog for the complete list of bugfixes and for additional, more +detailed bugfix information): + + * Core OS: + + - wd_create(): Correct a counting error in the number of available + watchdog timers. When the number of free timers is low, the counter + could be incremented below zero. + - mq_open(): When message queue is opened, inode_reserve() leaves the + reference count at zero. mq_open() logic must assure that the + reference count of the newly created inode is one. + - work_queue(): Logic that sets the queued indication and the logic + that does the actual queuing must be atomic. + + * Binary Loader: + + - Fix a memory leak in the built-in application logic: File was not + being closed. From Bruno Herrera. + + * File System/Block Drivers: + + - poll(): If we fail to setup the poll for any file descriptor, for + any reason, set the POLLERR bit. + - rwbuffer: Fix some logic errors. From Dmitry Nikolaev via Juha + Niskanen. + - ROMFS: One allocation was not being freed if there was a subsequent + failure to allocation I/O buffers resulting in a memory leak on + certain error conditions. From Bruno Herrera. + + * Networking/Network Drivers: + + - Fix a bug in tun interface driver. From Max Neklyudov. + - recvfrom(): Correct wait for new data when NET_UDP_READAHEAD is + enabled. Fix size accounting when recvfrom_udpreadahead() sets + state.rf_recvlen == -1. I have not checked if data are accumulated + to the right position in the buffer however. From Pavel Pisa. + - networking: Correct return value from psock_tcp_accept(). From + SaeHie Park. + - TCP: Fix a problem in when there are multiple network devices. + Polls were being sent to all TCP sockets before. This is not good + because it means that packets may sometimes be sent out on the wrong + device. That is inefficient because it will cause retransmissions + and bad performance. But, worse, when one of the devices is not + Ethernet, it will have a different MSS and, as a result, incorrect + data transfers can cause crashes. The fix is to lock into a single + device once the MSS is locked locked down. + - net/tcp: The logic that binds a specific network device to a + connection was faulty for the case of multiple network devices. On + bind(), the local address should be used to associate a device with + the connection (if the local address is not INADDR_ANY); On connect(), + the remote address should be used (in case the local address is + INADDR_ANY). On accept(), it does not matter but the remote address + is the one guaranteed to be available. + - net/tcp: Fix unbuffered send compilation error when Ethernet is not + enabled. From Alan Cavalho de Assis. + + * ARMv7-M: + + - All ARMV7-M IRQ setup: Always set the NVIC vector table address + unconditionally. This is needed in cases where the code is running + with a bootload and when the code is running from RAM. It is also + needed by the logic of up_ramvec_initialize() which gets the vector + base address from the NVIC. Suggested by Pavel Pisa. + - Fix some H/W floating point logic: In the original implementation, + !defined(CONFIG_ARMV7M_CMNVECTOR) was a sufficient test to determine + if lazy floating point register saving was being used. But recents + changes added common lazy register as well so now that test must be + (!defined(CONFIG_ARMV7M_CMNVECTOR) || defined(CONFIG_ARMV7M_LAZYFPU)). + - ARMv7-M, all "lazy" interrupt stack logic. Assembly instruction + that fetches the saved value is incorrect; replace with more + traditional push and pop. This is an important fix. Noted by + Stefan Kolb. + - All ARMV7-M: Force 8-byte stack alignment when calling from assembly + to C to interrupt handling. + - up_schedulesigaction(): Fix logic that determines if there is a + pending signal action before scheduling the next signal action. + Both the test and the scheduling action need to be atomic. This + problem was fixed on the ARMv7-M but also ported to other + architectures that had the same issue. + + * NXP LPC43xx: + + - LPC43xx: Fix NVIC_SYSH_PRIORITY_STEP define. From Ilya Averyanov. + - LPC43xx: Fix missing #define in eeprom. From Ilya Averyanov. + + * NXP LPC43xx Drivers: + + - Fixed the SPI driver. From Ilya Averyanov. + + * Atmel SAMA5 Drivers: + + - LPC31 and SAMA5D EHCI: Fix qh_ioccheck to move bp to next QH. From + Ilya Averyanov. + - LPC31 and SAMA5D EHCI: Performance improvement: Do not disable the + asynchronous queue when adding a new QH structure. From Ilya + Averyanov. + + * C Library/Header Files: + + - gethostbyname(): correct returned address format when DNS is used. + The hostent.h_addr_list should point to raw in_addr or in6_addr + as defined in the standard. Original implementation used that for + numeric addresses but for DNS lookup returned pointer to whole + sockaddr_in or sockaddr_in6. From Pavel Pisa . + - asin(): The function did not convert for some input values. asing() + did not convert for values which do not belong to the domain of the + function. But aside of that the function also did not converge for + allowed values. I achieved a conversion of the function by + reducing the DBL_EPSION and by checking if the input value is in + the domain of the function. This is a fix for the problem but the + function should always terminate after a given number of iterations. + From Stefan Kolb. + - Change all references from avsprintf to vasprintf. From Sebastien + Lorquet. + + * Applications: apps/nshlib: + + - Fix error handling in 'cat' command. On a failure to allocate + memory, a file was not being closed. From Bruno Herrera. + - Fix error handling in 'mv' command. On a failure to expand the + second path, the memory allocated for the expansion of the first + path was not being freed. From Bruno Herrera. + + * Applications: apps/system: + + - apps/system/netdb: Failed to build if CONFIG_NET_HOSTFILE was not + defined because gethostbyaddr() was not available. Noted by + OrbitalFox. + + * Applications: apps/netutils: + + - Various Kconfig files in netutils: Fix some changes from from + NETUTILS_DNSCLIENT to NETDB_DNSCLIENT. From Pavel Pisa. + + * Applications: apps/modbus: + + - Macros PR_BEGIN_EXTERN_C and PR_END_EXTERN_C were not defined in + all contexts. Replace with explicit expansion in all cases. From Stefan Kolb. + +NuttX-7.13 Release Notes +------------------------ + +The 113th release of NuttX, Version 7.13, was made on December 5, 2015, +and is available for download from the Bitbucket.org website. Note +that release consists of two tarballs: nuttx-7.13.tar.gz and +apps-7.13.tar.gz. These are available from: + + https://bitbucket.org/patacongo/nuttx/downloads + https://bitbucket.org/nuttx/apps/downloads + +Both may be needed (see the top-level nuttx/README.txt file for build +information). + +Additional new features and extended functionality: + + * Core OS: + + - External RTC: Added OS support for external RTC chips. + - boardctl(): Add a command to the boardctl() interface to obtain a + board unique ID. + + * File Systems: + + - TMPFS: Add support for a new TMPFS, RAM file system. The TMPFS + file system does not require any significant amount of memory + itself. It will grow dynamically as files are added and shrink back + when files are deleted. A very low overhead way to retain temporary + files. + - VFS: The VFS was extended to support standard file operations on + block drivers (open, close, read, write, etc.). The open() interface + accomplishes this by creating a temporary characer driver to mediate + the character oriented accesses to tje block driver. + - HOSTFS: Added a HOSTFS file system for use with the simulator. The + HOSTFS file system mounts in the simulated Nuttx context by provides + proxied access to the file system on the host PC. This is useful for + providing file system content and nonvolatile storage of files in the + simulation environment. From Ken Pettit. + - MTD/PROCFS: Add an interface to un-register an MTD procfs entry. + From Ken Pettit. + - filemtd: A new MTD conversion layer that will convert a regular file + (or driver file) to an MTD device. This is useful for testing on the + simulation using the HOSTFS. From Ken Pettit. + - PROCFS: Extended to include networking entries in the procfs. Device + status, device statistics, and network statistics are now available + from the PROCFS. + - PROCFS: The PROCFS file system can now be configured so that it + supports runtime registration of PROCFS entries with + CONFIG_FS_PROCFS_REGISTER=y. + + * Graphics/Graphic Drivers: + + - ST7565 Driver: Extend to include support for the ERC12864-3. From + Pierre-noel Bouteville. + + * Common Device Drivers: + + - User buttons: Added a character driver to support application access + to board buttons. Supports notification of button activity via + signals. + - User LEDs: Added a character driver to support application access + to on-board LEDs. + - Zero Cross: Added a Zero Cross device driver support. From Alan + Carvalho de Assis. + - MAX6675: Added support to Thermocouple-to-Digital converter MAX6675. + From Alan Carvalho de Assis. + - BCH: Block-to-character (BCH) driver should forward ioctl() calls + to the contained block driver. + - S25FL1xx: Added a S25FL1xx QuadSPI FLASH driver. + - On-Chip FLASH: Added an upper half MTD device that can use the + interfaces defined in included/nuttx/progmem.h to provide a + standard MTD driver. + - Serial: Implemented high level DMA infrastructure for serial + devices. From Max Neklyudov. + - AT24XX: Add support for multiple AT24xx EEPROM parts, each with + unique I2C addresses, but otherwise identical. + - External RTC: Added drivers for external I2C RTC chips: DS3102, + DS1307, DS3231, DS3232, and NXP PCF85263. + - W25: Added support for byte write mode to the W25 FLASH driver. From + Ken Pettit. + - dev/loop: Added a loop character device. losetup() and loteardown() + should not be called directory from applications. Rather, these + functions are now available as IOCTL commands to the loop driver. + - dev/smart: Added support for a /dev/smart loop device. From Ken + Pettit. + + * Networking: + + - Driver Statistics: Most network drivers do not support statistics. + Those that do only supported them when DEBUG is enabled. Each + driver collected an architecture specific set of statistics and + there was no common mechanism to view those statistics. Thus, + the driver feature was mostly useless. This release standardizes + the driver statistics and puts the definition in the common network + device structure defined in netdev.h where they can be accessed by + network applications. All Ethernet drivers that collect statistics + have been adapted to use these common statistics. + + * Simulation Platform: + + - W25 FLASH: Added support for W25 FLASH simulation. From Ken Pettit. + - HOSTFS: Added support for the HOSTFS file system (see "File Systems", + above). + + * Atmel SAMV7: + + - SAME70: Added support for the SAME70 family of chips. + - Tickless: SAMV7 now supports the tickless mode of operation. + + * Atmel SAMV7 Drivers: + + - MPU: Added MPU and protected build support. + - QSPI: Added a QuadSPI FLASH driver. This driver operates in the + memory-mapped, Serial Memory Mode (SMM). + - FLASH: Added support to write on-chip FLASH. + - Timer/Counter: TC driver ported to SAMV7 from the SAMA5. Free-running + and one-short timer logic also ported. + - PCK: Brought programmable clock (PCK) logic from SAMA5 into SAMV7. + - Timer/Counter: Support PCK6 as an optional source for the timer/ + counter clock. + + * Atmel SAMV7 Boards: + + - SAME70-Xplained: Add NSH and networking configurations for the + SAME70 Xplained board. Includes verified support for serial console, + LEDs, buttons, SDRAM, HSMCI SD card, and networking. + - SAMV7-XULT and SAME70-Xplained: If Tickless mode is selected then + enable PCK6 as a timer/counter clock source + + * STMicro STM32: + + - CCM PROCFS: Is no longer a part of the 'base' procfs entries and can + now only be supported via run time registration with + CONFIG_FS_PROCFS_REGISTER=y. + + * STMicro STM32 Drivers: + + - Timers: Add a compatible lower-half timer driver for use with the + common timer upper-half driver. From Wail Khemir. + + * STMicro STM32 Boards: + + - STM32F4-Discovery: Add low level support for the Zero Cross driver + for the STM32F4-Discovery. From Alan Carvalho de Assis. + - STM32F4-Discovery: Add board config to support for the MAX6675. From + Alan Carvalho de Assis. + + * C Library/Header Files: + + - bsearch(): Added the bsearch() function from NetBSD. + - freopen(): Added support for freopen(). + - strftime(): Added day-of-week support (when avaialable). + + * Tools: + + - nxstyle: Add crappy style checking tool nxstyle.c. See thee tools/ + README file for more info. + + * Applications: NSH + + - mksmartfs command: Add configuration option to supported multiple + rootdirectories. From Ken Pettit. + - Add support for 'basename' and 'dirname' commands. + - set command: Like bash, NSH set command now strips off any leading + or trailing whitespace. + - mount command: The mount commands now accepts mount options + (currently needed only for the hostfs file system). From Ken + Pettit. + - losetup command: NSH no longer calls losetup() and loteardown + directly. Now it opens /dev/loop and accomplishes these things + using ioctl() calls. + - ifconfig command: If CONFIG_NETDEV_STATISTICS=y, then print the + network driver statistics in the ifconfig. + - ifconfig, ifup, and ifdown: These commands now uses /proc/net/ + to view network device configuration and status and /proc/net/stat + to show network statistics. A consequence of this is that you + cannot view this network information if the procfs is not enabled + and mounted at /proc. + - losmart command: Added a new NSH losmart command. losmart setups + up a loop device for the smart MTD driver similar to losetup but + with different syntax. From Ken Pettit. + - ps command: The 'ps' command now uses /proc// to obtain task + status information. A consequence of this is that you cannot use + the 'ps' command if the procfs is not enabled and mounted at /proc. + + * Applications: apps/system: + + - apps/system/hexed: Port the hexed command line hexadeciamal editor + to Nuttx. See http://apps.venomdev.net/hexed/. + + * Applications: apps/fsutils: + + - apps/fsutils/smartfs: Move into apps/fsutils from kernel, now uses + only open and ioctl. From Ken Pettit. + + * Applications: apps/examples: + + - apps/examples/fstest: Add a generic file system test. This is + essentially the same as examples/smart, but has all of the SmartFS + specific logic ripped out. This was created for testing the new + TMPFS. + - apps/examples/zerocross: Add a Zero Cross application example. From + Alan Carvalho de Assis. + - apps/examples/media: Add a simple test for access of media via a + block driver or MTD driver. + +Bugfixes. Only the most critical bugfixes are listed here (see the +ChangeLog for the complete list of bugfixes and for additional, more +detailed bugfix information): + + * Core OS: + + - Fixed an error in clock_timespec_subtract(). Found by Lok. + - pthreads: CRITICAL BUGFIX: Logic was wiping out the indication that + of the type of a pthread. Hence, it could be confused as a task. + Found because this was causing a crash when /proc/nnn/cmdline was + printed. + + * File System/Block Drivers: + + - SMART MTD: Fix some Smart wear-leveling bugs. Fixed SmartFS wear + level error that occurs when the logical sector size is too small to + save all wear level status bytes in a single sector. Logical + sectors 1 and 2 were simply not being allocated and then the + read_sector and write_sector routines were failing. From Ken + Pettit. + + * Graphics/Graphic Drivers: + + - ILI9432: Fixed errors in orientation. Portrait, RPortrait, and + Landscript should work correly now. They were displayed mirrored. + From Marco Krahl. + + * Common Drivers: + + - CAN: Fix a problem in the CAN upper-half driver that occurs only + for CAN hardware that support a H/W FIFO of outgoing CAN messages. + In this case, there can be a hang condition if both the H/W and + S/W FIFOs are both full. In that case, there may be no event to + awaken the upper half driver. Add a new (conditional) CAN upper + half interface called can_txready() that can be used by the lower + half driver to avoid this hang condition. + - MS58xx: Fix some issues with initialization and with CRC + calculation. From Karim Keddam. + - W25: Fixed W25 FLASH driver page read/write logic. From Ken Pettit. + + * Atmel SAMV7 Drivers: + + - USART1 pin configuration: Reconfigure System I/O when using USART1. + From Frank Benkert. + - MCAN: Added a call to can_txready() to the MCAN driver. + + * STMicro STM32 Drivers: + + - stm32 F4: Fix some TIM12 pin mappings. From Max Kriegleder. + + * STMicro STM32 Boards: + + - STM32F429i-Disco: Calculated partition boundries based on page + block sizes but mtd_partition() is expecting calculations based on + erase block size. From Alan Carvalho de Assis. + + * C Library/Header Files: + + - sys/types.h: When building on a 64-bit machine, the size of size_t + should be 64-bits. In general, I believe that sizeof(size_t) should + be the same as sizeof(uinptr_t). mmsize_t should always be 32-bits + in any event. The last change to stddef has been backed out. With + these changes, the simulator builds without errors or warnings an a + 64-bit machine. + + * Applications: apps/nshlib: + + - The I/O buffer, g_iobuffer, should not be a global buffer. That + will not work in an environment where there are multiple NSH + sessions. The I/O buffer must, instead, be a part part of the + session-specific data defined in nsh_console.h. + +NuttX-7.14 Release Notes +------------------------ + +The 114th release of NuttX, Version 7.14, was made on January 28, 2016, +and is available for download from the Bitbucket.org website. Note +that release consists of two tarballs: nuttx-7.14.tar.gz and +apps-7.14.tar.gz. These are available from: + + https://bitbucket.org/patacongo/nuttx/downloads + https://bitbucket.org/nuttx/apps/downloads + +Both may be needed (see the top-level nuttx/README.txt file for build +information). + +Additional new features and extended functionality: + + * Core OS: + + - modules: Add support for kernel modules: insmod, rmmod, support + functions. procfs support for user lsmod functioniality. + - SIGEV_THREAD: Add support for the SIGEV_THREAD notification method + in struct sigevent. This initial implementation will only work in + the FLAT build since it utilizes the work queue for signal + callbacks. See the top-level TODO file for additional details. + - 64-Bit Timer: If the 64-bit timer is selected, then use it whenever + clock_systimer() is called rather then chopping the 64-bit timer + down to 32-bits. Add a new type, systime_t to represent the 32- or + 64-bit system timer. This eliminates clock_systimer32() and + clock_systime64(); there is now only clock_systimer(). + + * Common Device Drivers: + + - Telnet Driver: Move the Telnet driver from apps/ to + nuttx/drivers/net. It is a driver a belongs in the OS. Now works + like the loop device: A new interface called telnet_initialize() + registers a telnet session "factory" device at /dev/telnet. Via + ioctl, the factory device can create instances of the telnet + character devices at /dev/telnetN to support Telnet sessions. + - PCA9635PW: Add a driver for the PCA9635PW I2C LED driver IC which + can be used to control the intensity of up to 16 LEDs. From + Alexander Entinger. + - MCP9844: Driver for the MCP9844 I2C digital temperature sensor with + a selectable resolution. From Alexander Entinger. + - PN532: Add driver for the NXP PN532 NFC-chip. From Janne Rosberg + and others at Offcode Ltd. + - LSM9DS1: Add driver for the STMicro LSM9DS1 chip. The LSM9DS1 is a + system-in-package featuring a 3D digital linear acceleration sensor, + a 3D digital angular rate sensor, and a 3D digital magnetic sensor. + From Paul Alexander Patience. + - CAN Interface: Add more extensive error reporting capaibility to + the CAN interface definitions. From Frank Benkert. + - SPI Interface: Add an optional hwfeatures() method to the SPI + interface. + + * Simulation Platform: + + - NSH configuration uses the custom start up scriptwith a read-only + passwd file. Includes hooks for an MOTD message. + + * ARMv7-R + + - ARMv7-R: Add basic architecture support for the ARMv7-R processor + family. + + * Atmel AVR: + + - Atmega2560: Add support for the Atmega2560. From Dimitry Kloper. + - debug.h: Add an AVR-specific header file used when the AVR MEMX + pointer is used. From Dimitri Kloper. + + * Atmel AVR Boards: + + - Arduino-Mega2560: Add support for the Arduino-Mega2560. From + Dimitry Koper. + + * Atmel SAMV7 Drivers: + + - Port the TRNG driver from the SAMA5D3/4 to the SAMV7. + - Port the WDT driver from the SAMA5D3/4 to the SAMV7. + - Add an RSWDT driver. + + * Atmel SAMV7 Boards: + + - SAMV71-XULT: Add configuration for testing OS modules. + + * Freescale Kinetis: + + - MK60N512VLL100: Add support for the MK60N512VLL100 Kinetis part. + From Andrew Webster. + + * Freescale Kinetis Boards: + + - ENET: Numerous updates to the Kinetis ENET driver. That driver is + now functional. From Andrew Webster. + + * NXP LPC43xx Boards: + + - WaveShare LPC4337-WS: Support for the WaveShare LPC4337-WS board. + From Lok Tep. + + * STMicro STM32 Drivers: + + - Timer Capture: Add timer input capture driver. From Pierre-Noel + Bouteville. + + * STMicro STM32 Boards: + + - Olimex STM32 H407: Added a port to the Olimex STM32 H407 board. + This board features the STMicro STM32F407ZGT6 (144 pins). + Contributed by Neil Hancock. + + * TI TMS550 Boards: + + - TI LaunchXL-TMS57004: Add basic board support for TI LaunchXL- + TMS57004. Still a work in progress. + + * C Library/Header Files: + + - sys/time.h: Add timeradd(), timersub(), timerclear(), timerisset(), + and timercmp() as macros. These are non-POSIX interfaces, but + included in most BSD deriviatives, including Linux. From Manuel St??. + - AVR support: Introduce support for Atmel toolchain in-flash strings. + Atmel toolchain AVR compiler provides a transparent in-flash object + support using __flash and __memx symbols. The former indicates to + compiler that this is a flash-based object. The later used with + pointer indicates that the referenced object may reside either in + flash or in RAM. The compiler automatically makes 32-bit pointer + with flag indicating whether referenced object is in flash or RAM + and generates code to access either in run-time. Thus, any function + hat accepts __memx object can transparently work with RAM and flash + objects. + For platforms with a Harvard architecture and a very small RAM like + AVR this allows to move all constant strings used in trace messages + to flash in the instruction address space, releasing resources for + other things. This change introduces IOBJ and IPTR type qualifiers. + The 'I' indicates that the object may lie in instruction space on a + Harvard architecture machine. For platforms that do not have __flash + and __memx or similar symbols IOBJ and IPTR are empty, making the + types equivalent to, for example, 'const char' and 'const char*'. + For Atmel compiler these will become 'const __flash char' and + 'const __memx char*'. All printf() functions and syslog() functions + are changed so that the qualifier is used with the format parameter. + From Dimitry Kloper. + - debug.h: Add configuration to support an architecture-specific + debug.h header file. From Dimitri Kloper. + - netdb: Add support for the use of a DNS resolver file like + /etc/resolv.conf. + - TEA: Add an implementation of the Tiny Encryption Algorithm. + - math32.h: Add some utilities to support 64-bit arithmetic + operations for platforms that do not support long long types. + + * Tools: + + - tools/cnvwindeps.c: Add a tool that will convert paths in + dependencies generated by a Windows compiler so that they can be + used with the Cygwin make. + - tools/mkwindeps.sh: A script that coordinates use of cnvwindeps.exe. + Dependencies now work on the Cygwin platform when using a Windows + ative toolchain. + + * Applications: NSH + + - Module Commands: Add module commands: insmod, rmmod, and lsmod. + - Time Command: Add a 'time' command that may be used to time the + execution of other commands. + - Password Commands: Add useradd, userdel, and passwd commands. + - MOTD: Now supports a Message of the Day (MOTD) that will be + presented after the NSH greeting. + - Session Logins: All sessions may be protected with logins using the + encrypted password in /etc/passwd. + - Extended Logins. Added optional platform-specific function to + perform password verification and optional delay after each failed + login attempt. + + * Applications: apps/fsutils: + + - apps/fsutils/passwd: Utility library for accessing a password file + like /etc/passwd. + + * Applications: apps/netutils: + + - apps/netutils/telnetd: Now creates Telnet sessions by opening a new + factory device at /dev/telnet and then using ioctl calls to create + the session character drivers at /dev/telnetN. + - apps/netutils/netlib: Add netlib_get_dripv4addr() and + netlib_get_ipv4netmask(). From Pelle Windestam. + + * Applications: apps/examples: + + - apps/examples/module: Add a test harness for verifying NuttX kernel + modules. + - apps/examples/pca9635: Add a simple test of PCA9635PW PWM LED driver. + From Alan Carvalho de Assis. + - apps/examples/ostest: Add a test of POSIX timers using SIGEV_THREAD. + +Bugfixes. Only the most critical bugfixes are listed here (see the +ChangeLog for the complete list of bugfixes and for additional, more +detailed bugfix information): + + * Core OS: + + - pthreads: CRITICAL BUGFIX: Logic was wiping out the indication that + of the type of a pthread. Hence, it could be confused as a task. + - waitpid: CRITICAL BUGFIX. Add a reference count to prevent waitpid + from using stale memory released by the waited-for task group. + - clock_systimespec(): Fix an error in a time conversion. + + * File System/Block Drivers: + + - poll(): Fix handling of sem_tickwait() return value sem_tickwait() + does not return an -1+errno, it returns a negated errno value. + Noted by Freddie Chopin. + + * Common Drivers: + + - TUN Driver: Fix a compile time error in the TUN driver. From + Vladimir Komendantskiy. + - USB Host HID Parser: Wrong size used in memcpy(). From Hang Xu. + - PCA9555: Fixed a bug in the function pca9555_setbit which occurs if + someone tries to set one of the pins 8-15. The problem is that + after the check if the pin is greater than 7 the variable addr is + incremented and used in the Call I2C_WRITEREAD. But later in the + call to the I2C_WRITE buf[0] is used as address but this address is + not incremented as it should be. Note address does mean the address + to the register in the ioexpander and not the I2C address. From + Stefan Kolb. + + * Networking: + + - TCP/IOB: Numerous fixes, mostly relate to TCP and IOB buffering + and race conditions. These were necessary for for the NuttX + networking later to be stable in some stress testing. From Andrew + Webster. + + * Atmel SAMV7 Drivers: + + - USBHS Device: In USBHS device driver, fix check if zero length + packet is needed. + + * STMicro STM32 Drivers: + + - OTG FS Host: Fix some backward arguments to stm32_putreg(). Note + by Hang Xu. + + * Tools: + + - tools/mkdeps.c: Extended/fixed support for --winpath option. + Dependencies now work under Cygwin with a native Windows toolchain. + + * Build System: + + - apps/platform/Makefile: Use a relative path to the board directory + link rather than the absolute path. For Cygwin, the absolute would + would need converted with cygpath. But just using the relative path + is a simpler solution. diff --git a/TODO b/TODO index b63ea6f64640a8d258d64df6f879fbb63af967b3..74e94c7b5a1363514f9e959780c065f9ad549ad5 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ -NuttX TODO List (Last updated August 6, 2015) +NuttX TODO List (Last updated February 18, 2016) +NuttX TODO List (Last updated February 18, 2016) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -9,27 +10,29 @@ issues reated to each board port. nuttx/ - (12) Task/Scheduler (sched/) + (13) Task/Scheduler (sched/) (1) Memory Management (mm/) (3) Signals (sched/signal, arch/) (2) pthreads (sched/pthread) (0) Message Queues (sched/mqueue) - (4) C++ Support + (6) Kernel/Protected Build + (3) C++ Support (6) Binary loaders (binfmt/) (12) Network (net/, drivers/net) (4) USB (drivers/usbdev, drivers/usbhost) - (12) Libraries (libc/, libm/) + (0) Other drivers (drivers/) + (11) Libraries (libc/, libm/) (11) File system/Generic drivers (fs/, drivers/) (8) Graphics subsystem (graphics/) (1) Pascal add-on (pcode/) - (2) Build system / Toolchains - (3) Linux/Cywgin simulation (arch/sim) - (5) ARM (arch/arm/) + (1) Build system / Toolchains + (4) Linux/Cywgin simulation (arch/sim) + (4) ARM (arch/arm/) apps/ - (4) Network Utilities (apps/netutils/) - (3) NuttShell (NSH) (apps/nshlib) + (3) Network Utilities (apps/netutils/) + (2) NuttShell (NSH) (apps/nshlib) (1) System libraries apps/system (apps/system) (4) Other Applications & Tests (apps/examples/) @@ -213,6 +216,27 @@ o Task/Scheduler (sched/) Status: Open Priority: Medium-ish + Title: SCALABILITY + Description: Task control information is retained in simple lists. This + is completely appropriate for small embedded systems where + the number of tasks, N, is relatively small. Most list + operations are O(N). This could become as issue if N gets + very large. + + In that case, these simple lists should be replaced with + something more performant such as a balanced tree in the + case of ordered lists. Fortunately, most internal lists are + hidden behind simple accessor functions and so the internal + data structures can be changed if need with very little impact. + + + Explicity refereence to the list strucutre are hidden behnid + the macro this_task(). + + Status: Open + Priority: Low. Things are just the way that we want them for the way + that NuttX is used today. + o Memory Managment (mm/) ^^^^^^^^^^^^^^^^^^^^^^ @@ -314,9 +338,17 @@ o Signals (sched/signal, arch/) embedded system. Title: SIGEV_THREAD - Description: sig_notify() logic does not support SIGEV_THREAD; structure - struct sigevent does not provide required members sigev_notify_function - or sigev_notify_attributes. + Description: Implementation of support for support for SIGEV_THREAD is available + only in the FLAT build mode because it uses the OS work queues to + perform the callback. The alternative for the PROTECTED and KERNEL + builds would be to create pthreads in the user space to perform the + callbacks. That is not a very attractive solution due to performance + issues. It would also require some additional logic to specify the + TCB of the parent so that the pthread could be bound to the correct + group. + + There is also some user-space logic in libc/aio/lio_listio.c. That + logic could use the user-space work queue for the callbacks. Status: Low, there are alternative designs. However, these features are required by the POSIX standard. Priority: Low for now @@ -414,35 +446,19 @@ o Kernel/Protected Build COMMAND KERNEL INTERFACE(s) -------- ---------------------------------------------- - losetup losetup(), loteardown() mkfatfs mkfatfs mkrd ramdisk_register() - dd bchlib_setup(), bchlib_read(), bchlib_write(), - bchlib_teardown() - ps sched_foreach() - ifup netdev_foreach() - ifdown netdev_foreach() - ifconfig netdev_foreach(), g_netstats ping icmp_ping() - Status: Open - Priority: Medium/High -- the kernel build configuration is not fully fielded - yet. + The busybox mkfatfs does not involve any OS calls; it does + its job by simply opening the block driver (using open/xopen) + and modifying it with write operations. See: - Title: NSH free COMMAND LIMITATION - Description: The NSH 'free' command only shows memory usage in the user - heap only, not usage in the kernel heap. I am thinking that - kernel heap memory usage should be available in /proc/memory. - Status: Open - Priority: Medium/High + http://git.busybox.net/busybox/tree/util-linux/mkfs_vfat.c - Title: TELNETD PARTITIONING. - Description: Telnetd is implemented as a driver that resides in the apps/ - directory. In the kernel/protected build modes, the driver - logic must be moved into the kernel part of the build (nuttx/, - although the application level interfaces must stay in apps/). Status: Open - Priority: Medium + Priority: Medium/High -- the kernel build configuration is not fully fielded + yet. Title: NxTERM PARTITIONING. Description: NxTerm is implemented (correctly) as a driver that resides @@ -508,6 +524,10 @@ o Kernel/Protected Build console output. The requests for the pid() are part of the implementation of the I/O's re-entrant semaphore implementation and would not be an issue in the more general case. + + Update: + One solution might be to used CONFIG_TLS, add the PID to struct + tls_info_s. Then the PID could be obtained without a system call. Status: Open Priority: Low-Medium. Right now, I do not know if these syscalls are a real performance issue or not. The above statistics were collected @@ -563,20 +583,6 @@ o C++ Support would be to get a hold of the compilers definition of size_t. Priority: Low. - Title: STATIC CONSTRUCTORS - Description: Need to call static constructors - Update: Static constructors are implemented for the STM32 F4 and - this will provide the model for all solutions. Basically, if - CONFIG_HAVE_CXXINITIALIZE=y is defined in the configuration, then - board-specific code must provide the interface up_cxxinitialize(). - up_cxxinitialize() is called from application logic to initialize - all static class instances. This TODO item probably has to stay - open because this solution is only available on STM32 F4. - Status: Open - Priority: Low, depends on toolchain. Call to gcc's built-in static - constructor logic will probably have to be performed by - user logic in the application. - Title: STATIC CONSTRUCTORS AND MULTITASKING Description: The logic that calls static constructors operates on the main thread of the initial user application task. Any static @@ -801,25 +807,6 @@ o Network (net/, drivers/net) Status: Open Priority: Low - Title: STANDARDIZE ETHERNET DRIVER STATISTICS - Description: Need to standardize collection of statistics from network - drivers. Currently they are useless because they are not - accessible. The solution is to standardize the structure - that holds the drivers statistics. Then apps/nshlib - ifconfig command could present the driver statistics. - - Currently these drivers support non-standard statistics: - - arch/arm/src/kinetis/kinetis_enet.c - arch/arm/src/lpc17xx/lpc17_ethernet.c - arch/arm/src/tiva/lm3s_ethernet.c - arch/mips/src/pic32mx/pic32mx-ethernet.c - arch/z80/src/ez80/ez80_emac.c - - The other Ethernet drivers support no statistics. - Status: Open - Priority: Low. This is not a bug but an enhancement idea. - Title: CONCURRENT TCP SEND OPERATIONS Description: At present, there cannot be two concurrent active TCP send operations in progress using the same socket. This is because @@ -990,6 +977,12 @@ o Network (net/, drivers/net) Priority: Low. I don't know of any issues now, but I am sure that someone will encounter this in the future. + Title: MISSING netdb INTERFACES + Description: There is no implementation for many netdb interfaces such as + getaddrinfo(), freeaddrinfo(), getnameinfo(), etc. + Status: Open + Priority: Low + o USB (drivers/usbdev, drivers/usbhost) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1197,11 +1190,6 @@ o Libraries (libc/) Status: Open Priority: Low - Title: DAYS OF THE WEEK - Description: strftime() and other timing functions do not handle days of the week. - Status: Open - Priority: Low - Title: RESETTING GETOPT() Description: There is an issue with the way that getopt() handles errors that return '?'. @@ -1293,12 +1281,16 @@ o Libraries (libc/) it does not return at all as the loop in it does not converge, hanging your app. - "There are likely many other issues like these as the Rhombs + "There are likely many other issues like these as the Rhombus OS code has not been tested or used that much. Sorry for not providing patches, but we found it easier just to switch the math library." Ref: https://groups.yahoo.com/neo/groups/nuttx/conversations/messages/7805 + + UPDATE: 2015-09-01: A fix for the noted problems with asin() + has been applied. + Status: Open Priority: Low for casual users but clearly high if you need care about these incorrect corner case behaviors in the math libraries. @@ -1308,8 +1300,8 @@ o File system / Generic drivers (fs/, drivers/) NOTE: The NXFFS file system has its own TODO list at nuttx/fs/nxffs/README.txt - Title: CHMOD() AND TRUNCATE() - Description: Implement chmod(), truncate(). + Title: CHMOD(), TRUNCATE(), AND FSTAT() + Description: Implement chmod(), truncate(), and fstat(). Status: Open Priority: Low @@ -1545,6 +1537,7 @@ o Graphics subsystem (graphics/) Status: Open Priority: Low, not a serious issue but worth noting. There is no plan to change this behavior. + o Pascal Add-On (pcode/) ^^^^^^^^^^^^^^^^^^^^^^ @@ -1568,16 +1561,6 @@ o Pascal Add-On (pcode/) o Build system ^^^^^^^^^^^^ - Title: WINDOWS DEPENDENCY GENERATION - Description: Dependency generation is currently disabled when a Windows native - toolchain is used in a POSIX-like environment (like Cygwin). The - issue is that the Windows tool generates dependencies use Windows - path formatting and this fails with the dependency file (Make.dep) - is include). Perhaps the only issue is that all of the Windows - dependencies needed to be quoted in the Make.dep files. - Status: Open - Priority: Low -- unless some dependency-related build issues is discovered. - Title: MAKE EXPORT LIMITATIONS Description: The top-level Makefile 'export' target that will bundle up all of the NuttX libraries, header files, and the startup object into an export-able @@ -1591,6 +1574,9 @@ o Build system Status: Open Priority: Low. +o Other drivers (drivers/) + ^^^^^^^^^^^^^^^^^^^^^^^^ + o Linux/Cywgin simulation (arch/sim) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1623,18 +1609,81 @@ o Linux/Cywgin simulation (arch/sim) "faked" during IDLE loop processing and, as a result, there is no task pre-emption because there are no asynchronous events. This could probably be fixed if the "timer interrupt" were driver by Linux - signals. NOTE: You would also have to implement irqsave() and - irqrestore() to block and (conditionally) unblock the signal. + signals. NOTE: You would also have to implement up_irq_save() and + up_irq_restore() to block and (conditionally) unblock the signal. Status: Open Priority: Low + Title: SMP SIMULATION ISSUES + Description: The configuration has basic support SMP testing. The simulation + supports the emulation of multiple CPUs by creating multiple + pthreads, each run a copy of the simulation in the same process + address space. + + At present, the SMP simulation is not fully functional: It does + operate on the simulated CPU threads for a few context switches + then fails during a setjmp() operation. I suspect that this is + not an issue with the NuttX SMP logic but more likely some chaos + in the pthread controls. I have seen similar such strange behavior + other times that I have tried to use setjmp/longmp from a signal + handler! Like when I tried to implement simulated interrupts + using signals. + + Apparently, if longjmp is invoked from the context of a signal + handler, the result is undefined: + http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1318.htm + + You can enable SMP for ostest configuration by enabling: + + -# CONFIG_EXPERIMENTAL is not set + +CONFIG_EXPERIMENTAL=y + + +CONFIG_SPINLOCK=y + +CONFIG_SMP=y + +CONFIG_SMP_NCPUS=2 + +CONFIG_SMP_IDLETHREAD_STACKSIZE=2048 + + You also must enable near-realtime-performance otherwise even long + timeouts will expire before a CPU thread even has a chance to + execute. + + -# CONFIG_SIM_WALLTIME is not set + +CONFIG_SIM_WALLTIME=y + + And you can enable some additional debug output with: + + -# CONFIG_DEBUG_SCHED is not set + +CONFIG_DEBUG_SCHED=y + + -# CONFIG_SCHED_INSTRUMENTATION is not set + +CONFIG_SCHED_INSTRUMENTATION=y + + The NSH configuration can also be forced to run SMP, but + suffers from the same quirky behavior. I can be made + reliable if you modify arch/sim/src/up_idle.c so that + the IDLE loop only runs for CPU0. Otherwise, often + simuart_post() will be called from CPU1 and it will try + to restart NSH on CPU0 and, again, the same quirkiness + occurs. + + But for example, this command: + + nsh> sleep 1 & + + will execute the sleep command on CPU1 which has worked + every time that I have tried it (which is not too many + times). + + Status: Open + Priority: Low, SMP is important, but SMP on the simulator is not + o ARM (arch/arm/) ^^^^^^^^^^^^^^^ Title: IMPROVED ARM INTERRUPT HANDLING Description: ARM interrupt handling performance could be improved in some ways. One easy way is to use a pointer to the context save - area in current_regs instead of using up_copystate so much. + area in g_current_regs instead of using up_copystate so much. This approach is already implemented for the ARM Cortex-M0, Cortex-M3, Cortex-M4, and Cortex-A5 families. But still needs @@ -1694,31 +1743,6 @@ o ARM (arch/arm/) If your design needs continuous interrupts like this, please try the above change and, please, submit a patch with the working fix. - Title: STACK ALIGNMENT IN INTERRUPT HANDLERS - Description: The EABI standard requires that the stack always have a 32-byte - alignment. There is no guarantee at present that the stack will be - so aligned in an interrupt handler. Therefore, I would expect some - issues if, for example, floating point or perhaps long long operations - were performed in an interrupt handler. - - This issue exists for ARM7, ARM9, Cortex-M0, Cortex-M3, and - Cortex-M4 but has been addressed for the Cortex-A5. The fix - is really simple can cannot be incorporated without some - substantial testing. For ARM, the fix is the following logic - arround each call into C code from assembly: - - mov r4, sp /* Save the SP in a preserved register */ - bic sp, sp, #7 /* Force 8-byte alignment */ - bl cfunction /* Call the C function */ - mov sp, r4 /* Restore the possibly unaligned stack pointer */ - - This same issue applies to the interrupt stack which is, I think - improperly aligned in almost all cases (except Cortex-A5). - - Status: Open - Priority: Low for me because I never do floating point operations in - interrupt handlers. - Title: IMPROVED TASK START-UP AND SYSCALL RETURN Description: Couldn't up_start_task and up_start_pthread syscalls be eliminated. Wouldn't this work to get us from kernel- @@ -1758,18 +1782,6 @@ o Network Utilities (apps/netutils/) Status: Open. An annoyance, but not a real problem. Priority: Low - Title: DHCPD ACCESSES KERNEL PRIVATE INTERFACE - Description: arp_update() is referenced outside of nuttx/net. It is used in - in the netutils/ DHCPD logic to set entries in the ARP table. - That is violation of the separation of kernel and OS - functionality. As a consequence, dhcpd will not work with the - NuttX kernel built. - - This direct OS call needs to be replaced with a network ioctl() - call. - Status: Open - Priority: Medium. Important for full functionality with kernel build. - Title: NETWORK MONITOR NOT GENERALLY AVAILABLE Description: The NSH network management logic has general applicability but is currently useful only because it is embedded in the NSH @@ -1787,13 +1799,7 @@ o NuttShell (NSH) (apps/nshlib) show status for the single interface on the command line; it will still show status for all interfaces. Status: Open - Priority: Low (multiple network interfaces not fully supported yet anyway). - - Title: ARP COMMAND - Description: Add an ARP command so that we can see and modify the contents of - the ARP table. - Status: Open - Priority: Low (enhancement) + Priority: Low Title: ARPPING COMMAND Description: Add an arping command diff --git a/arch b/arch index 6190d664666b19580969c4e620646ef4e54f0182..feb41dfa8e178a1194fd17afae154bc55912993d 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 6190d664666b19580969c4e620646ef4e54f0182 +Subproject commit feb41dfa8e178a1194fd17afae154bc55912993d diff --git a/audio/.gitignore b/audio/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4b32ec6a3dad99cabafd7be62b05f4422d3d4aeb --- /dev/null +++ b/audio/.gitignore @@ -0,0 +1,10 @@ +/Make.dep +/.depend +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/audio/audio.c b/audio/audio.c index f09fe631f0b8c9d7353cd4a8d39e001b8fa8a320..a1f0db3834ca97b08b16d815567767fd064cb772 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -379,7 +379,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case AUDIOIOC_GETCAPS: { - FAR struct audio_caps_s *caps = (FAR struct audio_caps_s*)((uintptr_t)arg); + FAR struct audio_caps_s *caps = (FAR struct audio_caps_s *)((uintptr_t)arg); DEBUGASSERT(lower->ops->getcaps != NULL); audvdbg("AUDIOIOC_GETCAPS: Device=%d\n", caps->ac_type); @@ -393,7 +393,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case AUDIOIOC_CONFIGURE: { FAR const struct audio_caps_desc_s *caps = - (FAR const struct audio_caps_desc_s*)((uintptr_t)arg); + (FAR const struct audio_caps_desc_s *)((uintptr_t)arg); DEBUGASSERT(lower->ops->configure != NULL); audvdbg("AUDIOIOC_INITIALIZE: Device=%d\n", caps->caps.ac_type); @@ -873,11 +873,11 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev) char path[AUDIO_MAX_DEVICE_PATH]; static bool dev_audio_created = false; #ifndef CONFIG_AUDIO_CUSTOM_DEV_PATH - const char* devname = "/dev/audio"; + FAR const char *devname = "/dev/audio"; #elif !defined(CONFIG_AUDIO_DEV_ROOT) - const char* devname = CONFIG_AUDIO_DEV_PATH; - const char* ptr; - char* pathptr; + FAR const char *devname = CONFIG_AUDIO_DEV_PATH; + FAR const char *ptr; + FAR char *pathptr; #endif /* Allocate the upper-half data structure */ diff --git a/audio/pcm_decode.c b/audio/pcm_decode.c index b8808a2cb7d4f4c9aeb5588a8740c03a1249c480..d57d5dbb9b25a694eb58797540f25cbc34dc348f 100644 --- a/audio/pcm_decode.c +++ b/audio/pcm_decode.c @@ -259,23 +259,23 @@ static void pcm_callback(FAR void *arg, uint16_t reason, #ifdef CONFIG_PCM_DEBUG static void pcm_dump(FAR const struct wav_header_s *wav) { - dbg( "Wave file header\n"); - dbg( " Header Chunk:\n"); - dbg( " Chunk ID: 0x%08x\n", wav->hdr.chunkid); - dbg( " Chunk Size: %u\n", wav->hdr.chunklen); - dbg( " Format: 0x%08x\n", wav->hdr.format); - dbg( " Format Chunk:\n"); - dbg( " Chunk ID: 0x%08x\n", wav->fmt.chunkid); - dbg( " Chunk Size: %u\n", wav->fmt.chunklen); - dbg( " Audio Format: 0x%04x\n", wav->fmt.format); - dbg( " Num. Channels: %d\n", wav->fmt.nchannels); - dbg( " Sample Rate: %u\n", wav->fmt.samprate); - dbg( " Byte Rate: %u\n", wav->fmt.byterate); - dbg( " Block Align: %d\n", wav->fmt.align); - dbg( " Bits Per Sample: %d\n", wav->fmt.bpsamp); - dbg( " Data Chunk:\n"); - dbg( " Chunk ID: 0x%08x\n", wav->data.chunkid); - dbg( " Chunk Size: %u\n", wav->data.chunklen); + dbg("Wave file header\n"); + dbg(" Header Chunk:\n"); + dbg(" Chunk ID: 0x%08x\n", wav->hdr.chunkid); + dbg(" Chunk Size: %u\n", wav->hdr.chunklen); + dbg(" Format: 0x%08x\n", wav->hdr.format); + dbg(" Format Chunk:\n"); + dbg(" Chunk ID: 0x%08x\n", wav->fmt.chunkid); + dbg(" Chunk Size: %u\n", wav->fmt.chunklen); + dbg(" Audio Format: 0x%04x\n", wav->fmt.format); + dbg(" Num. Channels: %d\n", wav->fmt.nchannels); + dbg(" Sample Rate: %u\n", wav->fmt.samprate); + dbg(" Byte Rate: %u\n", wav->fmt.byterate); + dbg(" Block Align: %d\n", wav->fmt.align); + dbg(" Bits Per Sample: %d\n", wav->fmt.bpsamp); + dbg(" Data Chunk:\n"); + dbg(" Chunk ID: 0x%08x\n", wav->data.chunkid); + dbg(" Chunk Size: %u\n", wav->data.chunklen); } #endif diff --git a/binfmt/Makefile b/binfmt/Makefile index c5cfe9736bcf196ffd3596820cb6c06d8928ad7a..5c5244d89bf9f38fa4181440bd9b9d2932510b5c 100644 --- a/binfmt/Makefile +++ b/binfmt/Makefile @@ -1,7 +1,7 @@ ############################################################################ # nxflat/Makefile # -# Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2009, 2012-2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(TOPDIR)$(DELIM)sched"} BINFMT_ASRCS = BINFMT_CSRCS = binfmt_globals.c binfmt_register.c binfmt_unregister.c BINFMT_CSRCS += binfmt_loadmodule.c binfmt_unloadmodule.c binfmt_execmodule.c -BINFMT_CSRCS += binfmt_exec.c binfmt_dumpmodule.c +BINFMT_CSRCS += binfmt_exec.c binfmt_copyargv.c binfmt_dumpmodule.c ifeq ($(CONFIG_BINFMT_EXEPATH),y) BINFMT_CSRCS += binfmt_exepath.c @@ -56,11 +56,6 @@ ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) BINFMT_CSRCS += binfmt_schedunload.c endif -# Symbol table source files - -BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c -BINFMT_CSRCS += symtab_findorderedbyname.c symtab_findorderedbyvalue.c - ifeq ($(CONFIG_LIBC_EXECFUNCS),y) BINFMT_CSRCS += binfmt_execsymtab.c endif diff --git a/binfmt/binfmt_internal.h b/binfmt/binfmt.h similarity index 82% rename from binfmt/binfmt_internal.h rename to binfmt/binfmt.h index 184263183ced4dc28d0324306846c0f5f4f7436a..370ef57eaebcabe67c62a976163e8c0983a0fff5 100644 --- a/binfmt/binfmt_internal.h +++ b/binfmt/binfmt.h @@ -1,5 +1,5 @@ /**************************************************************************** - * binfmt/binfmt_internal.h + * binfmt/binfmt.h * * Copyright (C) 2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __BINFMT_BINFMT_INTERNAL_H -#define __BINFMT_BINFMT_INTERNAL_H +#ifndef __BINFMT_BINFMT_H +#define __BINFMT_BINFMT_H /**************************************************************************** * Included Files @@ -68,9 +68,9 @@ extern "C" EXTERN FAR struct binfmt_s *g_binfmts; -/*********************************************************************** +/**************************************************************************** * Public Function Prototypes - ***********************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: dump_module @@ -92,6 +92,26 @@ int dump_module(FAR const struct binary_s *bin); # define dump_module(bin) #endif +/**************************************************************************** + * Name: binfmt_copyargv + * + * Description: + * In the kernel build, the argv list will likely lie in the caller's + * address environment and, hence, by inaccessible when we swith to the + * address environment of the new process address environment. So we + * do not have any real option other than to copy the callers argv[] list. + * + * Input Parameter: + * bin - Load structure + * argv - Argument list + * + * Returned Value: + * Zero (OK) on sucess; a negater erro value on failure. + * + ****************************************************************************/ + +int binfmt_copyargv(FAR struct binary_s *bin, FAR char * const *argv); + /**************************************************************************** * Name: binfmt_freeargv * @@ -117,5 +137,5 @@ void binfmt_freeargv(FAR struct binary_s *bin); } #endif -#endif /* __BINFMT_BINFMT_INTERNAL_H */ +#endif /* __BINFMT_BINFMT_H */ diff --git a/binfmt/binfmt_copyargv.c b/binfmt/binfmt_copyargv.c new file mode 100644 index 0000000000000000000000000000000000000000..2fee46d047d460aba7f739efc4b2f59a9ddc876b --- /dev/null +++ b/binfmt/binfmt_copyargv.c @@ -0,0 +1,197 @@ +/**************************************************************************** + * binfmt/binfmt_copyargv.c + * + * Copyright (C) 2009, 2013-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "binfmt.h" + +#ifndef CONFIG_BINFMT_DISABLE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* This is an artificial limit to detect error conditions where an argv[] + * list is not properly terminated. + */ + +#define MAX_EXEC_ARGS 256 + +/**************************************************************************** + * Public Function + ****************************************************************************/ + +/**************************************************************************** + * Name: binfmt_copyargv + * + * Description: + * In the kernel build, the argv list will likely lie in the caller's + * address environment and, hence, by inaccessible when we switch to the + * address environment of the new process address environment. So we + * do not have any real option other than to copy the callers argv[] list. + * + * Input Parameter: + * bin - Load structure + * argv - Argument list + * + * Returned Value: + * Zero (OK) on sucess; a negater erro value on failure. + * + ****************************************************************************/ + +int binfmt_copyargv(FAR struct binary_s *bin, FAR char * const *argv) +{ +#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) + FAR char *ptr; + size_t argvsize; + size_t argsize; + int nargs; + int i; + + /* Get the number of arguments and the size of the argument list */ + + bin->argv = (FAR char **)NULL; + bin->argbuffer = (FAR char *)NULL; + + if (argv) + { + argsize = 0; + nargs = 0; + + for (i = 0; argv[i]; i++) + { + /* Increment the size of the allocation with the size of the next string */ + + argsize += (strlen(argv[i]) + 1); + nargs++; + + /* This is a sanity check to prevent running away with an unterminated + * argv[] list. MAX_EXEC_ARGS should be sufficiently large that this + * never happens in normal usage. + */ + + if (nargs > MAX_EXEC_ARGS) + { + bdbg("ERROR: Too many arguments: %lu\n", (unsigned long)argvsize); + return -E2BIG; + } + } + + bvdbg("args=%d argsize=%lu\n", nargs, (unsigned long)argsize); + + /* Allocate the argv array and an argument buffer */ + + if (argsize > 0) + { + argvsize = (nargs + 1) * sizeof(FAR char *); + bin->argbuffer = (FAR char *)kmm_malloc(argvsize + argsize); + if (!bin->argbuffer) + { + bdbg("ERROR: Failed to allocate the argument buffer\n"); + return -ENOMEM; + } + + /* Copy the argv list */ + + bin->argv = (FAR char **)bin->argbuffer; + ptr = bin->argbuffer + argvsize; + for (i = 0; argv[i]; i++) + { + bin->argv[i] = ptr; + argsize = strlen(argv[i]) + 1; + memcpy(ptr, argv[i], argsize); + ptr += argsize; + } + + /* Terminate the argv[] list */ + + bin->argv[i] = (FAR char *)NULL; + } + } + + return OK; + +#else + /* Just save the caller's argv pointer */ + + bin->argv = argv; + return OK; +#endif +} + +/**************************************************************************** + * Name: binfmt_freeargv + * + * Description: + * Release the copied argv[] list. + * + * Input Parameter: + * binp - Load structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) +void binfmt_freeargv(FAR struct binary_s *binp) +{ + /* Is there an allocated argument buffer */ + + if (binp->argbuffer) + { + /* Free the argument buffer */ + + kmm_free(binp->argbuffer); + } + + /* Nullify the allocated argv[] array and the argument buffer pointers */ + + binp->argbuffer = (FAR char *)NULL; + binp->argv = (FAR char **)NULL; +} +#endif + +#endif /* !CONFIG_BINFMT_DISABLE */ diff --git a/binfmt/binfmt_dumpmodule.c b/binfmt/binfmt_dumpmodule.c index 8fec9adb7e0c870b9fccb1f21d0f57edf48ac360..c69fed83c4398b844364bf8150c09c74f7e082c6 100644 --- a/binfmt/binfmt_dumpmodule.c +++ b/binfmt/binfmt_dumpmodule.c @@ -45,7 +45,7 @@ #include -#include "binfmt_internal.h" +#include "binfmt.h" #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT) && !defined(CONFIG_BINFMT_DISABLE) @@ -65,11 +65,11 @@ * Private Functions ****************************************************************************/ -/*********************************************************************** +/**************************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ -/*********************************************************************** +/**************************************************************************** * Name: dump_module * * Description: @@ -80,7 +80,7 @@ * 0 (OK) is returned on success and a negated errno is returned on * failure. * - ***********************************************************************/ + ****************************************************************************/ int dump_module(FAR const struct binary_s *bin) { diff --git a/binfmt/binfmt_exec.c b/binfmt/binfmt_exec.c index 3f866fe99a0633f04dab55fd4637e1d517b4b3b9..f3f62027ebfb7cc564330b4f46ed868c60910ba1 100644 --- a/binfmt/binfmt_exec.c +++ b/binfmt/binfmt_exec.c @@ -46,129 +46,10 @@ #include #include -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* This is an artificial limit to detect error conditions where an argv[] - * list is not properly terminated. - */ - -#define MAX_EXEC_ARGS 256 - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: binfmt_copyargv - * - * Description: - * In the kernel build, the argv list will likely lie in the caller's - * address environment and, hence, by inaccessible when we swith to the - * address environment of the new process address environment. So we - * do not have any real option other than to copy the callers argv[] list. - * - * Input Parameter: - * bin - Load structure - * argv - Argument list - * - * Returned Value: - * Zero (OK) on sucess; a negater erro value on failure. - * - ****************************************************************************/ - -static inline int binfmt_copyargv(FAR struct binary_s *bin, FAR char * const *argv) -{ -#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) - FAR char *ptr; - size_t argvsize; - size_t argsize; - int nargs; - int i; - - /* Get the number of arguments and the size of the argument list */ - - bin->argv = (FAR char **)NULL; - bin->argbuffer = (FAR char *)NULL; - - if (argv) - { - argsize = 0; - nargs = 0; - - for (i = 0; argv[i]; i++) - { - /* Increment the size of the allocation with the size of the next string */ - - argsize += (strlen(argv[i]) + 1); - nargs++; - - /* This is a sanity check to prevent running away with an unterminated - * argv[] list. MAX_EXEC_ARGS should be sufficiently large that this - * never happens in normal usage. - */ - - if (nargs > MAX_EXEC_ARGS) - { - bdbg("ERROR: Too many arguments: %lu\n", (unsigned long)argvsize); - return -E2BIG; - } - } - - bvdbg("args=%d argsize=%lu\n", nargs, (unsigned long)argsize); - - /* Allocate the argv array and an argument buffer */ - - if (argsize > 0) - { - argvsize = (nargs + 1) * sizeof(FAR char *); - bin->argbuffer = (FAR char *)kmm_malloc(argvsize + argsize); - if (!bin->argbuffer) - { - bdbg("ERROR: Failed to allocate the argument buffer\n"); - return -ENOMEM; - } - - /* Copy the argv list */ - - bin->argv = (FAR char **)bin->argbuffer; - ptr = bin->argbuffer + argvsize; - for (i = 0; argv[i]; i++) - { - bin->argv[i] = ptr; - argsize = strlen(argv[i]) + 1; - memcpy(ptr, argv[i], argsize); - ptr += argsize; - } - - /* Terminate the argv[] list */ - - bin->argv[i] = (FAR char *)NULL; - } - } - - return OK; - -#else - /* Just save the caller's argv pointer */ - - bin->argv = argv; - return OK; -#endif -} - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index ccc20063cb02e560b0c19aad416f135b534a14c2..971c47123cce10c1b8f0477b99c1ca9141bcc800 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -53,7 +53,7 @@ #include #include "sched/sched.h" -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE @@ -159,7 +159,7 @@ int exec_module(FAR const struct binary_s *binp) /* Allocate a TCB for the new task. */ - tcb = (FAR struct task_tcb_s*)kmm_zalloc(sizeof(struct task_tcb_s)); + tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s)); if (!tcb) { err = ENOMEM; @@ -189,7 +189,7 @@ int exec_module(FAR const struct binary_s *binp) * will need to change if/when we want to support dynamic stack allocation. */ - stack = (FAR uint32_t*)kumm_malloc(binp->stacksize); + stack = (FAR uint32_t *)kumm_malloc(binp->stacksize); if (!stack) { err = ENOMEM; diff --git a/binfmt/binfmt_execsymtab.c b/binfmt/binfmt_execsymtab.c index 63fa14adb2bcf852b31125fb31be6ce0ff196f9f..09a36bfce7aaa7319323933f0468518144974355 100644 --- a/binfmt/binfmt_execsymtab.c +++ b/binfmt/binfmt_execsymtab.c @@ -1,7 +1,7 @@ /**************************************************************************** * binfmt/binfmt_execsymtab.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include +#include #include #include @@ -68,7 +69,7 @@ #endif /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef CONFIG_EXECFUNCS_HAVE_SYMTAB @@ -116,10 +117,10 @@ void exec_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols) * size are returned as a single atomic operation. */ - flags = irqsave(); + flags = enter_critical_section(); *symtab = g_exec_symtab; *nsymbols = g_exec_nsymbols; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -147,10 +148,10 @@ void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols) * size are set as a single atomic operation. */ - flags = irqsave(); + flags = enter_critical_section(); g_exec_symtab = symtab; g_exec_nsymbols = nsymbols; - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_LIBC_EXECFUNCS */ \ No newline at end of file diff --git a/binfmt/binfmt_exepath.c b/binfmt/binfmt_exepath.c index 1e05d55f3bc3c7afb3367be1e64035e33c0b3bc4..c99ae8706a1c0533922424b74fa12c002dd54601 100644 --- a/binfmt/binfmt_exepath.c +++ b/binfmt/binfmt_exepath.c @@ -142,7 +142,7 @@ EXEPATH_HANDLE exepath_init(void) return (EXEPATH_HANDLE)exepath; } - /**************************************************************************** +/**************************************************************************** * Name: exepath_next * * Description: @@ -190,7 +190,7 @@ FAR char *exepath_next(EXEPATH_HANDLE handle, FAR const char *relpath) * in the PATH variable have been considered. */ - for (;;) + for (; ; ) { /* Make sure that exepath->next points to the beginning of a string */ @@ -244,7 +244,7 @@ FAR char *exepath_next(EXEPATH_HANDLE handle, FAR const char *relpath) /* Verify that a regular file exists at this path */ - ret = stat(fullpath, &buf);; + ret = stat(fullpath, &buf); if (ret == OK && S_ISREG(buf.st_mode)) { return fullpath; diff --git a/binfmt/binfmt_loadmodule.c b/binfmt/binfmt_loadmodule.c index 83868460a6d7355c3932027ea0b85cb65e0d8537..1b614838e6afb59fe4f9565397d5906b3a45cac3 100644 --- a/binfmt/binfmt_loadmodule.c +++ b/binfmt/binfmt_loadmodule.c @@ -46,7 +46,7 @@ #include #include -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE diff --git a/binfmt/binfmt_register.c b/binfmt/binfmt_register.c index 925f29353fd36a076e507062f16b0a4239f5c63f..48ddfc1daab9160fb3023e681cc747352b50f0db 100644 --- a/binfmt/binfmt_register.c +++ b/binfmt/binfmt_register.c @@ -46,7 +46,7 @@ #include -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE diff --git a/binfmt/binfmt_schedunload.c b/binfmt/binfmt_schedunload.c index 3d897953df6f2e814351a7046956903df84eb2ea..f9da1349f6b96688f47315b30567c0cbf4ef4498 100644 --- a/binfmt/binfmt_schedunload.c +++ b/binfmt/binfmt_schedunload.c @@ -1,7 +1,7 @@ /**************************************************************************** * binfmt/binfmt_schedunload.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,10 +43,11 @@ #include #include +#include #include #include -#include "binfmt_internal.h" +#include "binfmt.h" #if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_SCHED_HAVE_PARENT) @@ -84,7 +85,7 @@ FAR struct binary_s *g_unloadhead; * pid - The task ID of the child task * bin - This structure must have been allocated with kmm_malloc() and must * persist until the task unloads - + * * * Returned Value: * None @@ -105,10 +106,10 @@ static void unload_list_add(pid_t pid, FAR struct binary_s *bin) * interrupts. */ - flags = irqsave(); + flags = enter_critical_section(); bin->flink = g_unloadhead; g_unloadhead = bin; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -313,13 +314,13 @@ int schedule_unload(pid_t pid, FAR struct binary_s *bin) /* Emergency removal from the list */ - flags = irqsave(); + flags = enter_critical_section(); if (unload_list_remove(pid) != bin) { blldbg("ERROR: Failed to remove structure\n"); } - irqrestore(flags); + leave_critical_section(flags); goto errout; } diff --git a/binfmt/binfmt_unloadmodule.c b/binfmt/binfmt_unloadmodule.c index 535942b0f6e2f757c0f3c0c873b1fa39f94d6573..887d6d66c09a84aad65f2d533bf0c9e2af4e7311 100644 --- a/binfmt/binfmt_unloadmodule.c +++ b/binfmt/binfmt_unloadmodule.c @@ -48,7 +48,7 @@ #include #include -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE @@ -211,38 +211,5 @@ int unload_module(FAR struct binary_s *binp) return OK; } -/**************************************************************************** - * Name: binfmt_freeargv - * - * Description: - * Release the copied argv[] list. - * - * Input Parameter: - * binp - Load structure - * - * Returned Value: - * None - * - ****************************************************************************/ - -#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) -void binfmt_freeargv(FAR struct binary_s *binp) -{ - /* Is there an allocated argument buffer */ - - if (binp->argbuffer) - { - /* Free the argument buffer */ - - kmm_free(binp->argbuffer); - } - - /* Nullify the allocated argv[] array and the argument buffer pointers */ - - binp->argbuffer = (FAR char *)NULL; - binp->argv = (FAR char **)NULL; -} -#endif - #endif /* CONFIG_BINFMT_DISABLE */ diff --git a/binfmt/binfmt_unregister.c b/binfmt/binfmt_unregister.c index f895e354d07dc37b04c90bfdba5bfdffd1639785..f97b06ff2da702ee26af72c61d1b9015d3fbe095 100644 --- a/binfmt/binfmt_unregister.c +++ b/binfmt/binfmt_unregister.c @@ -46,7 +46,7 @@ #include -#include "binfmt_internal.h" +#include "binfmt.h" #ifndef CONFIG_BINFMT_DISABLE diff --git a/binfmt/builtin.c b/binfmt/builtin.c index 4e6b18c9c4b3292734f8b287b68cd0681bebaf68..537556136b65b956e2b119e691841304025d2606 100644 --- a/binfmt/builtin.c +++ b/binfmt/builtin.c @@ -116,6 +116,7 @@ static int builtin_loadbinary(struct binary_s *binp) { int errval = get_errno(); bdbg("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval); + close(fd); return -errval; } @@ -128,6 +129,7 @@ static int builtin_loadbinary(struct binary_s *binp) { int errval = get_errno(); bdbg("ERROR: %s is not a builtin application\n", filename); + close(fd); return -errval; } @@ -140,6 +142,7 @@ static int builtin_loadbinary(struct binary_s *binp) binp->entrypt = b->main; binp->stacksize = b->stacksize; binp->priority = b->priority; + close(fd); return OK; } diff --git a/binfmt/elf.c b/binfmt/elf.c index 2cb18fe91917f7fe42850cb9e49556371e60ca01..7291389ebade37dbbcddd933ccfcd75cdef41df3 100644 --- a/binfmt/elf.c +++ b/binfmt/elf.c @@ -198,7 +198,7 @@ static void elf_dumpentrypt(FAR struct binary_s *binp, } #endif - elf_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt, + elf_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt, MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); #ifdef CONFIG_ARCH_ADDRENV diff --git a/binfmt/libelf/libelf.h b/binfmt/libelf/libelf.h index 58ec757b8d542c90fc35780cabed5de23e9fc962..a61f38017a9795827704ed17f8ff100ecd3ee02f 100644 --- a/binfmt/libelf/libelf.h +++ b/binfmt/libelf/libelf.h @@ -49,11 +49,7 @@ #include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** diff --git a/binfmt/libelf/libelf_bind.c b/binfmt/libelf/libelf_bind.c index 59782bb1ca8f9743be15eaca65dad84cce371128..a4fd589613bc1d222acefb27f04e1c7b37f35d6c 100644 --- a/binfmt/libelf/libelf_bind.c +++ b/binfmt/libelf/libelf_bind.c @@ -113,7 +113,7 @@ static inline int elf_readrel(FAR struct elf_loadinfo_s *loadinfo, /* And, finally, read the symbol table entry into memory */ - return elf_read(loadinfo, (FAR uint8_t*)rel, sizeof(Elf32_Rel), offset); + return elf_read(loadinfo, (FAR uint8_t *)rel, sizeof(Elf32_Rel), offset); } /**************************************************************************** diff --git a/binfmt/libelf/libelf_ctors.c b/binfmt/libelf/libelf_ctors.c index 11d6b8810b1a4d8aabf47272e9f4c4f91047365b..95f3884135f67bc6aae2b6a92ff7cf72baf82eb3 100644 --- a/binfmt/libelf/libelf_ctors.c +++ b/binfmt/libelf/libelf_ctors.c @@ -163,7 +163,7 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo) { /* Allocate memory to hold a copy of the .ctor section */ - loadinfo->ctoralloc = (binfmt_ctor_t*)kumm_malloc(ctorsize); + loadinfo->ctoralloc = (binfmt_ctor_t *)kumm_malloc(ctorsize); if (!loadinfo->ctoralloc) { bdbg("Failed to allocate memory for .ctors\n"); @@ -174,7 +174,7 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo) /* Read the section header table into memory */ - ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->ctors, ctorsize, + ret = elf_read(loadinfo, (FAR uint8_t *)loadinfo->ctors, ctorsize, shdr->sh_offset); if (ret < 0) { @@ -206,7 +206,7 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo) * will be relocated via the normal mechanism. */ - loadinfo->ctors = (binfmt_ctor_t*)shdr->sh_addr; + loadinfo->ctors = (binfmt_ctor_t *)shdr->sh_addr; } } diff --git a/binfmt/libelf/libelf_dtors.c b/binfmt/libelf/libelf_dtors.c index d268ab1e268b9ca3c6bd9e8accc3d32a03a11c25..1f4cdab7e3e27cf673f4bf90e05f2c51d34f67b1 100644 --- a/binfmt/libelf/libelf_dtors.c +++ b/binfmt/libelf/libelf_dtors.c @@ -163,7 +163,7 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo) { /* Allocate memory to hold a copy of the .dtor section */ - loadinfo->ctoralloc = (binfmt_dtor_t*)kumm_malloc(dtorsize); + loadinfo->ctoralloc = (binfmt_dtor_t *)kumm_malloc(dtorsize); if (!loadinfo->ctoralloc) { bdbg("Failed to allocate memory for .dtors\n"); @@ -174,7 +174,7 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo) /* Read the section header table into memory */ - ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->dtors, dtorsize, + ret = elf_read(loadinfo, (FAR uint8_t *)loadinfo->dtors, dtorsize, shdr->sh_offset); if (ret < 0) { @@ -206,7 +206,7 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo) * will be relocated via the normal mechanism. */ - loadinfo->dtors = (binfmt_dtor_t*)shdr->sh_addr; + loadinfo->dtors = (binfmt_dtor_t *)shdr->sh_addr; } } diff --git a/binfmt/libelf/libelf_init.c b/binfmt/libelf/libelf_init.c index 2ba84bfefdaf21bce855bdbc6a96d1c81f3ee42e..35414fca18371ada5ae84427e64863da73e52144 100644 --- a/binfmt/libelf/libelf_init.c +++ b/binfmt/libelf/libelf_init.c @@ -172,19 +172,19 @@ int elf_init(FAR const char *filename, FAR struct elf_loadinfo_s *loadinfo) /* Read the ELF ehdr from offset 0 */ - ret = elf_read(loadinfo, (FAR uint8_t*)&loadinfo->ehdr, sizeof(Elf32_Ehdr), 0); + ret = elf_read(loadinfo, (FAR uint8_t *)&loadinfo->ehdr, sizeof(Elf32_Ehdr), 0); if (ret < 0) { bdbg("Failed to read ELF header: %d\n", ret); return ret; } - elf_dumpbuffer("ELF header", (FAR const uint8_t*)&loadinfo->ehdr, sizeof(Elf32_Ehdr)); + elf_dumpbuffer("ELF header", (FAR const uint8_t *)&loadinfo->ehdr, sizeof(Elf32_Ehdr)); /* Verify the ELF header */ ret = elf_verifyheader(&loadinfo->ehdr); - if (ret <0) + if (ret < 0) { /* This may not be an error because we will be called to attempt loading * EVERY binary. If elf_verifyheader() does not recognize the ELF header, diff --git a/binfmt/libelf/libelf_load.c b/binfmt/libelf/libelf_load.c index c81be5c196d703848b83f1417e0f83e206222f84..b5cef6c6e9c6ac25a88d92e568384cc548338c8d 100644 --- a/binfmt/libelf/libelf_load.c +++ b/binfmt/libelf/libelf_load.c @@ -157,8 +157,8 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo) /* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */ bvdbg("Loaded sections:\n"); - text = (FAR uint8_t*)loadinfo->textalloc; - data = (FAR uint8_t*)loadinfo->dataalloc; + text = (FAR uint8_t *)loadinfo->textalloc; + data = (FAR uint8_t *)loadinfo->dataalloc; for (i = 0; i < loadinfo->ehdr.e_shnum; i++) { diff --git a/binfmt/libelf/libelf_read.c b/binfmt/libelf/libelf_read.c index dacd52347b45a00aa8ba01d588f609f65a59c4de..420c8f1808932c39f72164d98b7ad0976cd95ba0 100644 --- a/binfmt/libelf/libelf_read.c +++ b/binfmt/libelf/libelf_read.c @@ -68,9 +68,9 @@ ****************************************************************************/ #if defined(ELF_DUMP_READDATA) -static inline void elf_dumpreaddata(char *buffer, int buflen) +static inline void elf_dumpreaddata(FAR char *buffer, int buflen) { - uint32_t *buf32 = (uint32_t*)buffer; + FAR uint32_t *buf32 = (FAR uint32_t *)buffer; int i; int j; diff --git a/binfmt/libelf/libelf_sections.c b/binfmt/libelf/libelf_sections.c index 7aeff5a9e98c7fd1ba97f2dab24e437ceb1dc204..26189d72479788c3679de5e6cfef4e227b6a5964 100644 --- a/binfmt/libelf/libelf_sections.c +++ b/binfmt/libelf/libelf_sections.c @@ -117,7 +117,7 @@ static inline int elf_sectname(FAR struct elf_loadinfo_s *loadinfo, buffer = loadinfo->iobuffer; bytesread = 0; - for (;;) + for (; ; ) { /* Get the number of bytes to read */ @@ -211,16 +211,18 @@ int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo) /* Allocate memory to hold a working copy of the sector header table */ - loadinfo->shdr = (FAR Elf32_Shdr*)kmm_malloc(shdrsize); + loadinfo->shdr = (FAR FAR Elf32_Shdr *)kmm_malloc(shdrsize); if (!loadinfo->shdr) { - bdbg("Failed to allocate the section header table. Size: %ld\n", (long)shdrsize); + bdbg("Failed to allocate the section header table. Size: %ld\n", + (long)shdrsize); return -ENOMEM; } /* Read the section header table into memory */ - ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->shdr, shdrsize, loadinfo->ehdr.e_shoff); + ret = elf_read(loadinfo, (FAR uint8_t *)loadinfo->shdr, shdrsize, + loadinfo->ehdr.e_shoff); if (ret < 0) { bdbg("Failed to read section header table: %d\n", ret); diff --git a/binfmt/libelf/libelf_symbols.c b/binfmt/libelf/libelf_symbols.c index c2be4d193da007f7d413d98510e91a4efdb1a067..17694815585b72ce7f6d63944cd7dc3b3789d606 100644 --- a/binfmt/libelf/libelf_symbols.c +++ b/binfmt/libelf/libelf_symbols.c @@ -107,7 +107,7 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo, bytesread = 0; - for (;;) + for (; ; ) { /* Get the number of bytes to read */ @@ -239,7 +239,7 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index, /* And, finally, read the symbol table entry into memory */ - return elf_read(loadinfo, (FAR uint8_t*)sym, sizeof(Elf32_Sym), offset); + return elf_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf32_Sym), offset); } /**************************************************************************** diff --git a/binfmt/libelf/libelf_verify.c b/binfmt/libelf/libelf_verify.c index ee6c880f673906695155a23a05605ba3e893b406..015d9d39fe191d0ad9bd2b1c7f27e9b637c81db7 100644 --- a/binfmt/libelf/libelf_verify.c +++ b/binfmt/libelf/libelf_verify.c @@ -53,7 +53,10 @@ * Private Constant Data ****************************************************************************/ -static const char g_elfmagic[EI_MAGIC_SIZE] = { 0x7f, 'E', 'L', 'F' }; +static const char g_elfmagic[EI_MAGIC_SIZE] = +{ + 0x7f, 'E', 'L', 'F' +}; /**************************************************************************** * Private Functions diff --git a/binfmt/libnxflat/libnxflat_bind.c b/binfmt/libnxflat/libnxflat_bind.c index dfb1e911cc6c401d59e4aa316bd796bb5963ebe8..3c1709b2a5be2ee0bbb0a00debbf6fed82d3abaa 100644 --- a/binfmt/libnxflat/libnxflat_bind.c +++ b/binfmt/libnxflat/libnxflat_bind.c @@ -102,14 +102,14 @@ static inline int nxflat_bindrel32i(FAR struct nxflat_loadinfo_s *loadinfo, uint32_t offset) { - uint32_t *addr; + FAR uint32_t *addr; bvdbg("NXFLAT_RELOC_TYPE_REL32I Offset: %08x I-Space: %p\n", offset, loadinfo->ispace + sizeof(struct nxflat_hdr_s)); if (offset < loadinfo->dsize) { - addr = (uint32_t*)(offset + loadinfo->dspace->region); + addr = (FAR uint32_t *)(offset + loadinfo->dspace->region); bvdbg(" Before: %08x\n", *addr); *addr += (uint32_t)(loadinfo->ispace + sizeof(struct nxflat_hdr_s)); bvdbg(" After: %08x\n", *addr); @@ -141,14 +141,14 @@ static inline int nxflat_bindrel32i(FAR struct nxflat_loadinfo_s *loadinfo, static inline int nxflat_bindrel32d(FAR struct nxflat_loadinfo_s *loadinfo, uint32_t offset) { - uint32_t *addr; + FAR uint32_t *addr; bvdbg("NXFLAT_RELOC_TYPE_REL32D Offset: %08x D-Space: %p\n", offset, loadinfo->dspace->region); if (offset < loadinfo->dsize) { - addr = (uint32_t*)(offset + loadinfo->dspace->region); + addr = (FAR uint32_t *)(offset + loadinfo->dspace->region); bvdbg(" Before: %08x\n", *addr); *addr += (uint32_t)(loadinfo->dspace->region); bvdbg(" After: %08x\n", *addr); @@ -183,14 +183,14 @@ static inline int nxflat_bindrel32d(FAR struct nxflat_loadinfo_s *loadinfo, static inline int nxflat_bindrel32id(FAR struct nxflat_loadinfo_s *loadinfo, uint32_t offset) { - uint32_t *addr; + FAR uint32_t *addr; bvdbg("NXFLAT_RELOC_TYPE_REL32D Offset: %08x D-Space: %p\n", offset, loadinfo->dspace->region); if (offset < loadinfo->dsize) { - addr = (uint32_t*)(offset + loadinfo->dspace->region); + addr = (FAR uint32_t *)(offset + loadinfo->dspace->region); bvdbg(" Before: %08x\n", *addr); *addr += ((uint32_t)loadinfo->ispace - (uint32_t)(loadinfo->dspace->region)); bvdbg(" After: %08x\n", *addr); @@ -231,7 +231,7 @@ static inline int nxflat_gotrelocs(FAR struct nxflat_loadinfo_s *loadinfo) /* The NXFLAT header is the first thing at the beginning of the ISpace. */ - hdr = (FAR struct nxflat_hdr_s*)loadinfo->ispace; + hdr = (FAR struct nxflat_hdr_s *)loadinfo->ispace; /* From this, we can get the offset to the list of relocation entries */ @@ -348,8 +348,8 @@ static inline int nxflat_gotrelocs(FAR struct nxflat_loadinfo_s *loadinfo) #ifdef CONFIG_NXFLAT_DUMPBUFFER if (ret == OK && nrelocs > 0) { - relocs = (FAR struct nxflat_reloc_s*)(offset - loadinfo->isize + loadinfo->dspace->region); - nxflat_dumpbuffer("GOT", (FAR const uint8_t*)relocs, nrelocs * sizeof(struct nxflat_reloc_s)); + relocs = (FAR struct nxflat_reloc_s *)(offset - loadinfo->isize + loadinfo->dspace->region); + nxflat_dumpbuffer("GOT", (FAR const uint8_t *)relocs, nrelocs * sizeof(struct nxflat_reloc_s)); } #endif @@ -397,7 +397,7 @@ static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo, /* The NXFLAT header is the first thing at the beginning of the ISpace. */ - hdr = (FAR struct nxflat_hdr_s*)loadinfo->ispace; + hdr = (FAR struct nxflat_hdr_s *)loadinfo->ispace; /* From this, we can get the offset to the list of symbols imported by * this module and the number of symbols imported by this module. @@ -440,7 +440,7 @@ static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo, DEBUGASSERT(offset >= loadinfo->isize && offset < loadinfo->isize + loadinfo->dsize); - imports = (struct nxflat_import_s*) + imports = (FAR struct nxflat_import_s *) (offset - loadinfo->isize + loadinfo->dspace->region); /* Now, traverse the list of imported symbols and attempt to bind @@ -462,7 +462,7 @@ static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo, offset = imports[i].i_funcname; DEBUGASSERT(offset < loadinfo->isize); - symname = (char*)(offset + loadinfo->ispace + sizeof(struct nxflat_hdr_s)); + symname = (FAR char *)(offset + loadinfo->ispace + sizeof(struct nxflat_hdr_s)); /* Find the exported symbol value for this this symbol name. */ @@ -494,7 +494,7 @@ static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo, #ifdef CONFIG_NXFLAT_DUMPBUFFER if (nimports > 0) { - nxflat_dumpbuffer("Imports", (FAR const uint8_t*)imports, nimports * sizeof(struct nxflat_import_s)); + nxflat_dumpbuffer("Imports", (FAR const uint8_t *)imports, nimports * sizeof(struct nxflat_import_s)); } #endif @@ -549,7 +549,7 @@ static inline int nxflat_clearbss(FAR struct nxflat_loadinfo_s *loadinfo) /* Zero the BSS area */ - memset((void*)(loadinfo->dspace->region + loadinfo->datasize), 0, + memset((FAR void *)(loadinfo->dspace->region + loadinfo->datasize), 0, loadinfo->bsssize); /* Restore the original address environment */ diff --git a/binfmt/libnxflat/libnxflat_init.c b/binfmt/libnxflat/libnxflat_init.c index 2057a18358014525e7e65562c01cd9e3e65414b9..52159c5f03199c9f29c4903c88cab884fb3c07df 100644 --- a/binfmt/libnxflat/libnxflat_init.c +++ b/binfmt/libnxflat/libnxflat_init.c @@ -118,14 +118,15 @@ int nxflat_init(const char *filename, struct nxflat_loadinfo_s *loadinfo) /* Read the NXFLAT header from offset 0 */ - ret = nxflat_read(loadinfo, (char*)&loadinfo->header, + ret = nxflat_read(loadinfo, (FAR char *)&loadinfo->header, sizeof(struct nxflat_hdr_s), 0); if (ret < 0) { bdbg("Failed to read NXFLAT header: %d\n", ret); return ret; } - nxflat_dumpbuffer("NXFLAT header", (FAR const uint8_t*)&loadinfo->header, + + nxflat_dumpbuffer("NXFLAT header", (FAR const uint8_t *)&loadinfo->header, sizeof(struct nxflat_hdr_s)); /* Verify the NXFLAT header */ diff --git a/binfmt/libnxflat/libnxflat_load.c b/binfmt/libnxflat/libnxflat_load.c index 663953ea274ac63a1b2430bab757ef15995dccb1..a3e49d3ce1d245f7397759dcc6bd548ff233cd9d 100644 --- a/binfmt/libnxflat/libnxflat_load.c +++ b/binfmt/libnxflat/libnxflat_load.c @@ -147,7 +147,7 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo) */ loadinfo->ispace = (uint32_t)mmap(NULL, loadinfo->isize, PROT_READ, - MAP_SHARED|MAP_FILE, loadinfo->filfd, 0); + MAP_SHARED | MAP_FILE, loadinfo->filfd, 0); if (loadinfo->ispace == (uint32_t)MAP_FAILED) { bdbg("Failed to map NXFLAT ISpace: %d\n", errno); @@ -189,7 +189,8 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo) * DSpace memory. */ - ret = nxflat_read(loadinfo, (char*)loadinfo->dspace->region, dreadsize, doffset); + ret = nxflat_read(loadinfo, (FAR char *)loadinfo->dspace->region, + dreadsize, doffset); if (ret < 0) { bdbg("Failed to read .data section: %d\n", ret); diff --git a/binfmt/libnxflat/libnxflat_read.c b/binfmt/libnxflat/libnxflat_read.c index 3257945bedbe2c2b0df14ca6173cc80d519d3214..023b7c07e4f8d07c54f263d6891a98dd0506ce1f 100644 --- a/binfmt/libnxflat/libnxflat_read.c +++ b/binfmt/libnxflat/libnxflat_read.c @@ -69,9 +69,9 @@ ****************************************************************************/ #if defined(NXFLAT_DUMP_READDATA) -static inline void nxflat_dumpreaddata(char *buffer, int buflen) +static inline void nxflat_dumpreaddata(FAR char *buffer, int buflen) { - uint32_t *buf32 = (uint32_t*)buffer; + FAR uint32_t *buf32 = (FAR uint32_t *)buffer; int i; int j; diff --git a/binfmt/libnxflat/libnxflat_unload.c b/binfmt/libnxflat/libnxflat_unload.c index 08b1f44f35ea6794b75923f298c668fc3f5fdf4a..7cca6f25f344b11b90670a593bd05f3265edff01 100644 --- a/binfmt/libnxflat/libnxflat_unload.c +++ b/binfmt/libnxflat/libnxflat_unload.c @@ -79,14 +79,14 @@ * ****************************************************************************/ -int nxflat_unload(struct nxflat_loadinfo_s *loadinfo) +int nxflat_unload(FAR struct nxflat_loadinfo_s *loadinfo) { /* Release the memory segments */ /* Release the I-Space mmap'ed file */ if (loadinfo->ispace) { - munmap((void*)loadinfo->ispace, loadinfo->isize); + munmap((FAR void *)loadinfo->ispace, loadinfo->isize); loadinfo->ispace = 0; } diff --git a/binfmt/libpcode/README.txt b/binfmt/libpcode/README.txt index 8f980ce1e9bf3a32730d9a0093dc4f08648c8060..d0bbb4ffc3c8c45f76bbec78ae16f17d28c35098 100644 --- a/binfmt/libpcode/README.txt +++ b/binfmt/libpcode/README.txt @@ -50,6 +50,8 @@ Files include in this directory include: xxd -g 1 -i romfs.img >romfs.h then cleaned up with an editor to conform with NuttX coding standards. + Also, the data definitions in the romfs.h file should be marked with + 'const' qualifier the so that the data will be stored in FLASH. Test Configuration ------------------ diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c index a839bbc07cbe50b2fe29c7ed392e21b15c16bb37..1c4b454ff99a003142e619a39f82cac8ac8f6c8e 100644 --- a/binfmt/nxflat.c +++ b/binfmt/nxflat.c @@ -187,7 +187,7 @@ static int nxflat_loadbinary(struct binary_s *binp) */ binp->entrypt = (main_t)(loadinfo.ispace + loadinfo.entryoffs); - binp->mapped = (void*)loadinfo.ispace; + binp->mapped = (FAR void *)loadinfo.ispace; binp->mapsize = loadinfo.isize; binp->stacksize = loadinfo.stacksize; @@ -202,7 +202,7 @@ static int nxflat_loadbinary(struct binary_s *binp) #ifdef CONFIG_ARCH_ADDRENV # warning "REVISIT" #else - binp->alloc[0] = (void*)loadinfo.dspace; + binp->alloc[0] = (FAR void *)loadinfo.dspace; #endif #ifdef CONFIG_ARCH_ADDRENV @@ -213,7 +213,7 @@ static int nxflat_loadbinary(struct binary_s *binp) up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv); #endif - nxflat_dumpbuffer("Entry code", (FAR const uint8_t*)binp->entrypt, + nxflat_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt, MIN(loadinfo.isize - loadinfo.entryoffs, 512)); nxflat_uninit(&loadinfo); @@ -227,11 +227,11 @@ errout: return ret; } -/*********************************************************************** +/**************************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ -/*********************************************************************** +/**************************************************************************** * Name: nxflat_initialize * * Description: @@ -244,7 +244,7 @@ errout: * 0 (OK) is returned on success and a negated errno is returned on * failure. * - ***********************************************************************/ + ****************************************************************************/ int nxflat_initialize(void) { diff --git a/binfmt/pcode.c b/binfmt/pcode.c index a4423c6900dcd810ef25cf269d37a08f82f0c095..6023622440e0a23cf54000b6b38c068b89b4e8c8 100644 --- a/binfmt/pcode.c +++ b/binfmt/pcode.c @@ -352,7 +352,7 @@ static int pcode_load(struct binary_s *binp) { /* Set up for the next gulp */ - DEBUGASSERT(nread > 0 && nread <=remaining); + DEBUGASSERT(nread > 0 && nread <= remaining); remaining -= nread; ptr += nread; } diff --git a/configs b/configs index ac4035687c824bb4a573e06feb017cb4f3ce7626..f7c42ff4a006f5d37fa6a818aafaf20886309fd1 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit ac4035687c824bb4a573e06feb017cb4f3ce7626 +Subproject commit f7c42ff4a006f5d37fa6a818aafaf20886309fd1 diff --git a/crypto/Kconfig b/crypto/Kconfig index b23d23f56f023a2007d4a6165e390d66d85ac29d..022fce7a05125780c52302905a3e888f86ef3060 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -39,4 +39,15 @@ config CRYPTO_CRYPTODEV bool "cryptodev support" default n -endif +config CRYPTO_SW_AES + bool "Software AES library" + default n + ---help--- + Enable the software AES library as described in + include/nuttx/crypto/aes.h + + TODO: Adapt interfaces so that they are consistent with H/W AES + implemenations. This needs to support up_aesinitialize() and + aes_cypher() per include/nuttx/crypto/crypto.h. + +endif # CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index b3131531e83df38e308a5edf32d3559f0f206eb1..c56640534ef654f266bed052e9eea457a7e796db 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -35,33 +35,41 @@ -include $(TOPDIR)/Make.defs +CRYPTO_ASRCS = +CRYPTO_CSRCS = + ifeq ($(CONFIG_CRYPTO),y) # Basic -CRYPTO_ASRCS = -CRYPTO_CSRCS = crypto.c testmngr.c +CRYPTO_CSRCS += crypto.c testmngr.c # cryptodev support ifeq ($(CONFIG_CRYPTO_CRYPTODEV),y) -CRYPTO_CSRCS += cryptodev.c + CRYPTO_CSRCS += cryptodev.c +endif + +# Sofware AES library + +ifeq ($(CONFIG_CRYPTO_SW_AES),y) + CRYPTO_CSRCS += aes.c endif endif # CONFIG_CRYPTO -ASRCS = $(CRYPTO_ASRCS) -AOBJS = $(ASRCS:.S=$(OBJEXT)) +ASRCS = $(CRYPTO_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) -CSRCS = $(CRYPTO_CSRCS) -COBJS = $(CSRCS:.c=$(OBJEXT)) +CSRCS = $(CRYPTO_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) -SRCS = $(ASRCS) $(CSRCS) -OBJS = $(AOBJS) $(COBJS) +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) -BIN = libcrypto$(LIBEXT) +BIN = libcrypto$(LIBEXT) -all: $(BIN) +all: $(BIN) $(AOBJS): %$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) diff --git a/crypto/aes.c b/crypto/aes.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c638f71897da335aedfb16a2c82378a8f89175 --- /dev/null +++ b/crypto/aes.c @@ -0,0 +1,594 @@ +/**************************************************************************** + * crypto/aes.c + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Extracted from the CC3000 Host Driver Implementation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of Texas Instruments Incorporated 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. + * + ****************************************************************************/ + +/* TODO: Adapt interfaces so that they are consistent with H/W AES + * implemenations. This needs to support up_aesinitialize() and + * aes_cypher() per include/nuttx/crypto/crypto.h. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Forward sbox */ + +static const uint8_t g_sbox[256] = +{ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, /* 0 */ + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, /* 1 */ + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, /* 2 */ + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, /* 3 */ + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, /* 4 */ + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, /* 5 */ + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, /* 6 */ + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, /* 7 */ + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, /* 8 */ + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, /* 9 */ + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, /* A */ + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, /* B */ + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, /* C */ + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, /* D */ + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, /* E */ + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 /* F */ +}; + +/* Inverse sbox */ + +static const uint8_t g_rsbox[256] = +{ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +/* Round constant */ + +static const uint8_t g_rcon[11] = +{ + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +}; + +static uint8_t g_expanded_key[176]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: expand_key + * + * Description: + * Expend a 16 bytes key for AES128 implementation + * + * Input Parameters: + * key AES128 key - 16 bytes + * expanded_key expanded AES128 key + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void expand_key(FAR uint8_t *expanded_key, FAR const uint8_t *key) +{ + uint16_t buf1; + uint16_t ii; + + for (ii = 0; ii < 16; ii++) + { + expanded_key[ii] = key[ii]; + } + + for (ii = 1; ii < 11; ii++) + { + buf1 = expanded_key[ii*16 - 4]; + expanded_key[ii * 16 + 0] = g_sbox[expanded_key[ii *16 - 3]] ^ expanded_key[(ii - 1) * 16 + 0] ^ g_rcon[ii]; + expanded_key[ii * 16 + 1] = g_sbox[expanded_key[ii *16 - 2]] ^ expanded_key[(ii - 1) * 16 + 1]; + expanded_key[ii * 16 + 2] = g_sbox[expanded_key[ii *16 - 1]] ^ expanded_key[(ii - 1) * 16 + 2]; + expanded_key[ii * 16 + 3] = g_sbox[buf1] ^ expanded_key[(ii - 1) * 16 + 3]; + expanded_key[ii * 16 + 4] = expanded_key[(ii - 1) * 16 + 4] ^ expanded_key[ii * 16 + 0]; + expanded_key[ii * 16 + 5] = expanded_key[(ii - 1) * 16 + 5] ^ expanded_key[ii * 16 + 1]; + expanded_key[ii * 16 + 6] = expanded_key[(ii - 1) * 16 + 6] ^ expanded_key[ii * 16 + 2]; + expanded_key[ii * 16 + 7] = expanded_key[(ii - 1) * 16 + 7] ^ expanded_key[ii * 16 + 3]; + expanded_key[ii * 16 + 8] = expanded_key[(ii - 1) * 16 + 8] ^ expanded_key[ii * 16 + 4]; + expanded_key[ii * 16 + 9] = expanded_key[(ii - 1) * 16 + 9] ^ expanded_key[ii * 16 + 5]; + expanded_key[ii * 16 +10] = expanded_key[(ii - 1) * 16 +10] ^ expanded_key[ii * 16 + 6]; + expanded_key[ii * 16 +11] = expanded_key[(ii - 1) * 16 +11] ^ expanded_key[ii * 16 + 7]; + expanded_key[ii * 16 +12] = expanded_key[(ii - 1) * 16 +12] ^ expanded_key[ii * 16 + 8]; + expanded_key[ii * 16 +13] = expanded_key[(ii - 1) * 16 +13] ^ expanded_key[ii * 16 + 9]; + expanded_key[ii * 16 +14] = expanded_key[(ii - 1) * 16 +14] ^ expanded_key[ii * 16 +10]; + expanded_key[ii * 16 +15] = expanded_key[(ii - 1) * 16 +15] ^ expanded_key[ii * 16 +11]; + } +} + +/****************************************************************************** + * Name: galois_mul2 + * + * Description: + * Multiply by 2 in the galois field + * + * Input Parameters: + * value argument to multiply + * + * Returned Value: + * Multiplied argument + * + ******************************************************************************/ + +static uint8_t galois_mul2(uint8_t value) +{ + if (value >> 7) + { + value = value << 1; + return (value ^ 0x1b); + } + else + { + return value << 1; + } +} + +/****************************************************************************** + * Name: aes_encr + * + * Description: + * Internal implementation of AES128 encryption. + * Straight forward aes encryption implementation. First the group of + * operations: + * + * - addRoundKey + * - subbytes + * - shiftrows + * - mixcolums + * + * is executed 9 times, after this addroundkey to finish the 9th round, after + * that the 10th round without mixcolums no further subfunctions to save + * cycles for function calls no structuring with "for (....)" to save cycles. + * + * Input Parameters: + * expanded_key expanded AES128 key + * state 16 bytes of plain text and cipher text + * + * Returned Value: + * None + * + ******************************************************************************/ + +static void aes_encr(FAR uint8_t *state, FAR const uint8_t *expanded_key) +{ + uint8_t buf1; + uint8_t buf2; + uint8_t buf3; + uint8_t round; + + for (round = 0; round < 9; round ++) + { + /* addroundkey, sbox and shiftrows */ + /* Row 0 */ + + state[0] = g_sbox[(state[0] ^ expanded_key[(round * 16)])]; + state[4] = g_sbox[(state[4] ^ expanded_key[(round * 16) + 4])]; + state[8] = g_sbox[(state[8] ^ expanded_key[(round * 16) + 8])]; + state[12] = g_sbox[(state[12] ^ expanded_key[(round * 16) + 12])]; + + /* Row 1 */ + + buf1 = state[1] ^ expanded_key[(round * 16) + 1]; + state[1] = g_sbox[(state[5] ^ expanded_key[(round * 16) + 5])]; + state[5] = g_sbox[(state[9] ^ expanded_key[(round * 16) + 9])]; + state[9] = g_sbox[(state[13] ^ expanded_key[(round * 16) + 13])]; + state[13] = g_sbox[buf1]; + + /* Row 2 */ + + buf1 = state[2] ^ expanded_key[(round * 16) + 2]; + buf2 = state[6] ^ expanded_key[(round * 16) + 6]; + state[2] = g_sbox[(state[10] ^ expanded_key[(round * 16) + 10])]; + state[6] = g_sbox[(state[14] ^ expanded_key[(round * 16) + 14])]; + state[10] = g_sbox[buf1]; + state[14] = g_sbox[buf2]; + + /* Row 3 */ + + buf1 = state[15] ^ expanded_key[(round * 16) + 15]; + state[15] = g_sbox[(state[11] ^ expanded_key[(round * 16) + 11])]; + state[11] = g_sbox[(state[7] ^ expanded_key[(round * 16) + 7])]; + state[7] = g_sbox[(state[3] ^ expanded_key[(round * 16) + 3])]; + state[3] = g_sbox[buf1]; + + /* mixcolums */ + /* Col1 */ + + buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; + buf2 = state[0]; + buf3 = state[0] ^ state[1]; buf3 = galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; + buf3 = state[1] ^ state[2]; buf3 = galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; + buf3 = state[2] ^ state[3]; buf3 = galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; + buf3 = state[3] ^ buf2; buf3 = galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; + + /* Col2 */ + + buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; + buf2 = state[4]; + buf3 = state[4] ^ state[5]; buf3 = galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; + buf3 = state[5] ^ state[6]; buf3 = galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; + buf3 = state[6] ^ state[7]; buf3 = galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; + buf3 = state[7] ^ buf2; buf3 = galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; + + /* Col3 */ + + buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; + buf2 = state[8]; + buf3 = state[8] ^ state[9]; buf3 = galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; + buf3 = state[9] ^ state[10]; buf3 = galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; + buf3 = state[10] ^ state[11]; buf3 = galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; + buf3 = state[11] ^ buf2; buf3 = galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; + + /* Col4 */ + + buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; + buf2 = state[12]; + buf3 = state[12] ^ state[13]; buf3 = galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; + buf3 = state[13] ^ state[14]; buf3 = galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; + buf3 = state[14] ^ state[15]; buf3 = galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; + buf3 = state[15] ^ buf2; buf3 = galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; + } + + /* 10th round without mixcols */ + + state[0] = g_sbox[(state[0] ^ expanded_key[(round * 16)])]; + state[4] = g_sbox[(state[4] ^ expanded_key[(round * 16) + 4])]; + state[8] = g_sbox[(state[8] ^ expanded_key[(round * 16) + 8])]; + state[12] = g_sbox[(state[12] ^ expanded_key[(round * 16) + 12])]; + + /* Row 1 */ + + buf1 = state[1] ^ expanded_key[(round * 16) + 1]; + state[1] = g_sbox[(state[5] ^ expanded_key[(round * 16) + 5])]; + state[5] = g_sbox[(state[9] ^ expanded_key[(round * 16) + 9])]; + state[9] = g_sbox[(state[13] ^ expanded_key[(round * 16) + 13])]; + state[13] = g_sbox[buf1]; + + /* Row 2 */ + + buf1 = state[2] ^ expanded_key[(round * 16) + 2]; + buf2 = state[6] ^ expanded_key[(round * 16) + 6]; + state[2] = g_sbox[(state[10] ^ expanded_key[(round * 16) + 10])]; + state[6] = g_sbox[(state[14] ^ expanded_key[(round * 16) + 14])]; + state[10] = g_sbox[buf1]; + state[14] = g_sbox[buf2]; + + /* Row 3 */ + + buf1 = state[15] ^ expanded_key[(round * 16) + 15]; + state[15] = g_sbox[(state[11] ^ expanded_key[(round * 16) + 11])]; + state[11] = g_sbox[(state[7] ^ expanded_key[(round * 16) + 7])]; + state[7] = g_sbox[(state[3] ^ expanded_key[(round * 16) + 3])]; + state[3] = g_sbox[buf1]; + + /* Last addroundkey */ + + state[0] ^= expanded_key[160]; + state[1] ^= expanded_key[161]; + state[2] ^= expanded_key[162]; + state[3] ^= expanded_key[163]; + state[4] ^= expanded_key[164]; + state[5] ^= expanded_key[165]; + state[6] ^= expanded_key[166]; + state[7] ^= expanded_key[167]; + state[8] ^= expanded_key[168]; + state[9] ^= expanded_key[169]; + state[10] ^= expanded_key[170]; + state[11] ^= expanded_key[171]; + state[12] ^= expanded_key[172]; + state[13] ^= expanded_key[173]; + state[14] ^= expanded_key[174]; + state[15] ^= expanded_key[175]; +} + +/****************************************************************************** + * Name: aes_decr + * + * Description: + * Internal implementation of AES128 decryption. + * Straight forward aes decryption implementation. The order of substeps is + * the exact reverse of decryption inverse functions: + * + * - addRoundKey is its own inverse + * - rsbox is inverse of sbox + * - rightshift instead of leftshift + * - invMixColumns = barreto + mixColumns + * + * No further subfunctions to save cycles for function calls no structuring + * with "for (....)" to save cycles + * + * Input Parameters: + * expanded_key expanded AES128 key + * state 16 bytes of cipher text and plain text + * + * Returned Value: + * None + * + ******************************************************************************/ + +static void aes_decr(FAR uint8_t *state, FAR const uint8_t *expanded_key) +{ + uint8_t buf1; + uint8_t buf2; + uint8_t buf3; + int8_t round; + + round = 9; + + /* Initial addroundkey */ + + state[0] ^= expanded_key[160]; + state[1] ^= expanded_key[161]; + state[2] ^= expanded_key[162]; + state[3] ^= expanded_key[163]; + state[4] ^= expanded_key[164]; + state[5] ^= expanded_key[165]; + state[6] ^= expanded_key[166]; + state[7] ^= expanded_key[167]; + state[8] ^= expanded_key[168]; + state[9] ^= expanded_key[169]; + state[10] ^= expanded_key[170]; + state[11] ^= expanded_key[171]; + state[12] ^= expanded_key[172]; + state[13] ^= expanded_key[173]; + state[14] ^= expanded_key[174]; + state[15] ^= expanded_key[175]; + + /* 10th round without mixcols */ + + state[0] = g_rsbox[state[0]] ^ expanded_key[(round * 16)]; + state[4] = g_rsbox[state[4]] ^ expanded_key[(round * 16) + 4]; + state[8] = g_rsbox[state[8]] ^ expanded_key[(round * 16) + 8]; + state[12] = g_rsbox[state[12]] ^ expanded_key[(round * 16) + 12]; + + /* Row 1 */ + + buf1 = g_rsbox[state[13]] ^ expanded_key[(round * 16) + 1]; + state[13] = g_rsbox[state[9]] ^ expanded_key[(round * 16) + 13]; + state[9] = g_rsbox[state[5]] ^ expanded_key[(round * 16) + 9]; + state[5] = g_rsbox[state[1]] ^ expanded_key[(round * 16) + 5]; + state[1] = buf1; + + /* Row 2 */ + + buf1 = g_rsbox[state[2]] ^ expanded_key[(round * 16) + 10]; + buf2 = g_rsbox[state[6]] ^ expanded_key[(round * 16) + 14]; + state[2] = g_rsbox[state[10]] ^ expanded_key[(round * 16) + 2]; + state[6] = g_rsbox[state[14]] ^ expanded_key[(round * 16) + 6]; + state[10] = buf1; + state[14] = buf2; + + /* Row 3 */ + + buf1 = g_rsbox[state[3]] ^ expanded_key[(round * 16) + 15]; + state[3] = g_rsbox[state[7]] ^ expanded_key[(round * 16) + 3]; + state[7] = g_rsbox[state[11]] ^ expanded_key[(round * 16) + 7]; + state[11] = g_rsbox[state[15]] ^ expanded_key[(round * 16) + 11]; + state[15] = buf1; + + for (round = 8; round >= 0; round--) + { + /* barreto */ + /* Col1 */ + + buf1 = galois_mul2(galois_mul2(state[0] ^ state[2])); + buf2 = galois_mul2(galois_mul2(state[1] ^ state[3])); + state[0] ^= buf1; + state[1] ^= buf2; + state[2] ^= buf1; + state[3] ^= buf2; + + /* Col2 */ + + buf1 = galois_mul2(galois_mul2(state[4] ^ state[6])); + buf2 = galois_mul2(galois_mul2(state[5] ^ state[7])); + state[4] ^= buf1; + state[5] ^= buf2; + state[6] ^= buf1; + state[7] ^= buf2; + + /* Col3 */ + + buf1 = galois_mul2(galois_mul2(state[8] ^ state[10])); + buf2 = galois_mul2(galois_mul2(state[9] ^ state[11])); + state[8] ^= buf1; + state[9] ^= buf2; + state[10] ^= buf1; + state[11] ^= buf2; + + /* Col4 */ + + buf1 = galois_mul2(galois_mul2(state[12] ^ state[14])); + buf2 = galois_mul2(galois_mul2(state[13] ^ state[15])); + state[12] ^= buf1; + state[13] ^= buf2; + state[14] ^= buf1; + state[15] ^= buf2; + + /* mixcolums */ + /* Col1 */ + + buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; + buf2 = state[0]; + buf3 = state[0] ^ state[1]; buf3 = galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; + buf3 = state[1] ^ state[2]; buf3 = galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; + buf3 = state[2] ^ state[3]; buf3 = galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; + buf3 = state[3] ^ buf2; buf3 = galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; + + /* Col2 */ + + buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; + buf2 = state[4]; + buf3 = state[4] ^ state[5]; buf3 = galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; + buf3 = state[5] ^ state[6]; buf3 = galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; + buf3 = state[6] ^ state[7]; buf3 = galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; + buf3 = state[7] ^ buf2; buf3 = galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; + + /* Col3 */ + + buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; + buf2 = state[8]; + buf3 = state[8] ^ state[9]; buf3 = galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; + buf3 = state[9] ^ state[10]; buf3 = galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; + buf3 = state[10] ^ state[11]; buf3 = galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; + buf3 = state[11] ^ buf2; buf3 = galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; + + /* Col4 */ + + buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; + buf2 = state[12]; + buf3 = state[12] ^ state[13]; buf3 = galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; + buf3 = state[13] ^ state[14]; buf3 = galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; + buf3 = state[14] ^ state[15]; buf3 = galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; + buf3 = state[15] ^ buf2; buf3 = galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; + + /* addroundkey, rsbox and shiftrows */ + /* Row 0 */ + + state[0] = g_rsbox[state[0]] ^ expanded_key[(round * 16)]; + state[4] = g_rsbox[state[4]] ^ expanded_key[(round * 16) + 4]; + state[8] = g_rsbox[state[8]] ^ expanded_key[(round * 16) + 8]; + state[12] = g_rsbox[state[12]] ^ expanded_key[(round * 16) + 12]; + + /* Row 1 */ + + buf1 = g_rsbox[state[13]] ^ expanded_key[(round * 16) + 1]; + state[13] = g_rsbox[state[9]] ^ expanded_key[(round * 16) + 13]; + state[9] = g_rsbox[state[5]] ^ expanded_key[(round * 16) + 9]; + state[5] = g_rsbox[state[1]] ^ expanded_key[(round * 16) + 5]; + state[1] = buf1; + + /* Row 2 */ + + buf1 = g_rsbox[state[2]] ^ expanded_key[(round * 16) + 10]; + buf2 = g_rsbox[state[6]] ^ expanded_key[(round * 16) + 14]; + state[2] = g_rsbox[state[10]] ^ expanded_key[(round * 16) + 2]; + state[6] = g_rsbox[state[14]] ^ expanded_key[(round * 16) + 6]; + state[10] = buf1; + state[14] = buf2; + + /* Row 3 */ + + buf1 = g_rsbox[state[3]] ^ expanded_key[(round * 16) + 15]; + state[3] = g_rsbox[state[7]] ^ expanded_key[(round * 16) + 3]; + state[7] = g_rsbox[state[11]] ^ expanded_key[(round * 16) + 7]; + state[11] = g_rsbox[state[15]] ^ expanded_key[(round * 16) + 11]; + state[15] = buf1; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + /**************************************************************************** + * Name: aes_encrypt + * + * Description: + * AES128 encryption: Given AES128 key and 16 bytes plain text, cipher + * text of 16 bytes is computed. The AES implementation is in mode ECB + * (Electronic Code Book). + * + * Input Parameters: + * key AES128 key of size 16 bytes + * state 16 bytes of plain text and cipher text + * + * Returned Value + * None + * + ****************************************************************************/ + +void aes_encrypt(FAR uint8_t *state, FAR const uint8_t *key) +{ + /* Expand the key into 176 bytes */ + + expand_key(g_expanded_key, key); + aes_encr(state, g_expanded_key); +} + +/**************************************************************************** + * Name: aes_decrypt + * + * Description: + * AES128 decryption: Given AES128 key and 16 bytes cipher text, plain + * text of 16 bytes is computed The AES implementation is in mode ECB + * (Electronic Code Book). + * + * Input Parameters: + * key AES128 key of size 16 bytes + * state 16 bytes of plain text and cipher text + * + * Returned Value + * None + * + ****************************************************************************/ + +void aes_decrypt(FAR uint8_t *state, FAR const uint8_t *key) +{ + /* Expand the key into 176 bytes */ + + expand_key(g_expanded_key, key); + aes_decr(state, g_expanded_key); +} diff --git a/crypto/crypto.c b/crypto/crypto.c index 9b4391b5bb3ad47cf2676a0f91642999ff1cf0ee..401417d8744fafd95339479522b309ca5506c238 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -77,7 +77,7 @@ int up_cryptoinitialize(void) } #endif -#if CONFIG_CRYPTO_ALGTEST +#ifdef CONFIG_CRYPTO_ALGTEST res = crypto_test(); if (res) { diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index f6753effb5884adfc230529d94cad3673b2a6028..9710acf028180fdb68cc08cc5b42448840e2cfe3 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -50,6 +50,16 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_CRYPTO_AES +# define AES_CYPHER(mode) \ + aes_cypher(op->dst, op->src, op->len, op->iv, ses->key, ses->keylen, \ + mode, encrypt) +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -69,13 +79,18 @@ static int cryptodev_ioctl(FAR struct file *filep, int cmd, static const struct file_operations g_cryptodevops = { - 0, /* open */ - 0, /* close */ - cryptodev_read, /* read */ - cryptodev_write, /* write */ - 0, /* seek */ - cryptodev_ioctl, /* ioctl */ - 0, /* poll */ + 0, /* open */ + 0, /* close */ + cryptodev_read, /* read */ + cryptodev_write, /* write */ + 0, /* seek */ + cryptodev_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif }; /**************************************************************************** @@ -96,11 +111,11 @@ static ssize_t cryptodev_write(FAR struct file *filep, FAR const char *buffer, static int cryptodev_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { - switch(cmd) + switch (cmd) { case CIOCGSESSION: { - struct session_op *ses = (struct session_op*)arg; + FAR struct session_op *ses = (FAR struct session_op *)arg; ses->ses = (uint32_t)ses; return OK; } @@ -110,51 +125,46 @@ static int cryptodev_ioctl(FAR struct file *filep, int cmd, unsigned long arg) return OK; } +#ifdef CONFIG_CRYPTO_AES case CIOCCRYPT: { - FAR struct crypt_op *op = (struct crypt_op*)arg; - FAR struct session_op *ses = (struct session_op*)op->ses; + FAR struct crypt_op *op = (FAR struct crypt_op *)arg; + FAR struct session_op *ses = (FAR struct session_op *)op->ses; int encrypt; switch (op->op) - { - case COP_ENCRYPT: - encrypt = 1; - break; + { + case COP_ENCRYPT: + encrypt = 1; + break; - case COP_DECRYPT: - encrypt = 0; - break; + case COP_DECRYPT: + encrypt = 0; + break; - default: - return -EINVAL; - } + default: + return -EINVAL; + } switch (ses->cipher) - { - -#if defined(CONFIG_CRYPTO_AES) -# define AES_CYPHER(mode) aes_cypher(op->dst, op->src, op->len, op->iv, ses->key, ses->keylen, mode, encrypt) - - case CRYPTO_AES_ECB: - return AES_CYPHER(AES_MODE_ECB); + { + case CRYPTO_AES_ECB: + return AES_CYPHER(AES_MODE_ECB); - case CRYPTO_AES_CBC: - return AES_CYPHER(AES_MODE_CBC); + case CRYPTO_AES_CBC: + return AES_CYPHER(AES_MODE_CBC); - case CRYPTO_AES_CTR: - return AES_CYPHER(AES_MODE_CTR); + case CRYPTO_AES_CTR: + return AES_CYPHER(AES_MODE_CTR); -# undef AES_CYPHER -#endif - - default: - return -EINVAL; - } + default: + return -EINVAL; + } } +#endif default: - return -EINVAL; + return -ENOTTY; } } diff --git a/crypto/testmngr.c b/crypto/testmngr.c index 4002a2d980e4fd7ffb14091451a4200e51636269..c7fe86e78add3b1d246e64c2b4e5dafff66c6c6d 100644 --- a/crypto/testmngr.c +++ b/crypto/testmngr.c @@ -54,9 +54,9 @@ #include "testmngr.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #ifndef ARRAY_SIZE # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -68,7 +68,7 @@ * Private Functions ****************************************************************************/ -static int do_test_aes(FAR struct cipher_testvec* test, int mode, int encrypt) +static int do_test_aes(FAR struct cipher_testvec *test, int mode, int encrypt) { FAR void *out = kmm_zalloc(test->rlen); diff --git a/drivers/Kconfig b/drivers/Kconfig index 263001d9ccac69559436262b24305e2db540e218..d9105fcd9474ac05bf54fa234b1ebd210b265dc9 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -11,6 +11,9 @@ config DISABLE_POLL supported. If you do not use poll() or select(), then you can select DISABLE_POLL to reduce the code footprint by a small amount. + This selection disables the poll() interface as well as interfaces + the derive from poll() such as select(). + config DEV_NULL bool "Enable /dev/null" default y @@ -27,13 +30,7 @@ config DEV_RANDOM default n depends on ARCH_HAVE_RNG -config LOOP - bool "Enable loop device" - default n - ---help--- - Supports the standard loop device that can be used to export a - file (or character device) as a block device. See losetup() and - loteardown() in include/nuttx/fs/fs.h. +source drivers/loop/Kconfig menu "Buffering" @@ -107,6 +104,20 @@ config CAN_EXTID Enables support for the 28-bit extended ID. Default Standard 11-bit IDs. +config ARCH_HAVE_CAN_ERRORS + bool + default n + +config CAN_ERRORS + bool "CAN error reporting" + default n + depends on ARCH_HAVE_CAN_ERRORS + ---help--- + Support CAN error reporting. If this option is selected then CAN + error reporting is enabled. In the event of an error, the ch_error + bit will be set in the CAN message and the following message payload + will include a more detailed description of certain errors. + config CAN_FD bool "CAN FD" default n @@ -125,6 +136,70 @@ config CAN_NPENDINGRTR ---help--- The size of the list of pending RTR requests. Default: 4 +config CAN_TXREADY + bool "can_txready interface" + default n + select SCHED_WORKQUEUE + ---help--- + This selection enables the can_txready() interface. This interface + is needed only for CAN hardware that supports queing of outgoing + messages in a H/W FIFO. + + The CAN upper half driver also supports a queue of output messages + in a S/W FIFO. Messages are added to that queue when when + can_write() is called and removed from the queue in can_txdone() + when each TX message is complete. + + After each message is added to the S/W FIFO, the CAN upper half + driver will attempt to send the message by calling into the lower + half driver. That send will not be performed if the lower half + driver is busy, i.e., if dev_txready() returns false. In that + case, the number of messages in the S/W FIFO can grow. If the + S/W FIFO becomes full, then can_write() will wait for space in + the S/W FIFO. + + If the CAN hardware does not support a H/W FIFO then busy means + that the hardware is actively sending the message and is + guaranteed to become non busy (i.e, dev_txready()) when the + send transfer completes and can_txdone() is called. So the call + to can_txdone() means that the transfer has completed and also + that the hardware is ready to accept another transfer. + + If the CAN hardware supports a H/W FIFO, can_txdone() is not + called when the tranfer is complete, but rather when the + transfer is queued in the H/W FIFO. When the H/W FIFO becomes + full, then dev_txready() will report false and the number of + queued messages in the S/W FIFO will grow. + + There is no mechanism in this case to inform the upper half + driver when the hardware is again available, when there is + again space in the H/W FIFO. can_txdone() will not be called + again. If the S/W FIFO becomes full, then the upper half + driver will wait for space to become available, but there is + no event to awaken it and the driver will hang. + + Enabling this feature adds support for the can_txready() + interface. This function is called from the lower half + driver's CAN interrupt handler each time a TX transfer + completes. This is a sure indication that the H/W FIFO is + no longer full. can_txready() will then awaken the + can_write() logic and the hang condition is avoided. + +choice + prompt "TX Ready Work Queue" + default CAN_TXREADY_HIPRI + depends on CAN_TXREADY + +config CAN_TXREADY_LOPRI + bool "Low-priority work queue" + select SCHED_LPWORK + +config CAN_TXREADY_HIPRI + bool "High-priority work queue" + select SCHED_HPWORK + +endchoice # TX Ready Work Queue + config CAN_LOOPBACK bool "CAN loopback mode" default n @@ -139,6 +214,10 @@ config ARCH_HAVE_PWM_PULSECOUNT bool default n +config ARCH_HAVE_PWM_MULTICHAN + bool + default n + menuconfig PWM bool "PWM Driver Support" default n @@ -147,6 +226,7 @@ menuconfig PWM See include/nuttx/pwm.h for further PWM driver information. if PWM + config PWM_PULSECOUNT bool "PWM Pulse Count Support" default n @@ -157,6 +237,26 @@ config PWM_PULSECOUNT hardware will support a fixed pulse count, then this configuration should be set to enable the capability. +config PWM_MULTICHAN + bool "PWM Multiple Output Channel Support" + default n + depends on ARCH_HAVE_PWM_MULTICHAN + depends on !PWM_PULSECOUNT + ---help--- + Enables support for multiple output channels per timer. + +if PWM_MULTICHAN + +config PWM_NCHANNELS + int "Number of Output Channels Per Timer" + default 1 + range 1 4 + ---help--- + Specifies the number of output channels per timer. Each timer + may support fewer output channels than this value. + +endif # PWM_MULTICHAN + endif # PWM config ARCH_HAVE_I2CRESET @@ -168,41 +268,11 @@ menuconfig I2C default n ---help--- This selection enables building of the "upper-half" I2C driver. - See include/nuttx/i2c.h for further I2C driver information. + See include/nuttx/i2c/i2c_master.h for further I2C driver information. if I2C - -config I2C_SLAVE - bool "I2C Slave" - default n - -config I2C_TRANSFER - bool "Support the I2C transfer() method" - default n - -config I2C_WRITEREAD - bool "Support the I2C writeread() method" - default n - -config I2C_POLLED - bool "Polled I2C (no interrupts)" - default n - -config I2C_TRACE - bool "Enable I2C trace debug" - default n - -config I2C_NTRACE - int "Number of I2C trace records" - default 32 - depends on I2C_TRACE - -config I2C_RESET - bool "Support up_i2creset" - default n - depends on ARCH_HAVE_I2CRESET - -endif # I2C +source drivers/i2c/Kconfig +endif menuconfig SPI bool "SPI Driver Support" @@ -293,7 +363,7 @@ source drivers/input/Kconfig endif # INPUT menuconfig IOEXPANDER - bool "IO Expanders Support" + bool "IO Expander Support" default n ---help--- This directory holds implementations of IO expander drivers. @@ -319,6 +389,8 @@ if LCD source drivers/lcd/Kconfig endif # LCD +source drivers/leds/Kconfig + menuconfig MMCSD bool "MMC/SD Driver Support" default n @@ -331,6 +403,16 @@ if MMCSD source drivers/mmcsd/Kconfig endif # MMCSD +menuconfig MODEM + bool "Modem Support" + default n + ---help--- + Enable modem support. + +if MODEM +source drivers/modem/Kconfig +endif # MODEM + menuconfig MTD bool "Memory Technology Device (MTD) Support" default n @@ -468,15 +550,13 @@ if USBHOST source drivers/usbhost/Kconfig endif # USBHOST -menuconfig WIRELESS +menuconfig DRIVERS_WIRELESS bool "Wireless Device Support" default n ---help--- Drivers for various wireless devices. -if WIRELESS source drivers/wireless/Kconfig -endif # WIRELESS comment "System Logging Device Options" diff --git a/drivers/Makefile b/drivers/Makefile index 086cecb2ad17dba8ca15d9c17545126776f06ab6..025444990f91f5ad55db5f8a27d4917292bb3d9b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -52,10 +52,14 @@ VPATH = . include analog$(DELIM)Make.defs include audio$(DELIM)Make.defs include bch$(DELIM)Make.defs +include i2c$(DELIM)Make.defs include input$(DELIM)Make.defs include ioexpander$(DELIM)Make.defs include lcd$(DELIM)Make.defs +include leds$(DELIM)Make.defs +include loop$(DELIM)Make.defs include mmcsd$(DELIM)Make.defs +include modem$(DELIM)Make.defs include mtd$(DELIM)Make.defs include eeprom$(DELIM)Make.defs include net$(DELIM)Make.defs @@ -76,7 +80,7 @@ ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) CSRCS += dev_null.c dev_zero.c ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) - CSRCS += ramdisk.c loop.c + CSRCS += ramdisk.c ifeq ($(CONFIG_DRVR_WRITEBUFFER),y) CSRCS += rwbuffer.c else diff --git a/drivers/README.txt b/drivers/README.txt index 39b46109212b7954e33579443a838ca801c16d4c..420988ccd485ff8b8ecd25d59d7e6014ff762fb5 100644 --- a/drivers/README.txt +++ b/drivers/README.txt @@ -21,11 +21,6 @@ dev_null.c and dev_zero.c want to register these devices (devnull_register() and devzero_register()). -loop.c - Supports the standard loop device that can be used to export a - file (or character device) as a block device. See losetup() and - loteardown() in include/nuttx/fs/fs.h. - pwm.c Provides the "upper half" of a pulse width modulation (PWM) driver. The "lower half" of the PWM driver is provided by device-specific @@ -36,18 +31,10 @@ ramdisk.c a block driver that can be mounted as a files system. See include/nuttx/fs/ramdisk.h. -timer.c - Provides the "upper half" for a generic timer driver. See - include/nuttx/timers/timer.h for more information. - rwbuffer.c A facility that can be use by any block driver in-order to add writing buffering and read-ahead buffering. -watchdog.c - Provides the "upper half" for a generic watchdog driver. See - include/nuttx/timers/watchdog.h for more information. - Subdirectories of this directory: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,6 +68,9 @@ eeprom/ interface but instead use the simple character interface provided by the EEPROM drivers. +i2c/ + I2C drivers and support logic. See include/nuttx/i2c/i2c_master.h + input/ This directory holds implementations of human input device (HID) drivers. This includes such things as mouse, touchscreen, joystick, @@ -94,6 +84,15 @@ lcd/ Drivers for parallel and serial LCD and OLED type devices. These drivers support interfaces as defined in include/nuttx/lcd/lcd.h +leds/ + Various LED-related drivers including discrete as well as PWM- + driven LEDs. + +loop/ + Supports the standard loop device that can be used to export a + file (or character device) as a block device. See losetup() and + loteardown() in include/nuttx/fs/fs.h. + mmcsd/ Support for MMC/SD block drivers. MMC/SD block drivers based on SPI and SDIO/MCI interfaces are supported. See include/nuttx/mmcsd.h @@ -148,11 +147,22 @@ serial/ the NuttX system console. See also include/nuttx/serial/serial.h spi/ - SPI drivers. See include/nuttx/spi.h + SPI drivers and support logic. See include/nuttx/spi/spi.h syslog/ System logging devices. See include/syslog.h and include/nuttx/syslog/syslog.h +timers/ + Includes support for various timer devices including: + + - An "upper half" for a generic timer driver. See + include/nuttx/timers/timer.h for more information. + + - An "upper half" for a generic watchdog driver. See + include/nuttx/timers/watchdog.h for more information. + + - RTC drivers + usbdev/ USB device drivers. See also include/nuttx/usb/usbdev.h diff --git a/drivers/analog/Kconfig b/drivers/analog/Kconfig index 1bbc219f812c69599655f3806cc2fa325400f686..bc054804224e2671b94c8ce3d4b15091b50c2b1e 100644 --- a/drivers/analog/Kconfig +++ b/drivers/analog/Kconfig @@ -30,6 +30,18 @@ config ADC_NO_STARTUP_CONV ---help--- Do not start conversion when opening ADC device. +config ADC_ADS1242 + bool "TI ADS1242 support" + default n + select SPI + ---help--- + Enable driver support for the ADS1242 24-Bit SPI powered ADC. + + This driver supports reading the ADC conversion result as well as + configuring the ADC, setting the input channel, etc. is implemented + via ioctl calls. However, it does not yet implement the standard ADC + interface. + config ADC_ADS125X bool "TI ADS1255/ADS1256 support" default n diff --git a/drivers/analog/Make.defs b/drivers/analog/Make.defs index 89cc5bd3f78849a8acba1d923466586f5ccd94b3..2d12a1695d12702243fd167c372cf11a4e5a4e21 100644 --- a/drivers/analog/Make.defs +++ b/drivers/analog/Make.defs @@ -66,6 +66,10 @@ endif # Include ADC device drivers +ifeq ($(CONFIG_ADC_ADS1242),y) + CSRCS += ads1242.c +endif + ifeq ($(CONFIG_ADC_ADS125X),y) CSRCS += ads1255.c endif diff --git a/drivers/analog/ad5410.c b/drivers/analog/ad5410.c index 9caf675ab4615bafb23838137d5ee61e930010a4..33da3c76615a45d30021c09e16c23d06c8be5dbd 100644 --- a/drivers/analog/ad5410.c +++ b/drivers/analog/ad5410.c @@ -141,9 +141,9 @@ static int dac_setup(FAR struct dac_dev_s *dev) FAR struct spi_dev_s *spi = priv->spi; SPI_SELECT(spi, priv->devno, true); - SPI_SEND(spi,AD5410_REG_CMD); - SPI_SEND(spi,(AD5410_CMD_OUTEN|AD5410_CMD_420MA)>>8); - SPI_SEND(spi,AD5410_CMD_OUTEN|AD5410_CMD_420MA); + SPI_SEND(spi, AD5410_REG_CMD); + SPI_SEND(spi, (AD5410_CMD_OUTEN | AD5410_CMD_420MA) >> 8); + SPI_SEND(spi, AD5410_CMD_OUTEN | AD5410_CMD_420MA); SPI_SELECT(spi, priv->devno, false); return OK; } @@ -167,10 +167,10 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv; FAR struct spi_dev_s *spi = priv->spi; - SPI_SELECT(spi, priv->devno, true); - SPI_SEND(spi,AD5410_REG_WR); - SPI_SEND(spi,(uint8_t)(msg->am_data>>24)); - SPI_SEND(spi,(uint8_t)(msg->am_data>>16)); + SPI_SELECT(spi, priv->devno, true); + SPI_SEND(spi, AD5410_REG_WR); + SPI_SEND(spi, (uint8_t)(msg->am_data >> 24)); + SPI_SEND(spi, (uint8_t)(msg->am_data >> 16)); SPI_SELECT(spi, priv->devno, false); dac_txdone(&g_dacdev); return 0; @@ -207,8 +207,8 @@ FAR struct dac_dev_s *up_ad5410initialize(FAR struct spi_dev_s *spi, { FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_dacdev.ad_priv; - priv->spi=spi; - priv->devno=devno; + priv->spi = spi; + priv->devno = devno; return &g_dacdev; } #endif diff --git a/drivers/analog/adc.c b/drivers/analog/adc.c index 9b5bb6e42dd96ba96b99e7740b1c76f74131c0ba..ff6031ee68a7702e95252a23187f9f6c019e6e7c 100644 --- a/drivers/analog/adc.c +++ b/drivers/analog/adc.c @@ -59,7 +59,7 @@ #include #include -#include +#include /**************************************************************************** * Private Function Prototypes @@ -67,8 +67,9 @@ static int adc_open(FAR struct file *filep); static int adc_close(FAR struct file *filep); -static ssize_t adc_read(FAR struct file *, FAR char *, size_t); -static int adc_ioctl(FAR struct file *filep,int cmd,unsigned long arg); +static ssize_t adc_read(FAR struct file *fielp, FAR char *buffer, + size_t buflen); +static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg); /**************************************************************************** * Private Data @@ -133,7 +134,7 @@ static int adc_open(FAR struct file *filep) { /* Yes.. perform one time hardware initialization. */ - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); ret = dev->ad_ops->ao_setup(dev); if (ret == OK) { @@ -151,7 +152,7 @@ static int adc_open(FAR struct file *filep) dev->ad_ocount = tmp; } - irqrestore(flags); + leave_critical_section(flags); } } @@ -200,9 +201,9 @@ static int adc_close(FAR struct file *filep) /* Free the IRQ and disable the ADC device */ - flags = irqsave(); /* Disable interrupts */ + flags = enter_critical_section(); /* Disable interrupts */ dev->ad_ops->ao_shutdown(dev); /* Disable the ADC */ - irqrestore(flags); + leave_critical_section(flags); sem_post(&dev->ad_closesem); } @@ -243,7 +244,7 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen) { /* Interrupts must be disabled while accessing the ad_recv FIFO */ - flags = irqsave(); + flags = enter_critical_section(); while (dev->ad_recv.af_head == dev->ad_recv.af_tail) { /* The receive FIFO is empty -- was non-blocking mode selected? */ @@ -339,7 +340,7 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen) ret = nread; return_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); } avdbg("Returning: %d\n", ret); diff --git a/drivers/analog/ads1242.c b/drivers/analog/ads1242.c new file mode 100644 index 0000000000000000000000000000000000000000..93b82942c2cf6fde4d9ad3257102f4147ed6615e --- /dev/null +++ b/drivers/analog/ads1242.c @@ -0,0 +1,576 @@ +/**************************************************************************** + * drivers/sensors/ads1242.c + * Character driver for the MCP3426 Differential Input 16 Bit Delta/Sigma ADC + * + * Copyright (C) 2015 DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if defined(CONFIG_SPI) && defined(CONFIG_ADC_ADS1242) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ads1242_dev_s +{ + FAR struct spi_dev_s *spi; /* Pointer to the SPI instance */ + uint32_t osc_period_us; /* Period of the oscillator attached to the ADS1242 in us */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* SPI Helpers */ + +static void ads1242_reset(FAR struct ads1242_dev_s *dev); +static void ads1242_performSelfGainCalibration( + FAR struct ads1242_dev_s *dev); +static void ads1242_performSelfOffsetCalibration( + FAR struct ads1242_dev_s *dev); +static void ads1242_performSystemOffsetCalibration( + FAR struct ads1242_dev_s *dev); +static void ads1242_read_conversion_result(FAR struct ads1242_dev_s *dev, + FAR uint32_t *conversion_result); + +static void ads1242_write_reg(FAR struct ads1242_dev_s *dev, + uint8_t const reg_addr, uint8_t const reg_value); +static void ads1242_read_reg(FAR struct ads1242_dev_s *dev, + uint8_t const reg_addr, FAR uint8_t *reg_value); + +static void ads1242_set_gain(FAR struct ads1242_dev_s *dev, + ADS1242_GAIN_SELECTION const gain_selection); +static void ads1242_set_positive_input(FAR struct ads1242_dev_s *dev, + ADS1242_POSITIVE_INPUT_SELECTION const pos_in_sel); +static void ads1242_set_negative_input(FAR struct ads1242_dev_s *dev, + ADS1242_NEGATIVE_INPUT_SELECTION const neg_in_sel); +static bool ads1242_is_data_ready(FAR struct ads1242_dev_s *dev); + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) +static void ads1242_print_regs(FAR struct ads1242_dev_s *dev, char const *msg); +#endif /* CONFIG_DEBUG && CONFIG_DEBUG_VERBOSE */ + +/* Character driver methods */ + +static int ads1242_open(FAR struct file *filep); +static int ads1242_close(FAR struct file *filep); +static ssize_t ads1242_read(FAR struct file *, FAR char *, size_t); +static ssize_t ads1242_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int ads1242_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_ads1242_fops = +{ + ads1242_open, + ads1242_close, + ads1242_read, + ads1242_write, + NULL, + ads1242_ioctl +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ads1242_reset + ****************************************************************************/ + +static void ads1242_reset(FAR struct ads1242_dev_s *dev) +{ + SPI_SELECT(dev->spi, 0, true); /* Set nADC_SPI_CS to low which selects the ADS1242 */ + + SPI_SEND(dev->spi, ADS1242_CMD_RESET);/* Issue reset command */ + + SPI_SELECT(dev->spi, 0, false); /* Set nADC_SPI_CS to high which deselects the ADS1242 */ + + up_mdelay(100); /* Wait a little so the device has time to perform a proper reset */ +} + +/**************************************************************************** + * Name: ads1242_performSelfGainCalibration + ****************************************************************************/ + +static void ads1242_performSelfGainCalibration(FAR struct ads1242_dev_s *dev) +{ + SPI_SELECT(dev->spi, 0, true); + + SPI_SEND(dev->spi, ADS1242_CMD_SELF_GAIN_CALIB); + + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_performSelfOffsetCalibration + ****************************************************************************/ + +static void ads1242_performSelfOffsetCalibration(FAR struct ads1242_dev_s *dev) +{ + SPI_SELECT(dev->spi, 0, true); + + SPI_SEND(dev->spi, ADS1242_CMD_SELF_OFFSET_CALIB); + + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_performSystemOffsetCalibration + ****************************************************************************/ + +static void +ads1242_performSystemOffsetCalibration(FAR struct ads1242_dev_s *dev) +{ + SPI_SELECT(dev->spi, 0, true); + + SPI_SEND(dev->spi, ADS1242_CMD_SYSTEM_OFFSET_CALIB); + + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_read_conversion_result + ****************************************************************************/ + +static void ads1242_read_conversion_result(FAR struct ads1242_dev_s *dev, + FAR uint32_t *conversion_result) +{ + SPI_SELECT(dev->spi, 0, true); + + SPI_SEND(dev->spi, ADS1242_CMD_READ_DATA); + + /* Delay between last SCLK edge for DIN and first SCLK edge for DOUT: + * RDATA, RDATAC, RREG, WREG: Min 50 x tOSC Periods + */ + + up_udelay(50 * dev->osc_period_us); + + *conversion_result = 0; + + /* 1st Byte = MSB + * 2nd Byte = Mid-Byte + * 3rd Byte = LSB + */ + + *conversion_result |= ((uint32_t)(SPI_SEND(dev->spi, 0xFF))) << 16; + *conversion_result |= ((uint32_t)(SPI_SEND(dev->spi, 0xFF))) << 8; + *conversion_result |= ((uint32_t)(SPI_SEND(dev->spi, 0xFF))) << 0; + + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_write_reg + * + * Description: + * Write to the registers starting with the register address specified as + * part of the instruction. The number of registers that will be written + * is one plus the value of the second byte. + * + ****************************************************************************/ + +static void ads1242_write_reg(FAR struct ads1242_dev_s *dev, + uint8_t const reg_addr, uint8_t const reg_value) +{ + SPI_SELECT(dev->spi, 0, true); + SPI_SEND(dev->spi, ADS1242_CMD_WRITE_REGISTER | reg_addr); + SPI_SEND(dev->spi, 0x00); /* Write 1 Byte */ + SPI_SEND(dev->spi, reg_value); + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_read_reg + * + * Description: + * Output the data from up to 16 registers starting with the register + * address specified as part of the instruction. The number of registers + * read will be one plus the second byte count. If the count exceeds the + * remaining registers, the addresses wrap back to the beginning. + * + ****************************************************************************/ + +static void ads1242_read_reg(FAR struct ads1242_dev_s *dev, + uint8_t const reg_addr, FAR uint8_t *reg_value) +{ + SPI_SELECT(dev->spi, 0, true); + SPI_SEND(dev->spi, ADS1242_CMD_READ_REGISTER | reg_addr); + SPI_SEND(dev->spi, 0x00); /* Read 1 Byte */ + + /* Delay between last SCLK edge for DIN and first SCLK edge for DOUT: + * RDATA, RDATAC, RREG, WREG: Min 50 x tOSC Periods + */ + + up_udelay(50 * dev->osc_period_us); + + *reg_value = SPI_SEND(dev->spi, 0xFF); + + SPI_SELECT(dev->spi, 0, false); +} + +/**************************************************************************** + * Name: ads1242_set_gain + ****************************************************************************/ + +static void ads1242_set_gain(FAR struct ads1242_dev_s *dev, + ADS1242_GAIN_SELECTION const gain_selection) +{ + uint8_t setup_reg_value = 0; + + ads1242_read_reg(dev, ADS1242_REG_SETUP, &setup_reg_value); + setup_reg_value &= ~(ADS1242_REG_SETUP_BIT_PGA2 | + ADS1242_REG_SETUP_BIT_PGA1 | + ADS1242_REG_SETUP_BIT_PGA0); + setup_reg_value |= (uint8_t)(gain_selection); + ads1242_write_reg(dev, ADS1242_REG_SETUP, setup_reg_value); + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) + ads1242_print_regs(dev, "ads1242_set_gain"); +#endif + + /* It is necessary to perform a offset calibration after setting the gain */ + + ads1242_performSelfOffsetCalibration(dev); +} + +/**************************************************************************** + * Name: ads1242_set_positive_input + ****************************************************************************/ + +static void ads1242_set_positive_input(FAR struct ads1242_dev_s *dev, + ADS1242_POSITIVE_INPUT_SELECTION const pos_in_sel) +{ + uint8_t mux_reg_value = 0; + + ads1242_read_reg(dev, ADS1242_REG_MUX, &mux_reg_value); + mux_reg_value &= ~(ADS1242_REG_MUX_BIT_PSEL3 | ADS1242_REG_MUX_BIT_PSEL2 | + ADS1242_REG_MUX_BIT_PSEL1 | ADS1242_REG_MUX_BIT_PSEL0); + mux_reg_value |= (uint8_t)(pos_in_sel); + ads1242_write_reg(dev, ADS1242_REG_MUX, mux_reg_value); + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) + ads1242_print_regs(dev, "ads1242_set_positive_input"); +#endif +} + +/**************************************************************************** + * Name: ads1242_set_negative_input + ****************************************************************************/ + +static void ads1242_set_negative_input(FAR struct ads1242_dev_s *dev, + ADS1242_NEGATIVE_INPUT_SELECTION const neg_in_sel) +{ + uint8_t mux_reg_value = 0; + + ads1242_read_reg(dev, ADS1242_REG_MUX, &mux_reg_value); + mux_reg_value &= ~(ADS1242_REG_MUX_BIT_NSEL3 | ADS1242_REG_MUX_BIT_NSEL2 | + ADS1242_REG_MUX_BIT_NSEL1 | ADS1242_REG_MUX_BIT_NSEL0); + mux_reg_value |= (uint8_t)(neg_in_sel); + ads1242_write_reg(dev, ADS1242_REG_MUX, mux_reg_value); + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) + ads1242_print_regs(dev, "ads1242_set_negative_input"); +#endif +} + +/**************************************************************************** + * Name: ads1242_set_negative_input + ****************************************************************************/ + +static bool ads1242_is_data_ready(FAR struct ads1242_dev_s *dev) +{ + uint8_t acr_reg_value = 0xFF; + + ads1242_read_reg(dev, ADS1242_REG_ACR, &acr_reg_value); + return (acr_reg_value & ADS1242_REG_ACR_BIT_nDRDY) == 0; +} + +/**************************************************************************** + * Name: ads1242_print_regs + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) +static void ads1242_print_regs(FAR struct ads1242_dev_s *dev, char const *msg) +{ + uint8_t setup_reg_value = 0; + uint8_t mux_reg_value = 0; + uint8_t acr_reg_value = 0; + + dbg("%s\n", msg); + + ads1242_read_reg(dev, ADS1242_REG_SETUP, &setup_reg_value); + ads1242_read_reg(dev, ADS1242_REG_MUX, &mux_reg_value); + ads1242_read_reg(dev, ADS1242_REG_ACR, &acr_reg_value); + + dbg("SETUP %02X\n", setup_reg_value); + dbg("MUX %02X\n", mux_reg_value); + dbg("ACR %02X\n", acr_reg_value); +} +#endif /* CONFIG_DEBUG && CONFIG_DEBUG_VERBOSE */ + +/**************************************************************************** + * Name: ads1242_open + ****************************************************************************/ + +static int ads1242_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ads1242_dev_s *priv = inode->i_private; + + ads1242_reset(priv); + up_mdelay(100); + + ads1242_performSelfGainCalibration(priv); + up_mdelay(100); + + /* SPEED = 1 -> fMod = fOsc / 256 (fMod = Modulator Clock Speed) + * BUFEN = 1 -> Internal input buffer enabled -> results in a very high + * impedance input for the ADC ~ 5 GOhm + */ + + ads1242_write_reg(priv, ADS1242_REG_ACR, + ADS1242_REG_ACR_BIT_SPEED | ADS1242_REG_ACR_BIT_BUFEN); + + ads1242_performSelfOffsetCalibration(priv); + up_mdelay(100); + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) + ads1242_print_regs(priv, "ads1242_open"); +#endif + + return OK; +} +/**************************************************************************** + * Name: ads1242_close + ****************************************************************************/ + +static int ads1242_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ads1242_dev_s *priv = inode->i_private; + + ads1242_reset(priv); + up_mdelay(100); + + return OK; +} + +/**************************************************************************** + * Name: ads1242_read + ****************************************************************************/ + +static ssize_t ads1242_read(FAR struct file *filep, + FAR char *buffer, size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ads1242_write + ****************************************************************************/ + +static ssize_t ads1242_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ads1242_ioctl + ****************************************************************************/ + +static int ads1242_ioctl (FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ads1242_dev_s *priv = inode->i_private; + + int ret = OK; + + switch (cmd) + { + /* Read the result of an analog conversion */ + + case ANIOC_ADS2142_READ: + { + FAR uint32_t *data = (FAR uint32_t *)((uintptr_t)arg); + ads1242_read_conversion_result(priv, data); + } + break; + + /* Set the gain of the ADC */ + + case ANIOC_ADS2142_SET_GAIN: + { + ads1242_set_gain(priv, (ADS1242_GAIN_SELECTION)(arg)); + } + break; + + /* Set the positive input of the ADC */ + + case ANIOC_ADS2142_SET_POSITIVE_INPUT: + { + ads1242_set_positive_input(priv, + (ADS1242_POSITIVE_INPUT_SELECTION)(arg)); + } + break; + + /* Set the negative input of the ADC */ + + case ANIOC_ADS2142_SET_NEGATIVE_INPUT: + { + ads1242_set_negative_input(priv, + (ADS1242_NEGATIVE_INPUT_SELECTION)(arg)); + } + break; + + /* Check if data is ready to be read */ + + case ANIOC_ADS2142_IS_DATA_READY: + { + FAR bool *is_data_ready = (FAR bool *)((uintptr_t)arg); + *is_data_ready = ads1242_is_data_ready(priv); + } + break; + + /* Perform a system offset calibration - Note: Zero input signal must + * be applied. + */ + + case ANIOC_ADS2142_DO_SYSTEM_OFFSET_CALIB: + { + ads1242_performSystemOffsetCalibration(priv); + } + break; + + /* Command was not recognized */ + + default: + dbg ("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ads1242_register + * + * Description: + * Register the ADS1242 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/ads1242" + * spi - An instance of the SPI interface to use to communicate with ADS1242 + * osc_freq_hz - The frequency of the ADS1242 oscillator in Hz. Required for + * calculating the minimum delay periods when accessing the device via SPI. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ads1242_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + uint32_t const osc_freq_hz) +{ + FAR struct ads1242_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(spi != NULL); + + /* Initialize the ADS1242 device structure */ + + priv = (FAR struct ads1242_dev_s *)kmm_malloc(sizeof(struct ads1242_dev_s)); + if (priv == NULL) + { + dbg ("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->spi = spi; + + float const osc_period_us = (1000.0 * 1000.0) / ((float)(osc_freq_hz)); + priv->osc_period_us = (uint32_t)(osc_period_us); + + /* Register the character driver */ + + ret = register_driver(devpath, &g_ads1242_fops, 0666, priv); + if (ret < 0) + { + dbg ("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + /* setup SPI frequency */ + + SPI_SETFREQUENCY(spi, ADS1242_SPI_FREQUENCY); + + /* Setup SPI mode */ + + SPI_SETMODE(spi, ADS1242_SPI_MODE); + + return ret; +} + +#endif /* CONFIG_SPI && CONFIG_ADC_ADS1242 */ diff --git a/drivers/analog/ads1255.c b/drivers/analog/ads1255.c index 0fbf63c196a7f758eea6ab120ee8e19486505f95..432b7dd7660542e9a7da0ff5d2f1a1c140bbf1d0 100644 --- a/drivers/analog/ads1255.c +++ b/drivers/analog/ads1255.c @@ -147,17 +147,17 @@ static struct up_dev_s g_adcpriv = { .mux = (const uint8_t []) { - CONFIG_ADS1255_MUX,0 + CONFIG_ADS1255_MUX, 0 }, - .sps = CONFIG_ADS1255_SPS, + .sps = CONFIG_ADS1255_SPS, .channel = 0, - .irq = CONFIG_ADS1255_IRQ, + .irq = CONFIG_ADS1255_IRQ, }; static struct adc_dev_s g_adcdev = { - .ad_ops = &g_adcops, - .ad_priv= &g_adcpriv, + .ad_ops = &g_adcops, + .ad_priv = &g_adcpriv, }; /**************************************************************************** @@ -166,12 +166,12 @@ static struct adc_dev_s g_adcdev = static uint8_t getspsreg(uint16_t sps) { - static const unsigned short sps_tab[]= + static const unsigned short sps_tab[] = { 3, 7, 12, 20, 27, 40, 55, 80, 300, 750, 1500, 3000, 5000, 10000, 20000, 65535, }; - static const unsigned char sps_reg[]= + static const unsigned char sps_reg[] = { 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x72, 0x82, 0x92, 0xa1, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, @@ -203,12 +203,13 @@ static void adc_reset(FAR struct adc_dev_s *dev) SPI_SETMODE(spi, SPIDEV_MODE1); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); SPI_SETFREQUENCY(spi, CONFIG_ADS1255_FREQUENCY); usleep(1000); SPI_SELECT(spi, priv->devno, true); - SPI_SEND(spi,ADS125X_WREG+0x03); /* WRITE SPS REG */ - SPI_SEND(spi,0x00); /* count=1 */ - SPI_SEND(spi,0x63); + SPI_SEND(spi, ADS125X_WREG + 0x03); /* WRITE SPS REG */ + SPI_SEND(spi, 0x00); /* count=1 */ + SPI_SEND(spi, 0x63); SPI_SELECT(spi, priv->devno, false); } @@ -227,22 +228,22 @@ static int adc_setup(FAR struct adc_dev_s *dev) if (ret == OK) { SPI_SELECT(spi, priv->devno, true); - SPI_SEND(spi,ADS125X_WREG); /* WRITE REG from 0 */ - SPI_SEND(spi,0x03); /* count=4+1 */ + SPI_SEND(spi, ADS125X_WREG); /* WRITE REG from 0 */ + SPI_SEND(spi, 0x03); /* count=4+1 */ if (priv->buf) { - SPI_SEND(spi,ADS125X_BUFON); /* REG0 STATUS BUFFER ON */ + SPI_SEND(spi, ADS125X_BUFON); /* REG0 STATUS BUFFER ON */ } else { - SPI_SEND(spi,ADS125X_BUFOFF); + SPI_SEND(spi, ADS125X_BUFOFF); } - SPI_SEND(spi,priv->mux[0]); - SPI_SEND(spi,priv->pga); /* REG2 ADCON PGA=2 */ - SPI_SEND(spi,getspsreg(priv->sps)); + SPI_SEND(spi, priv->mux[0]); + SPI_SEND(spi, priv->pga); /* REG2 ADCON PGA=2 */ + SPI_SEND(spi, getspsreg(priv->sps)); usleep(1000); - SPI_SEND(spi,ADS125X_SELFCAL); + SPI_SEND(spi, ADS125X_SELFCAL); SPI_SELECT(spi, priv->devno, false); up_enable_irq(priv->irq); } @@ -292,30 +293,30 @@ static int adc_interrupt(int irq, void *context) unsigned char ch; SPI_SELECT(spi, priv->devno, true); - SPI_SEND(spi,ADS125X_RDATA); + SPI_SEND(spi, ADS125X_RDATA); up_udelay(10); - buf[3]=SPI_SEND(spi,0xff); - buf[2]=SPI_SEND(spi,0xff); - buf[1]=SPI_SEND(spi,0xff); - buf[0]=0; + buf[3] = SPI_SEND(spi, 0xff); + buf[2] = SPI_SEND(spi, 0xff); + buf[1] = SPI_SEND(spi, 0xff); + buf[0] = 0; priv->channel++; ch = priv->mux[priv->channel]; - if ( ch == 0 ) + if (ch == 0) { - priv->channel=0; + priv->channel = 0; ch = priv->mux[0]; } - SPI_SEND(spi,ADS125X_WREG+0x01); - SPI_SEND(spi,0x00); - SPI_SEND(spi,ch); - SPI_SEND(spi,ADS125X_SYNC); + SPI_SEND(spi, ADS125X_WREG + 0x01); + SPI_SEND(spi, 0x00); + SPI_SEND(spi, ch); + SPI_SEND(spi, ADS125X_SYNC); up_udelay(2); - SPI_SEND(spi,ADS125X_WAKEUP); + SPI_SEND(spi, ADS125X_WAKEUP); SPI_SELECT(spi, priv->devno, false); - adc_receive(&g_adcdev,priv->channel,*(int32_t *)buf); + adc_receive(&g_adcdev, priv->channel, *(int32_t *)buf); return OK; } diff --git a/drivers/analog/dac.c b/drivers/analog/dac.c index 515fc26842461ca748316ce36cef4dff2b49c34a..daf8b5f34a458b244998b1b7582af7faae11286a 100644 --- a/drivers/analog/dac.c +++ b/drivers/analog/dac.c @@ -59,7 +59,7 @@ #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -74,9 +74,11 @@ static int dac_open(FAR struct file *filep); static int dac_close(FAR struct file *filep); -static ssize_t dac_read(FAR struct file *, FAR char *, size_t); -static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); -static int dac_ioctl(FAR struct file *filep,int cmd,unsigned long arg); +static ssize_t dac_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int dac_ioctl(FAR struct file *filep, int cmd, unsigned long arg); /**************************************************************************** * Private Data @@ -141,7 +143,7 @@ static int dac_open(FAR struct file *filep) { /* Yes.. perform one time hardware initialization. */ - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); ret = dev->ad_ops->ao_setup(dev); if (ret == OK) { @@ -155,7 +157,7 @@ static int dac_open(FAR struct file *filep) dev->ad_ocount = tmp; } - irqrestore(flags); + leave_critical_section(flags); } } @@ -215,9 +217,9 @@ static int dac_close(FAR struct file *filep) /* Free the IRQ and disable the DAC device */ - flags = irqsave(); /* Disable interrupts */ + flags = enter_critical_section(); /* Disable interrupts */ dev->ad_ops->ao_shutdown(dev); /* Disable the DAC */ - irqrestore(flags); + leave_critical_section(flags); sem_post(&dev->ad_closesem); } @@ -287,7 +289,7 @@ static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t /* Interrupts must disabled throughout the following */ - flags = irqsave(); + flags = enter_critical_section(); /* Check if the TX FIFO was empty when we started. That is a clue that we have * to kick off a new TX sequence. @@ -299,7 +301,7 @@ static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t * shorter than the minimum. */ - if (buflen % 5 == 0 ) + if (buflen % 5 == 0) { msglen = 5; } @@ -324,7 +326,7 @@ static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t msglen = 5; } - while ((buflen - nsent) >= msglen ) + while ((buflen - nsent) >= msglen) { /* Check if adding this new message would over-run the drivers ability to enqueue * xmit data. @@ -394,27 +396,27 @@ static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t } else if (msglen == 4) { - fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent]; - fifo->af_buffer[fifo->af_tail].am_data=*(uint32_t *)&buffer[nsent]; - fifo->af_buffer[fifo->af_tail].am_data&=0xffffff00; + fifo->af_buffer[fifo->af_tail].am_channel = buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data = *(uint32_t *)&buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data &= 0xffffff00; } else if (msglen == 3) { - fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent]; - fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent+1]); - fifo->af_buffer[fifo->af_tail].am_data<<=16; + fifo->af_buffer[fifo->af_tail].am_channel = buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data = (*(uint16_t *)&buffer[nsent+1]); + fifo->af_buffer[fifo->af_tail].am_data <<= 16; } else if (msglen == 2) { - fifo->af_buffer[fifo->af_tail].am_channel=0; - fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent]); - fifo->af_buffer[fifo->af_tail].am_data<<=16; + fifo->af_buffer[fifo->af_tail].am_channel = 0; + fifo->af_buffer[fifo->af_tail].am_data = (*(uint16_t *)&buffer[nsent]); + fifo->af_buffer[fifo->af_tail].am_data <<= 16; } else if (msglen == 1) { - fifo->af_buffer[fifo->af_tail].am_channel=0; - fifo->af_buffer[fifo->af_tail].am_data=buffer[nsent]; - fifo->af_buffer[fifo->af_tail].am_data<<=24; + fifo->af_buffer[fifo->af_tail].am_channel = 0; + fifo->af_buffer[fifo->af_tail].am_data = buffer[nsent]; + fifo->af_buffer[fifo->af_tail].am_data <<= 24; } /* Increment the tail of the circular buffer */ @@ -426,21 +428,21 @@ static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t nsent += msglen; } - /* We get here after all messages have been added to the FIFO. Check if - * we need to kick of the XMIT sequence. - */ + /* We get here after all messages have been added to the FIFO. Check if + * we need to kick of the XMIT sequence. + */ - if (empty) - { - dac_xmit(dev); - } + if (empty) + { + dac_xmit(dev); + } /* Return the number of bytes that were sent */ ret = nsent; return_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/drivers/analog/pga11x.c b/drivers/analog/pga11x.c index 7bb4a11bb0b648e6072bce8018ca2c3f82ab3f47..d542bb77978ced27efdb4a2e512ad1d1a434b748 100644 --- a/drivers/analog/pga11x.c +++ b/drivers/analog/pga11x.c @@ -121,14 +121,6 @@ # define spivdbg(x...) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -155,6 +147,7 @@ static void pga11x_configure(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_PGA11X_SPIMODE); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); (void)SPI_SETFREQUENCY(spi, CONFIG_PGA11X_SPIFREQUENCY); } @@ -169,7 +162,6 @@ static void pga11x_configure(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void pga11x_lock(FAR struct spi_dev_s *spi) { spivdbg("Locking\n"); @@ -192,9 +184,6 @@ static void pga11x_lock(FAR struct spi_dev_s *spi) pga11x_configure(spi); } -#else -# define pga11x_lock(spi) -#endif /**************************************************************************** * Name: pga11x_unlock @@ -207,16 +196,12 @@ static void pga11x_lock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void pga11x_unlock(FAR struct spi_dev_s *spi) { spivdbg("Unlocking\n"); SPI_LOCK(spi, false); } -#else -# define pga11x_unlock(spi) -#endif /**************************************************************************** * Name: pga11x_send16 @@ -360,16 +345,8 @@ PGA11X_HANDLE pga11x_initialize(FAR struct spi_dev_s *spi) { spivdbg("Entry\n"); - /* Configure the SPI us for the device. Do this now only if the PGA11X is - * the only device on the bus. - */ - -#ifdef CONFIG_SPI_OWNBUS - pga11x_configure(spi); -#endif - - /* No other special state is required, just return the SPI driver instance - * as the handle. This gives us a place to extend functionality in the + /* No Special state is required, just return the SPI driver instance as + * the handle. This gives us a place to extend functionality in the * future if neccessary. */ diff --git a/drivers/audio/audio_null.c b/drivers/audio/audio_null.c index 7e0f366a782acc6d450fa5e17d359c6fdccfa978..f5a1337f5cabf0cc6b5f436c6f536d829a359408 100644 --- a/drivers/audio/audio_null.c +++ b/drivers/audio/audio_null.c @@ -101,7 +101,7 @@ static int null_start(FAR struct audio_lowerhalf_s *dev); #ifndef CONFIG_AUDIO_EXCLUDE_STOP #ifdef CONFIG_AUDIO_MULTI_SESSION static int null_stop(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); #else static int null_stop(FAR struct audio_lowerhalf_s *dev); #endif @@ -109,9 +109,9 @@ static int null_stop(FAR struct audio_lowerhalf_s *dev); #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION static int null_pause(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); static int null_resume(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); #else static int null_pause(FAR struct audio_lowerhalf_s *dev); static int null_resume(FAR struct audio_lowerhalf_s *dev); @@ -432,7 +432,7 @@ static void *null_workerthread(pthread_addr_t pvarg) #ifndef CONFIG_AUDIO_EXCLUDE_STOP while (!priv->terminate) #else - for (;;) + for (; ; ) #endif { /* Wait for messages from our message queue */ @@ -573,7 +573,7 @@ static int null_start(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_STOP #ifdef CONFIG_AUDIO_MULTI_SESSION -static int null_stop(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int null_stop(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int null_stop(FAR struct audio_lowerhalf_s *dev) #endif @@ -611,7 +611,7 @@ static int null_stop(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int null_pause(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int null_pause(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int null_pause(FAR struct audio_lowerhalf_s *dev) #endif @@ -630,7 +630,7 @@ static int null_pause(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int null_resume(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int null_resume(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int null_resume(FAR struct audio_lowerhalf_s *dev) #endif diff --git a/drivers/audio/vs1053.c b/drivers/audio/vs1053.c index dfc4220edba0dd637be119450db2259976d64276..68167ca31eb287173e49e5519ea861e7c6c927c7 100644 --- a/drivers/audio/vs1053.c +++ b/drivers/audio/vs1053.c @@ -111,35 +111,35 @@ struct vs1053_struct_s /* Our specific driver data goes here */ - const FAR struct vs1053_lower_s *hw_lower;/* Pointer to the hardware lower functions */ - FAR struct spi_dev_s *spi; /* Pointer to the SPI bus */ - FAR struct ap_buffer_s *apb; /* Pointer to the buffer we are processing */ - struct dq_queue_s apbq; /* Our queue for enqueued buffers */ - unsigned long spi_freq; /* Frequency to run the SPI bus at. */ - unsigned long chip_freq; /* Current chip frequency */ - mqd_t mq; /* Message queue for receiving messages */ - char mqname[16]; /* Our message queue name */ - pthread_t threadid; /* ID of our thread */ - sem_t apbq_sem; /* Audio Pipeline Buffer Queue sem access */ + const FAR struct vs1053_lower_s *hw_lower; /* Pointer to the hardware lower functions */ + FAR struct spi_dev_s *spi; /* Pointer to the SPI bus */ + FAR struct ap_buffer_s *apb; /* Pointer to the buffer we are processing */ + struct dq_queue_s apbq; /* Our queue for enqueued buffers */ + unsigned long spi_freq; /* Frequency to run the SPI bus at. */ + unsigned long chip_freq; /* Current chip frequency */ + mqd_t mq; /* Message queue for receiving messages */ + char mqname[16]; /* Our message queue name */ + pthread_t threadid; /* ID of our thread */ + sem_t apbq_sem; /* Audio Pipeline Buffer Queue sem access */ #ifndef CONFIG_AUDIO_EXCLUDE_VOLUME - int16_t volume; /* Current volume level */ + int16_t volume; /* Current volume level */ #ifndef CONFIG_AUDIO_EXCLUDE_BALANCE - int16_t balance; /* Current balance level */ + int16_t balance; /* Current balance level */ #endif /* CONFIG_AUDIO_EXCLUDE_BALANCE */ #endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */ #ifndef CONFIG_AUDIO_EXCLUDE_TONE - uint8_t bass; /* Bass level */ - uint8_t treble; /* Bass level */ + uint8_t bass; /* Bass level */ + uint8_t treble; /* Bass level */ #endif uint16_t endfillbytes; - uint8_t endfillchar; /* Fill char to send when no more data */ + uint8_t endfillchar; /* Fill char to send when no more data */ bool running; bool paused; bool endmode; #ifndef CONFIG_AUDIO_EXCLUDE_STOP bool cancelmode; #endif - bool busy; /* Set true when device reserved */ + bool busy; /* Set true when device reserved */ }; /**************************************************************************** @@ -167,7 +167,7 @@ static int vs1053_resume(FAR struct audio_lowerhalf_s *lower, static int vs1053_reserve(FAR struct audio_lowerhalf_s *lower, FAR void** ppContext); static int vs1053_release(FAR struct audio_lowerhalf_s *lower, - FAR void* pContext); + FAR void *pContext); #else static int vs1053_configure(FAR struct audio_lowerhalf_s *lower, FAR const struct audio_caps_s *pCaps); @@ -219,7 +219,10 @@ static const struct audio_ops_s g_audioops = /* ISR context pointers */ -static struct vs1053_struct_s* g_isrdata[CONFIG_VS1053_DEVICE_COUNT] = { NULL, }; +static struct vs1053_struct_s *g_isrdata[CONFIG_VS1053_DEVICE_COUNT] = +{ + NULL, +}; /* Volume control log table. This table is in increments of 2% of * requested volume level and is the register value that should be @@ -271,6 +274,7 @@ static void vs1053_spi_lock(FAR struct spi_dev_s *dev, unsigned long freq_mhz) SPI_SETMODE(dev, CONFIG_VS1053_SPIMODE); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, freq_mhz); } @@ -1518,14 +1522,14 @@ static int vs1053_start(FAR struct audio_lowerhalf_s *lower) #ifndef CONFIG_AUDIO_EXCLUDE_STOP #ifdef CONFIG_AUDIO_MULTI_SESSION -static int vs1053_stop(FAR struct audio_lowerhalf_s *lower, FAR void* session) +static int vs1053_stop(FAR struct audio_lowerhalf_s *lower, FAR void *session) #else static int vs1053_stop(FAR struct audio_lowerhalf_s *lower) #endif { FAR struct vs1053_struct_s *dev = (struct vs1053_struct_s *) lower; - struct audio_msg_s term_msg; - FAR void* value; + struct audio_msg_s term_msg; + FAR void *value; /* Send a message to stop all audio streaming */ @@ -1562,7 +1566,7 @@ static int vs1053_stop(FAR struct audio_lowerhalf_s *lower) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int vs1053_pause(FAR struct audio_lowerhalf_s *lower, FAR void* session) +static int vs1053_pause(FAR struct audio_lowerhalf_s *lower, FAR void *session) #else static int vs1053_pause(FAR struct audio_lowerhalf_s *lower) #endif @@ -1591,7 +1595,7 @@ static int vs1053_pause(FAR struct audio_lowerhalf_s *lower) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int vs1053_resume(FAR struct audio_lowerhalf_s *lower, FAR void* session) +static int vs1053_resume(FAR struct audio_lowerhalf_s *lower, FAR void *session) #else static int vs1053_resume(FAR struct audio_lowerhalf_s *lower) #endif @@ -1620,9 +1624,9 @@ static int vs1053_resume(FAR struct audio_lowerhalf_s *lower) ****************************************************************************/ static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower, - FAR struct ap_buffer_s *apb ) + FAR struct ap_buffer_s *apb) { - FAR struct vs1053_struct_s *dev = (struct vs1053_struct_s *) lower; + FAR struct vs1053_struct_s *dev = (struct vs1053_struct_s *)lower; struct audio_msg_s term_msg; int ret; @@ -1661,7 +1665,7 @@ static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower, ****************************************************************************/ static int vs1053_cancelbuffer(FAR struct audio_lowerhalf_s *lower, - FAR struct ap_buffer_s *apb ) + FAR struct ap_buffer_s *apb) { return OK; } @@ -1871,7 +1875,7 @@ struct audio_lowerhalf_s *vs1053_initialize(FAR struct spi_dev_s *spi, * for the DREQ to be active indicating the device is ready */ - retry = 200;; + retry = 200; while (!lower->read_dreq(lower) && retry) { up_udelay(10); diff --git a/drivers/audio/wm8904.c b/drivers/audio/wm8904.c index c90c834f653a6202a29408c73049bceb8eb42b0c..a437c137e83c2ddbb8dadddf421a88996fd91e71 100644 --- a/drivers/audio/wm8904.c +++ b/drivers/audio/wm8904.c @@ -3,7 +3,7 @@ * * Audio device driver for Wolfson Microelectronics WM8904 Audio codec. * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -59,10 +59,11 @@ #include #include +#include #include #include #include -#include +#include #include #include #include @@ -72,14 +73,6 @@ #include "wm8904.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -133,7 +126,7 @@ static int wm8904_start(FAR struct audio_lowerhalf_s *dev); #ifndef CONFIG_AUDIO_EXCLUDE_STOP #ifdef CONFIG_AUDIO_MULTI_SESSION static int wm8904_stop(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); #else static int wm8904_stop(FAR struct audio_lowerhalf_s *dev); #endif @@ -141,9 +134,9 @@ static int wm8904_stop(FAR struct audio_lowerhalf_s *dev); #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION static int wm8904_pause(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); static int wm8904_resume(FAR struct audio_lowerhalf_s *dev, - FAR void* session); + FAR void *session); #else static int wm8904_pause(FAR struct audio_lowerhalf_s *dev); static int wm8904_resume(FAR struct audio_lowerhalf_s *dev); @@ -232,7 +225,10 @@ const uint8_t g_sysclk_scaleb1[WM8904_BCLK_MAXDIV+1] = #ifndef CONFIG_WM8904_CLKDEBUG static #endif -const uint8_t g_fllratio[WM8904_NFLLRATIO] = {1, 2, 4, 8, 16}; +const uint8_t g_fllratio[WM8904_NFLLRATIO] = +{ + 1, 2, 4, 8, 16 +}; /**************************************************************************** * Private Functions @@ -263,17 +259,19 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr) /* Set up to write the address */ - msg[0].addr = priv->lower->address; - msg[0].flags = 0; - msg[0].buffer = ®addr; - msg[0].length = 1; + msg[0].frequency = priv->lower->frequency; + msg[0].addr = priv->lower->address; + msg[0].flags = 0; + msg[0].buffer = ®addr; + msg[0].length = 1; /* Followed by the read data */ - msg[1].addr = priv->lower->address; - msg[1].flags = I2C_M_READ; - msg[1].buffer = data; - msg[1].length = 2; + msg[1].frequency = priv->lower->frequency; + msg[1].addr = priv->lower->address; + msg[1].flags = I2C_M_READ; + msg[1].buffer = data; + msg[1].length = 2; /* Read the register data. The returned value is the number messages * completed. @@ -287,10 +285,10 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr) auddbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - auddbg("ERROR: up_i2creset failed: %d\n", ret); + auddbg("ERROR: I2C_RESET failed: %d\n", ret); break; } #else @@ -329,8 +327,15 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr) static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr, uint16_t regval) { + struct i2c_config_s config; int retries; + /* Setup up the I2C configuration */ + + config.frequency = priv->lower->frequency; + config.address = priv->lower->address; + config.addrlen = 7; + /* Try up to three times to read the register */ for (retries = 1; retries <= 3; retries++) @@ -348,18 +353,18 @@ static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr, * completed. */ - ret = I2C_WRITE(priv->i2c, data, 3); + ret = i2c_write(priv->i2c, &config, data, 3); if (ret < 0) { #ifdef CONFIG_I2C_RESET /* Perhaps the I2C bus is locked up? Try to shake the bus free */ - auddbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); + auddbg("WARNING: i2c_write failed: %d ... Resetting\n", ret); - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - auddbg("ERROR: up_i2creset failed: %d\n", ret); + auddbg("ERROR: I2C_RESET failed: %d\n", ret); break; } #else @@ -726,7 +731,7 @@ static void wm8904_setbitrate(FAR struct wm8904_dev_s *priv) minfout = WM8904_FVCO_MAX / WM8904_MAXOUTDIV; divndx = 0; - for (;;) + for (; ; ) { /* Calculate the new value of Fout that we would need to provide * with this SYSCLK divider in place. @@ -1312,7 +1317,7 @@ static void wm8904_senddone(FAR struct i2s_dev_s *i2s, * against that possibility. */ - flags = irqsave(); + flags = enter_critical_section(); /* Add the completed buffer to the end of our doneq. We do not yet * decrement the reference count. @@ -1329,7 +1334,7 @@ static void wm8904_senddone(FAR struct i2s_dev_s *i2s, /* REVISIT: This can be overwritten */ priv->result = result; - irqrestore(flags); + leave_critical_section(flags); /* Now send a message to the worker thread, informing it that there are * buffers in the done queue that need to be cleaned up. @@ -1364,13 +1369,13 @@ static void wm8904_returnbuffers(FAR struct wm8904_dev_s *priv) * use interrupt controls to protect against that possibility. */ - flags = irqsave(); + flags = enter_critical_section(); while (dq_peek(&priv->doneq) != NULL) { /* Take the next buffer from the queue of completed transfers */ apb = (FAR struct ap_buffer_s *)dq_remfirst(&priv->doneq); - irqrestore(flags); + leave_critical_section(flags); audvdbg("Returning: apb=%p curbyte=%d nbytes=%d flags=%04x\n", apb, apb->curbyte, apb->nbytes, apb->flags); @@ -1405,10 +1410,10 @@ static void wm8904_returnbuffers(FAR struct wm8904_dev_s *priv) #else priv->dev.upper(priv->dev.priv, AUDIO_CALLBACK_DEQUEUE, apb, OK); #endif - flags = irqsave(); + flags = enter_critical_section(); } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -1456,9 +1461,9 @@ static int wm8904_sendbuffer(FAR struct wm8904_dev_s *priv) * to avoid a possible race condition. */ - flags = irqsave(); + flags = enter_critical_section(); priv->inflight++; - irqrestore(flags); + leave_critical_section(flags); /* Send the entire audio buffer via I2S. What is a reasonable timeout * to use? This would depend on the bit rate and size of the buffer. @@ -1585,7 +1590,7 @@ static int wm8904_start(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_STOP #ifdef CONFIG_AUDIO_MULTI_SESSION -static int wm8904_stop(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int wm8904_stop(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int wm8904_stop(FAR struct audio_lowerhalf_s *dev) #endif @@ -1622,7 +1627,7 @@ static int wm8904_stop(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int wm8904_pause(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int wm8904_pause(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int wm8904_pause(FAR struct audio_lowerhalf_s *dev) #endif @@ -1651,7 +1656,7 @@ static int wm8904_pause(FAR struct audio_lowerhalf_s *dev) #ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME #ifdef CONFIG_AUDIO_MULTI_SESSION -static int wm8904_resume(FAR struct audio_lowerhalf_s *dev, FAR void* session) +static int wm8904_resume(FAR struct audio_lowerhalf_s *dev, FAR void *session) #else static int wm8904_resume(FAR struct audio_lowerhalf_s *dev) #endif @@ -2461,7 +2466,7 @@ static void wm8904_hw_reset(FAR struct wm8904_dev_s *priv) ****************************************************************************/ FAR struct audio_lowerhalf_s * - wm8904_initialize(FAR struct i2c_dev_s *i2c, FAR struct i2s_dev_s *i2s, + wm8904_initialize(FAR struct i2c_master_s *i2c, FAR struct i2s_dev_s *i2s, FAR const struct wm8904_lower_s *lower) { FAR struct wm8904_dev_s *priv; @@ -2489,12 +2494,6 @@ FAR struct audio_lowerhalf_s * dq_init(&priv->pendq); dq_init(&priv->doneq); - /* Initialize I2C */ - - auddbg("address=%02x frequency=%d\n", lower->address, lower->frequency); - I2C_SETFREQUENCY(i2c, lower->frequency); - I2C_SETADDRESS(i2c, lower->address, 7); - /* Software reset. This puts all WM8904 registers back in their * default state. */ diff --git a/drivers/audio/wm8904.h b/drivers/audio/wm8904.h index 8aeb5bce63593479dc7d6ee0896175b91a916719..e51d247c5f33ee01b846bab9198ab88d7da5e983 100644 --- a/drivers/audio/wm8904.h +++ b/drivers/audio/wm8904.h @@ -1067,7 +1067,7 @@ struct wm8904_dev_s /* Our specific driver data goes here */ const FAR struct wm8904_lower_s *lower; /* Pointer to the board lower functions */ - FAR struct i2c_dev_s *i2c; /* I2C driver to use */ + FAR struct i2c_master_s *i2c; /* I2C driver to use */ FAR struct i2s_dev_s *i2s; /* I2S driver to use */ struct dq_queue_s pendq; /* Queue of pending buffers to be sent */ struct dq_queue_s doneq; /* Queue of sent buffers to be returned */ diff --git a/drivers/audio/wm8904_debug.c b/drivers/audio/wm8904_debug.c index a45573ee27c022f0bf151ebf8ab89d3da36f1bf4..d94eb2c4fbbc4ab9ef86ebad5f941ae0ba1b23f5 100644 --- a/drivers/audio/wm8904_debug.c +++ b/drivers/audio/wm8904_debug.c @@ -394,7 +394,7 @@ void wm8904_clock_analysis(FAR struct audio_lowerhalf_s *dev, else { syslog(LOG_INFO, " MCLK_DIV: 2\n"); - sysclk >>=1; + sysclk >>= 1; } syslog(LOG_INFO, " SYSCLK: %lu (after divider)\n", (unsigned long)sysclk); diff --git a/drivers/bch/bch_internal.h b/drivers/bch/bch.h similarity index 78% rename from drivers/bch/bch_internal.h rename to drivers/bch/bch.h index dabd2f5c503e29325de16c9ad1c4a33802805693..157cf06133b2da34901b07ca98a2e9b71bf5f860 100644 --- a/drivers/bch/bch_internal.h +++ b/drivers/bch/bch.h @@ -1,7 +1,7 @@ /**************************************************************************** - * drivers/bch/bch_internal.h + * drivers/bch/bch.h * - * Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __FS_BCH_INTERNAL_H -#define __FS_BCH_INTERNAL_H +#ifndef __DRIVERS_BCH_BCH_H +#define __DRIVERS_BCH_BCH_H /**************************************************************************** * Included Files @@ -61,23 +61,24 @@ struct bchlib_s { - struct inode *inode; /* I-node of the block driver */ - sem_t sem; /* For atomic accesses to this structure */ - size_t nsectors; /* Number of sectors supported by the device */ - size_t sector; /* The current sector in the buffer */ - uint16_t sectsize; /* The size of one sector on the device */ - uint8_t refs; /* Number of references */ - bool dirty; /* Data has been written to the buffer */ - bool readonly; /* true: Only read operations are supported */ - FAR uint8_t *buffer; /* One sector buffer */ + FAR struct inode *inode; /* I-node of the block driver */ + uint32_t sectsize; /* The size of one sector on the device */ + size_t nsectors; /* Number of sectors supported by the device */ + size_t sector; /* The current sector in the buffer */ + sem_t sem; /* For atomic accesses to this structure */ + uint8_t refs; /* Number of references */ + bool dirty; /* true: Data has been written to the buffer */ + bool readonly; /* true: Only read operations are supported */ + bool unlinked; /* true: The driver has been unlinked */ + FAR uint8_t *buffer; /* One sector buffer */ #if defined(CONFIG_BCH_ENCRYPTION) - uint8_t key[CONFIG_BCH_ENCRYPTION_KEY_SIZE]; /* Encryption key */ + uint8_t key[CONFIG_BCH_ENCRYPTION_KEY_SIZE]; /* Encryption key */ #endif }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -103,4 +104,4 @@ EXTERN int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector); } #endif -#endif /* __FS_BCH_INTERNAL_H */ +#endif /* __DRIVERS_BCH_BCH_H */ diff --git a/drivers/bch/bchdev_driver.c b/drivers/bch/bchdev_driver.c index 9382b4d58a85418030d31f75b35013fd10b0de65..198cd334b381df1fb272d7b40031531f3984f4b1 100644 --- a/drivers/bch/bchdev_driver.c +++ b/drivers/bch/bchdev_driver.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/bch/bchdev_driver.c * - * Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions @@ -77,6 +77,9 @@ static ssize_t bch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int bch_unlink(FAR struct inode *inode); +#endif /**************************************************************************** * Public Data @@ -84,14 +87,17 @@ static int bch_ioctl(FAR struct file *filep, int cmd, const struct file_operations bch_fops = { - bch_open, /* open */ - bch_close, /* close */ - bch_read, /* read */ - bch_write, /* write */ - bch_seek, /* seek */ - bch_ioctl /* ioctl */ + bch_open, /* open */ + bch_close, /* close */ + bch_read, /* read */ + bch_write, /* write */ + bch_seek, /* seek */ + bch_ioctl /* ioctl */ #ifndef CONFIG_DISABLE_POLL - , 0 /* poll */ + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , bch_unlink /* unlink */ #endif }; @@ -152,7 +158,8 @@ static int bch_close(FAR struct file *filep) (void)bchlib_flushsector(bch); /* Decrement the reference count (I don't use bchlib_decref() because I - * want the entire close operation to be atomic wrt other driver operations. + * want the entire close operation to be atomic wrt other driver + * operations. */ if (bch->refs == 0) @@ -162,6 +169,30 @@ static int bch_close(FAR struct file *filep) else { bch->refs--; + + /* If the reference count decremented to zero AND if the character + * driver has been unlinked, then teardown the BCH device now. + */ + + if (bch->refs == 0 && bch->unlinked) + { + /* Tear the driver down now. */ + + ret = bchlib_teardown((FAR void *)bch); + + /* bchlib_teardown() would only fail if there are outstanding + * references on the device. Since we know that is not true, it + * should not fail at all. + */ + + DEBUGASSERT(ret >= 0); + if (ret >= 0) + { + /* Return without releasing the stale semaphore */ + + return OK; + } + } } bchlib_semgive(bch); @@ -302,6 +333,8 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) DEBUGASSERT(inode && inode->i_private); bch = (FAR struct bchlib_s *)inode->i_private; + /* Is this a request to get the private data structure */ + if (cmd == DIOC_GETPRIV) { FAR struct bchlib_s **bchr = (FAR struct bchlib_s **)((uintptr_t)arg); @@ -319,16 +352,86 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) bchlib_semgive(bch); } -#if defined(CONFIG_BCH_ENCRYPTION) + +#ifdef CONFIG_BCH_ENCRYPTION + /* Is this a request to set the encryption key? */ + else if (cmd == DIOC_SETKEY) { - memcpy(bch->key, (void*)arg, CONFIG_BCH_ENCRYPTION_KEY_SIZE); + memcpy(bch->key, (FAR void *)arg, CONFIG_BCH_ENCRYPTION_KEY_SIZE); ret = OK; } #endif + /* Otherwise, pass the IOCTL command on to the contained block driver */ + + else + { + FAR struct inode *bchinode = bch->inode; + + /* Does the block driver support the ioctl method? */ + + if (bchinode->u.i_bops->ioctl != NULL) + { + ret = bchinode->u.i_bops->ioctl(bchinode, cmd, arg); + } + } + + return ret; +} + +/**************************************************************************** + * Name: bch_unlink + * + * Handle unlinking of the BCH device + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int bch_unlink(FAR struct inode *inode) +{ + FAR struct bchlib_s *bch; + int ret = OK; + + DEBUGASSERT(inode && inode->i_private); + bch = (FAR struct bchlib_s *)inode->i_private; + + /* Get exclusive access to the BCH device */ + + bchlib_semtake(bch); + + /* Indicate that the driver has been unlinked */ + + bch->unlinked = true; + + /* If there are no open references to the drvier then teardown the BCH + * device now. + */ + + if (bch->refs == 0) + { + /* Tear the driver down now. */ + + ret = bchlib_teardown((FAR void *)bch); + + /* bchlib_teardown() would only fail if there are outstanding + * references on the device. Since we know that is not true, it + * should not fail at all. + */ + + DEBUGASSERT(ret >= 0); + if (ret >= 0) + { + /* Return without releasing the stale semaphore */ + + return OK; + } + } + + bchlib_semgive(bch); return ret; } +#endif /**************************************************************************** * Public Functions diff --git a/drivers/bch/bchdev_register.c b/drivers/bch/bchdev_register.c index 924977371ed3398341f4a1e4be862da123bc0291..139c2925767d1a7a90ebdc3e3facb42494f7ad05 100644 --- a/drivers/bch/bchdev_register.c +++ b/drivers/bch/bchdev_register.c @@ -44,7 +44,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchdev_unregister.c b/drivers/bch/bchdev_unregister.c index 8c7360882b657c9766ee43ce09095acb000bf908..0c6a35d4b18d9be1bb2b1473e3027bfcf1fadc8f 100644 --- a/drivers/bch/bchdev_unregister.c +++ b/drivers/bch/bchdev_unregister.c @@ -52,7 +52,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchlib_cache.c b/drivers/bch/bchlib_cache.c index 3e46c2405780d1ee6f1eaf60926f14820e53c8d3..8ad543b4b008d0f17388cb57324036a0a69941d0 100644 --- a/drivers/bch/bchlib_cache.c +++ b/drivers/bch/bchlib_cache.c @@ -47,7 +47,7 @@ #include -#include "bch_internal.h" +#include "bch.h" #if defined(CONFIG_BCH_ENCRYPTION) # include @@ -91,13 +91,16 @@ static void bch_xor(uint32_t *R, uint32_t *A, uint32_t *B) static int bch_cypher(FAR struct bchlib_s *bch, int encrypt) { int blocks = bch->sectsize / 16; - uint32_t *buffer = (uint32_t*)bch->buffer; + FAR uint32_t *buffer = (FAR uint32_t *)bch->buffer; int i; for (i = 0; i < blocks; i++, buffer += 16 / sizeof(uint32_t) ) { uint32_t T[4]; - uint32_t X[4] = {bch->sector, 0, 0, i}; + uint32_t X[4] = + { + bch->sector, 0, 0, i + }; aes_cypher(X, X, 16, NULL, bch->key, CONFIG_BCH_ENCRYPTION_KEY_SIZE, AES_MODE_ECB, CYPHER_ENCRYPT); diff --git a/drivers/bch/bchlib_read.c b/drivers/bch/bchlib_read.c index 5257e6f2bb376d78154bb3331d65235c39bd150c..d534d8491963b58e995dd1de9f89d48b519adcda 100644 --- a/drivers/bch/bchlib_read.c +++ b/drivers/bch/bchlib_read.c @@ -48,7 +48,7 @@ #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types @@ -132,7 +132,6 @@ ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t le /* Adjust pointers and counts */ - sectoffset = 0; sector++; if (sector >= bch->nsectors) @@ -149,7 +148,7 @@ ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t le * into the user buffer. */ - if (len >= bch->sectsize ) + if (len >= bch->sectsize) { nsectors = len / bch->sectsize; if (sector + nsectors > bch->nsectors) @@ -167,9 +166,7 @@ ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t le /* Adjust pointers and counts */ - sectoffset = 0; sector += nsectors; - nbytes = nsectors * bch->sectsize; bytesread += nbytes; diff --git a/drivers/bch/bchlib_sem.c b/drivers/bch/bchlib_sem.c index 1698ed0a54f9ccba42d9b0e3f9d3fc85e4ed7ed8..ff221d934f4e5e64c7b2e4b4d46152ec2ef6ec8f 100644 --- a/drivers/bch/bchlib_sem.c +++ b/drivers/bch/bchlib_sem.c @@ -43,7 +43,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/bch/bchlib_setup.c b/drivers/bch/bchlib_setup.c index e0c956a73910f69ca70de59f77c7a79bc1160367..6ec7a878a63c8ebe3b715506c860596e2bb10299 100644 --- a/drivers/bch/bchlib_setup.c +++ b/drivers/bch/bchlib_setup.c @@ -52,7 +52,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types @@ -93,7 +93,7 @@ int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle) /* Allocate the BCH state structure */ - bch = (FAR struct bchlib_s*)kmm_zalloc(sizeof(struct bchlib_s)); + bch = (FAR struct bchlib_s *)kmm_zalloc(sizeof(struct bchlib_s)); if (!bch) { fdbg("Failed to allocate BCH structure\n"); diff --git a/drivers/bch/bchlib_teardown.c b/drivers/bch/bchlib_teardown.c index 8d1f45ed9bc6f5e6344693efe4632ca94d27db3a..d97d3b8ffcdc8261ce57923272e76e61728b6d1c 100644 --- a/drivers/bch/bchlib_teardown.c +++ b/drivers/bch/bchlib_teardown.c @@ -47,7 +47,7 @@ #include #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types diff --git a/drivers/bch/bchlib_write.c b/drivers/bch/bchlib_write.c index 21fce2cd036cbbf96f6bc7d539315f05d2ab897e..b1636c6d450914330d2415624e46f05bd993b1c2 100644 --- a/drivers/bch/bchlib_write.c +++ b/drivers/bch/bchlib_write.c @@ -49,7 +49,7 @@ #include -#include "bch_internal.h" +#include "bch.h" /**************************************************************************** * Private Types @@ -132,7 +132,6 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, si /* Adjust pointers and counts */ - sectoffset = 0; sector++; if (sector >= bch->nsectors) @@ -149,7 +148,7 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, si * directly from the user buffer. */ - if (len >= bch->sectsize ) + if (len >= bch->sectsize) { nsectors = len / bch->sectsize; if (sector + nsectors > bch->nsectors) @@ -169,9 +168,7 @@ ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, si /* Adjust pointers and counts */ - sectoffset = 0; sector += nsectors; - nbytes = nsectors * bch->sectsize; byteswritten += nbytes; diff --git a/drivers/can.c b/drivers/can.c index f37557205bd013d9fd5b9987b250bd1bb30a0c71..a98e1145bc75d34077c281b1f5b0853bdffc11c2 100644 --- a/drivers/can.c +++ b/drivers/can.c @@ -54,13 +54,48 @@ #include #include -#include +#ifdef CONFIG_CAN_TXREADY +# include +#endif + +#include #ifdef CONFIG_CAN /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifdef CONFIG_CAN_TXREADY +# if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support required in this configuration +# undef CONFIG_CAN_TXREADY +# undef CONFIG_CAN_TXREADY_LOPRI +# undef CONFIG_CAN_TXREADY_HIPRI +# elif defined(CONFIG_CAN_TXREADY_LOPRI) +# undef CONFIG_CAN_TXREADY_HIPRI +# ifdef CONFIG_SCHED_LPWORK +# define CANWORK LPWORK +# else +# error Low priority work queue support required in this configuration +# undef CONFIG_CAN_TXREADY +# undef CONFIG_CAN_TXREADY_LOPRI +# endif +# elif defined(CONFIG_CAN_TXREADY_HIPRI) +# ifdef CONFIG_SCHED_HPWORK +# define CANWORK HPWORK +# else +# error High priority work queue support required in this configuration +# undef CONFIG_CAN_TXREADY +# undef CONFIG_CAN_TXREADY_HIPRI +# endif +# else +# error No work queue selection +# undef CONFIG_CAN_TXREADY +# endif +#endif + /* Debug ********************************************************************/ /* Non-standard debug that may be enabled just for testing CAN */ @@ -95,6 +130,9 @@ static uint8_t can_dlc2bytes(uint8_t dlc); #if 0 /* Not used */ static uint8_t can_bytes2dlc(uint8_t nbytes); #endif +#ifdef CONFIG_CAN_TXREADY +static void can_txready_work(FAR void *arg); +#endif /* Character driver methods */ @@ -246,6 +284,59 @@ static uint8_t can_bytes2dlc(FAR struct sam_can_s *priv, uint8_t nbytes) } #endif +/**************************************************************************** + * Name: can_txready_work + * + * Description: + * This function performs deferred processing from can_txready. See the + * discription of can_txready below for additionla information. + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_TXREADY +static void can_txready_work(FAR void *arg) +{ + FAR struct can_dev_s *dev = (FAR struct can_dev_s *)arg; + irqstate_t flags; + int ret; + + canllvdbg("xmit head: %d queue: %d tail: %d\n", + dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, + dev->cd_xmit.tx_tail); + + /* Verify that the xmit FIFO is not empty. The following operations must + * be performed with interrupt disabled. + */ + + flags = enter_critical_section(); + if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail) + { + /* Send the next message in the FIFO. */ + + ret = can_xmit(dev); + + /* If the message was successfully queued in the H/W FIFO, then + * can_txdone() should have been called. If the S/W FIFO were + * full before then there should now be free space in the S/W FIFO. + */ + + if (ret >= 0) + { + /* Are there any threads waiting for space in the TX FIFO? */ + + if (dev->cd_ntxwaiters > 0) + { + /* Yes.. Inform them that new xmit space is available */ + + (void)sem_post(&dev->cd_xmit.tx_sem); + } + } + } + + leave_critical_section(flags); +} +#endif + /**************************************************************************** * Name: can_open * @@ -291,7 +382,7 @@ static int can_open(FAR struct file *filep) { /* Yes.. perform one time hardware initialization. */ - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); ret = dev_setup(dev); if (ret == OK) { @@ -312,7 +403,7 @@ static int can_open(FAR struct file *filep) dev->cd_ocount = 1; } - irqrestore(flags); + leave_critical_section(flags); } else { @@ -395,9 +486,9 @@ static int can_close(FAR struct file *filep) /* Free the IRQ and disable the CAN device */ - flags = irqsave(); /* Disable interrupts */ + flags = enter_critical_section(); /* Disable interrupts */ dev_shutdown(dev); /* Disable the CAN */ - irqrestore(flags); + leave_critical_section(flags); sem_post(&dev->cd_closesem); } @@ -434,7 +525,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer, { /* Interrupts must be disabled while accessing the cd_recv FIFO */ - flags = irqsave(); + flags = enter_critical_section(); while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail) { /* The receive FIFO is empty -- was non-blocking mode selected? */ @@ -501,7 +592,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer, ret = nread; return_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); } return ret; @@ -531,7 +622,15 @@ static int can_xmit(FAR struct can_dev_s *dev) if (dev->cd_xmit.tx_head == dev->cd_xmit.tx_tail) { DEBUGASSERT(dev->cd_xmit.tx_queue == dev->cd_xmit.tx_head); + +#ifndef CONFIG_CAN_TXREADY + /* We can disable CAN TX interrupts -- unless there is a H/W FIFO. In + * that case, TX interrupts must stay enabled until the H/W FIFO is + * fully emptied. + */ + dev_txint(dev, false); +#endif return -EIO; } @@ -554,7 +653,7 @@ static int can_xmit(FAR struct can_dev_s *dev) DEBUGASSERT(dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail); /* Increment the FIFO queue index before sending (because dev_send() - * might call can_txdone(). + * might call can_txdone()). */ tmpndx = dev->cd_xmit.tx_queue; @@ -602,7 +701,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, /* Interrupts must disabled throughout the following */ - flags = irqsave(); + flags = enter_critical_section(); /* Check if the TX is inactive when we started. In certain race conditions, * there may be a pending interrupt to kick things back off, but we will @@ -634,7 +733,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, { /* The transmit FIFO is full -- was non-blocking mode selected? */ - if (filep->f_oflags & O_NONBLOCK) + if ((filep->f_oflags & O_NONBLOCK) != 0) { if (nsent == 0) { @@ -655,7 +754,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, if (inactive) { - can_xmit(dev); + (void)can_xmit(dev); } /* Wait for a message to be sent */ @@ -698,21 +797,21 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, nsent += msglen; } - /* We get here after all messages have been added to the FIFO. Check if - * we need to kick of the XMIT sequence. - */ + /* We get here after all messages have been added to the FIFO. Check if + * we need to kick of the XMIT sequence. + */ - if (inactive) - { - can_xmit(dev); - } + if (inactive) + { + (void)can_xmit(dev); + } /* Return the number of bytes that were sent */ ret = nsent; return_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -737,7 +836,7 @@ static inline ssize_t can_rtrread(FAR struct can_dev_s *dev, /* Disable interrupts through this operation */ - flags = irqsave(); + flags = enter_critical_section(); /* Find an available slot in the pending RTR list */ @@ -767,7 +866,7 @@ static inline ssize_t can_rtrread(FAR struct can_dev_s *dev, } } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -795,7 +894,7 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) */ case CANIOC_RTR: - ret = can_rtrread(dev, (struct canioc_rtr_s*)((uintptr_t)arg)); + ret = can_rtrread(dev, (FAR struct canioc_rtr_s *)((uintptr_t)arg)); break; /* Not a "built-in" ioctl command.. perhaps it is unique to this @@ -859,11 +958,14 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev) * Description: * Called from the CAN interrupt handler when new read data is available * - * Parameters: + * Input Parameters: * dev - CAN driver state structure * hdr - CAN message header * data - CAN message data (if DLC > 0) * + * Returned Value: + * OK on success; a negated errno on failure. + * * Assumptions: * CAN interrupts are disabled. * @@ -983,17 +1085,72 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, * Name: can_txdone * * Description: - * Called from the CAN interrupt handler at the completion of a send - * operation. + * Called when the hardware has processed the outgoing TX message. This + * normally means that the CAN messages was sent out on the wire. But + * if the CAN hardware supports a H/W TX FIFO, then this call may mean + * only that the CAN message has been added to the H/W FIFO. In either + * case, the upper-half CAN driver can remove the outgoing message from + * the S/W FIFO and discard it. + * + * This function may be called in different contexts, depending upon the + * nature of the underlying CAN hardware. + * + * 1. No H/W TX FIFO (CONFIG_CAN_TXREADY not defined) + * + * This function is only called from the CAN interrupt handler at the + * completion of a send operation. + * + * can_write() -> can_xmit() -> dev_send() + * CAN interrupt -> can_txdone() + * + * If the CAN hardware is busy, then the call to dev_send() will + * fail, the S/W TX FIFO will accumulate outgoing messages, and the + * thread calling can_write() may eventually block waiting for space in + * the S/W TX FIFO. + * + * When the CAN hardware completes the transfer and processes the + * CAN interrupt, the call to can_txdone() will make space in the S/W + * TX FIFO and will awaken the waiting can_write() thread. + * + * 2a. H/W TX FIFO (CONFIG_CAN_TXREADY=y) and S/W TX FIFO not full + * + * This function will be called back from dev_send() immediately when a + * new CAN message is added to H/W TX FIFO: + * + * can_write() -> can_xmit() -> dev_send() -> can_txdone() + * + * When the H/W TX FIFO becomes full, dev_send() will fail and + * can_txdone() will not be called. In this case the S/W TX FIFO will + * accumulate outgoing messages, and the thread calling can_write() may + * eventually block waiting for space in the S/W TX FIFO. + * + * 2b. H/W TX FIFO (CONFIG_CAN_TXREADY=y) and S/W TX FIFO full + * + * In this case, the thread calling can_write() is blocked waiting for + * space in the S/W TX FIFO. can_txdone() will be called, indirectly, + * from can_txready_work() running on the thread of the work queue. * - * Parameters: + * CAN interrupt -> can_txready() -> Schedule can_txready_work() + * can_txready_work() -> can_xmit() -> dev_send() -> can_txdone() + * + * The call dev_send() should not fail in this case and the subsequent + * call to can_txdone() will make space in the S/W TX FIFO and will + * awaken the waiting thread. + * + * Input Parameters: * dev - The specific CAN device * hdr - The 16-bit CAN header * data - An array contain the CAN data. * - * Return: + * Returned Value: * OK on success; a negated errno on failure. * + * Assumptions: + * Interrupts are disabled. This is required by can_xmit() which is called + * by this function. Interrupts are explicitly disabled when called + * through can_write(). Interrupts are expected be disabled when called + * from the CAN interrupt handler. + * ****************************************************************************/ int can_txdone(FAR struct can_dev_s *dev) @@ -1007,6 +1164,12 @@ int can_txdone(FAR struct can_dev_s *dev) if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail) { + /* The tx_queue index is incremented each time can_xmit() queues + * the transmission. When can_txdone() is called, the tx_queue + * index should always have been advanced beyond the current tx_head + * index. + */ + DEBUGASSERT(dev->cd_xmit.tx_head != dev->cd_xmit.tx_queue); /* Remove the message at the head of the xmit FIFO */ @@ -1037,4 +1200,123 @@ int can_txdone(FAR struct can_dev_s *dev) return ret; } +/**************************************************************************** + * Name: can_txready + * + * Description: + * Called from the CAN interrupt handler at the completion of a send + * operation. This interface is needed only for CAN hardware that + * supports queing of outgoing messages in a H/W FIFO. + * + * The CAN upper half driver also supports a queue of output messages in a + * S/W FIFO. Messages are added to that queue when when can_write() is + * called and removed from the queue in can_txdone() when each TX message + * is complete. + * + * After each message is added to the S/W FIFO, the CAN upper half driver + * will attempt to send the message by calling into the lower half driver. + * That send will not be performed if the lower half driver is busy, i.e., + * if dev_txready() returns false. In that case, the number of messages in + * the S/W FIFO can grow. If the S/W FIFO becomes full, then can_write() + * will wait for space in the S/W FIFO. + * + * If the CAN hardware does not support a H/W FIFO then busy means that + * the hardware is actively sending the message and is guaranteed to + * become non-busy (i.e, dev_txready()) when the send transfer completes + * and can_txdone() is called. So the call to can_txdone() means that the + * transfer has completed and also that the hardware is ready to accept + * another transfer. + * + * If the CAN hardware supports a H/W FIFO, can_txdone() is not called + * when the tranfer is complete, but rather when the transfer is queued in + * the H/W FIFO. When the H/W FIFO becomes full, then dev_txready() will + * report false and the number of queued messages in the S/W FIFO will grow. + * + * There is no mechanism in this case to inform the upper half driver when + * the hardware is again available, when there is again space in the H/W + * FIFO. can_txdone() will not be called again. If the S/W FIFO becomes + * full, then the upper half driver will wait for space to become + * available, but there is no event to awaken it and the driver will hang. + * + * Enabling this feature adds support for the can_txready() interface. + * This function is called from the lower half driver's CAN interrupt + * handler each time a TX transfer completes. This is a sure indication + * that the H/W FIFO is no longer full. can_txready() will then awaken + * the can_write() logic and the hang condition is avoided. + * + * Input Parameters: + * dev - The specific CAN device + * + * Returned Value: + * OK on success; a negated errno on failure. + * + * Assumptions: + * Interrupts are disabled. This function may execute in the context of + * and interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_CAN_TXREADY +int can_txready(FAR struct can_dev_s *dev) +{ + int ret = -ENOENT; + + canllvdbg("xmit head: %d queue: %d tail: %d waiters: %d\n", + dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail, + dev->cd_ntxwaiters); + + /* Verify that the xmit FIFO is not empty. This is safe because interrupts + * are always disabled when calling into can_xmit(); this cannot collide + * with ongoing activity from can_write(). + */ + + if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail) + { + /* Is work already scheduled? */ + + if (work_available(&dev->cd_work)) + { + /* Yes... schedule to perform can_txready() work on the worker + * thread. Although data structures are protected by disabling + * interrupts, the can_xmit() operations may involve semaphore + * operations and, hence, should not be done at the interrupt + * level. + */ + + ret = work_queue(CANWORK, &dev->cd_work, can_txready_work, dev, 0); + } + else + { + ret = -EBUSY; + } + } + else + { + /* There should not be any threads waiting for space in the S/W TX + * FIFO is it is empty. + * + * REVISIT: Assertion can fire in certain race conditions, i.e, when + * all waiters have been awakened but have not yet had a chance to + * decrement cd_ntxwaiters. + */ + + //DEBUGASSERT(dev->cd_ntxwaiters == 0); + +#if 0 /* REVISIT */ + /* When the H/W FIFO has been emptied, we can disable further TX + * interrupts. + * + * REVISIT: The fact that the S/W FIFO is empty does not mean that + * the H/W FIFO is also empty. If we really want this to work this + * way, then we would probably need and additional parameter to tell + * us if the H/W FIFO is empty. + */ + + dev_txint(dev, false); +#endif + } + + return ret; +} +#endif /* CONFIG_CAN_TXREADY */ #endif /* CONFIG_CAN */ diff --git a/drivers/dev_null.c b/drivers/dev_null.c index 1a405d7cfc37760d4465f9f4b99d5f44b124c6d9..eca30dd8e105b5d7a3ed29f09122252c0685dcbf 100644 --- a/drivers/dev_null.c +++ b/drivers/dev_null.c @@ -50,11 +50,13 @@ * Private Function Prototypes ****************************************************************************/ -static ssize_t devnull_read(FAR struct file *, FAR char *, size_t); -static ssize_t devnull_write(FAR struct file *, FAR const char *, size_t); +static ssize_t devnull_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t devnull_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); #ifndef CONFIG_DISABLE_POLL static int devnull_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup); + bool setup); #endif /**************************************************************************** @@ -106,7 +108,7 @@ static int devnull_poll(FAR struct file *filep, FAR struct pollfd *fds, { if (setup) { - fds->revents |= (fds->events & (POLLIN|POLLOUT)); + fds->revents |= (fds->events & (POLLIN | POLLOUT)); if (fds->revents != 0) { sem_post(fds->sem); diff --git a/drivers/dev_zero.c b/drivers/dev_zero.c index a1374101ad4efa320a71972c683427a8decc691b..0bb31688be86dc6a0a9959fe863c5a92f5bf5284 100644 --- a/drivers/dev_zero.c +++ b/drivers/dev_zero.c @@ -50,11 +50,13 @@ * Private Function Prototypes ****************************************************************************/ -static ssize_t devzero_read(FAR struct file *, FAR char *, size_t); -static ssize_t devzero_write(FAR struct file *, FAR const char *, size_t); +static ssize_t devzero_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t devzero_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); #ifndef CONFIG_DISABLE_POLL static int devzero_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup); + bool setup); #endif /**************************************************************************** @@ -109,7 +111,7 @@ static int devzero_poll(FAR struct file *filep, FAR struct pollfd *fds, { if (setup) { - fds->revents |= (fds->events & (POLLIN|POLLOUT)); + fds->revents |= (fds->events & (POLLIN | POLLOUT)); if (fds->revents != 0) { sem_post(fds->sem); diff --git a/drivers/eeprom/spi_xx25xx.c b/drivers/eeprom/spi_xx25xx.c index e8c520d907f38ad2c21c34191de25e54777e0f6a..1f9335b856778d9a2c62c2d24f4eb8bfeb10e74c 100644 --- a/drivers/eeprom/spi_xx25xx.c +++ b/drivers/eeprom/spi_xx25xx.c @@ -173,10 +173,10 @@ struct ee25xx_geom_s { - uint8_t bytes : 4; /*power of two of 128 bytes (0:128 1:256 2:512 etc) */ - uint8_t pagesize : 4; /*power of two of 8 bytes (0:8 1:16 2:32 3:64 etc)*/ - uint8_t addrlen : 4; /*number of bytes in command address field */ - uint8_t flags : 4; /*special address management for 25xx040, 1=A8 in inst*/ + uint8_t bytes : 4; /* Power of two of 128 bytes (0:128 1:256 2:512 etc) */ + uint8_t pagesize : 4; /* Power of two of 8 bytes (0:8 1:16 2:32 3:64 etc) */ + uint8_t addrlen : 4; /* Number of bytes in command address field */ + uint8_t flags : 4; /* Special address management for 25xx040, 1=A8 in inst */ }; /* Private data attached to the inode */ @@ -219,29 +219,29 @@ static const struct ee25xx_geom_s g_ee25xx_devices[] = { /* Microchip devices */ - { 0, 1, 1, 0}, /* 25xx010A 128 16 1*/ - { 1, 1, 1, 0}, /* 25xx020A 256 16 1*/ - { 2, 1, 1, 1}, /* 25xx040 512 16 1+bit*/ - { 3, 1, 1, 0}, /* 25xx080 1024 16 1*/ - { 3, 2, 2, 0}, /* 25xx080B 1024 32 2*/ - { 4, 1, 2, 0}, /* 25xx160 2048 16 2*/ - { 4, 2, 2, 0}, /* 25xx160B/D 2048 32 2*/ - { 5, 2, 2, 0}, /* 25xx320 4096 32 2*/ - { 6, 2, 2, 0}, /* 25xx640 8192 32 2*/ - { 7, 3, 2, 0}, /* 25xx128 16384 64 2*/ - { 8, 3, 2, 0}, /* 25xx256 32768 64 2*/ - { 9, 4, 2, 0}, /* 25xx512 65536 128 2*/ - {10, 5, 3, 0}, /* 25xx1024 131072 256 3*/ + { 0, 1, 1, 0}, /* 25xx010A 128 16 1 */ + { 1, 1, 1, 0}, /* 25xx020A 256 16 1 */ + { 2, 1, 1, 1}, /* 25xx040 512 16 1+bit */ + { 3, 1, 1, 0}, /* 25xx080 1024 16 1 */ + { 3, 2, 2, 0}, /* 25xx080B 1024 32 2 */ + { 4, 1, 2, 0}, /* 25xx160 2048 16 2 */ + { 4, 2, 2, 0}, /* 25xx160B/D 2048 32 2 */ + { 5, 2, 2, 0}, /* 25xx320 4096 32 2 */ + { 6, 2, 2, 0}, /* 25xx640 8192 32 2 */ + { 7, 3, 2, 0}, /* 25xx128 16384 64 2 */ + { 8, 3, 2, 0}, /* 25xx256 32768 64 2 */ + { 9, 4, 2, 0}, /* 25xx512 65536 128 2 */ + {10, 5, 3, 0}, /* 25xx1024 131072 256 3 */ /* Atmel devices */ - { 0, 0, 1, 0}, /* AT25010B 128 8 1*/ - { 1, 0, 1, 0}, /* AT25020B 256 8 1*/ - { 2, 0, 1, 1}, /* AT25040B 512 8 1+bit*/ + { 0, 0, 1, 0}, /* AT25010B 128 8 1 */ + { 1, 0, 1, 0}, /* AT25020B 256 8 1 */ + { 2, 0, 1, 1}, /* AT25040B 512 8 1+bit */ /* STM devices */ - {11, 5, 3, 0}, /* M95M02 262144 256 3*/ + {11, 5, 3, 0}, /* M95M02 262144 256 3 */ }; /* Driver operations */ @@ -288,6 +288,7 @@ static void ee25xx_lock(FAR struct spi_dev_s *dev) SPI_SETMODE(dev, CONFIG_EE25XX_SPIMODE); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, 10000000); /* This is the default speed */ } @@ -337,7 +338,7 @@ static void ee25xx_sendcmd(FAR struct spi_dev_s *spi, uint8_t cmd, buf[cmdlen++] = addr & 0xff; - SPI_SNDBLOCK(spi,buf,cmdlen); + SPI_SNDBLOCK(spi, buf, cmdlen); } /**************************************************************************** @@ -488,7 +489,7 @@ static int ee25xx_open(FAR struct file *filep) /* Increment the reference count */ - if ( (eedev->refs + 1) == 0) + if ((eedev->refs + 1) == 0) { ret = -EMFILE; } @@ -678,7 +679,7 @@ static ssize_t ee25xx_write(FAR struct file *filep, FAR const char *buffer, /* Clamp len to avoid crossing the end of the memory */ - if ( (len + filep->f_pos) > eedev->size) + if ((len + filep->f_pos) > eedev->size) { len = eedev->size - filep->f_pos; } @@ -807,7 +808,7 @@ int ee25xx_initialize(FAR struct spi_dev_s *dev, FAR char *devname, eedev->size = 128 << g_ee25xx_devices[devtype].bytes; eedev->pgsize = 8 << g_ee25xx_devices[devtype].pagesize; eedev->addrlen = g_ee25xx_devices[devtype].addrlen << 3; - if ( (g_ee25xx_devices[devtype].flags & 1)) + if ((g_ee25xx_devices[devtype].flags & 1)) { eedev->addrlen = 9; } diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..95bd11250073c7d6e33829a512a5ed2ec56dc670 --- /dev/null +++ b/drivers/i2c/Kconfig @@ -0,0 +1,34 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if I2C + +config I2C_SLAVE + bool "I2C Slave" + default n + +config I2C_POLLED + bool "Polled I2C (no interrupts)" + default n + +config I2C_RESET + bool "Support I2C reset interface method" + default n + depends on ARCH_HAVE_I2CRESET + +config I2C_TRACE + bool "Enable I2C trace debug" + default n + +config I2C_NTRACE + int "Number of I2C trace records" + default 32 + depends on I2C_TRACE + +config I2C_DRIVER + bool "I2C character driver" + default n + +endif # I2C diff --git a/drivers/i2c/Make.defs b/drivers/i2c/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..d7d708bdf23f52ec29c17cc4842d032d2d5eb50f --- /dev/null +++ b/drivers/i2c/Make.defs @@ -0,0 +1,52 @@ +############################################################################ +# drivers/i2c/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Don't build anything if there is no I2C support + +ifeq ($(CONFIG_I2C),y) + +CSRCS += i2c_read.c i2c_write.c i2c_writeread.c + +ifeq ($(CONFIG_I2C_DRIVER),y) +CSRCS += i2c_driver.c +endif + +# Include I2C device driver build support + +DEPPATH += --dep-path i2c +VPATH += :i2c +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)i2c} +endif + diff --git a/drivers/i2c/i2c_driver.c b/drivers/i2c/i2c_driver.c new file mode 100644 index 0000000000000000000000000000000000000000..ac53f0f1f1c16f427e3da45aa4d8497fa0d1e749 --- /dev/null +++ b/drivers/i2c/i2c_driver.c @@ -0,0 +1,438 @@ +/**************************************************************************** + * drivers/i2c/i2c_driver.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_I2C_DRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Device naming ************************************************************/ + +#define DEVNAME_FMT "/dev/i2c%d" +#define DEVNAME_FMTLEN (8 + 3 + 1) + +/* Debug ********************************************************************/ +/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */ + +#ifdef CONFIG_DEBUG_I2C +# define i2cdbg dbg +# define i2cvdbg vdbg +#else +# define i2cdbg(x...) +# define i2cvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Driver state structure */ + +struct i2c_driver_s +{ + FAR struct i2c_master_s *i2c; /* Contained I2C lower half driver */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + sem_t exclsem; /* Mutual exclusion */ + int16_t crefs; /* Number of open references */ + bool unlinked; /* True, driver has been unlinked */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int i2cdrvr_open(FAR struct file *filep); +static int i2cdrvr_close(FAR struct file *filep); +static ssize_t i2cdrvr_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t i2cdrvr_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int i2cdrvr_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int i2cdrvr_unlink(FAR struct inode *inode); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations i2cdrvr_fops = +{ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + i2cdrvr_open, /* open */ + i2cdrvr_close, /* close */ +#else + 0, /* open */ + 0, /* close */ +#endif + i2cdrvr_read, /* read */ + i2cdrvr_write, /* write */ + 0, /* seek */ + i2cdrvr_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , i2cdrvr_unlink /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2cdrvr_open + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int i2cdrvr_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct i2c_driver_s *priv; + int ret; + + /* Get our private data structure */ + + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + + priv = (FAR struct i2c_driver_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Get exclusive access to the I2C driver state structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + int errcode = errno; + DEBUGASSERT(errcode < 0); + return -errcode; + } + + /* Increment the count of open references on the RTC driver */ + + priv->crefs++; + DEBUGASSERT(priv->crefs > 0); + + sem_post(&priv->exclsem); + return OK; +} +#endif + +/**************************************************************************** + * Name: i2cdrvr_close + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int i2cdrvr_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct i2c_driver_s *priv; + int ret; + + /* Get our private data structure */ + + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + + priv = (FAR struct i2c_driver_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Get exclusive access to the I2C driver state structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + int errcode = errno; + DEBUGASSERT(errcode < 0); + return -errcode; + } + + /* Decrement the count of open references on the RTC driver */ + + DEBUGASSERT(priv->crefs > 0); + priv->crefs--; + + /* If the count has decremented to zero and the driver has been unlinked, + * then commit Hara-Kiri now. + */ + + if (priv->crefs <= 0 && priv->unlinked) + { + sem_destroy(&priv->exclsem); + kmm_free(priv); + return OK; + } + + sem_post(&priv->exclsem); + return OK; +} +#endif + +/**************************************************************************** + * Name: i2cdrvr_read + ****************************************************************************/ + +static ssize_t i2cdrvr_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + return 0; /* Return EOF */ +} + +/**************************************************************************** + * Name: i2cdrvr_write + ****************************************************************************/ + +static ssize_t i2cdrvr_write(FAR struct file *filep, FAR const char *buffer, + size_t len) +{ + return len; /* Say that everything was written */ +} + +/**************************************************************************** + * Name: i2cdrvr_ioctl + ****************************************************************************/ + +static int i2cdrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct i2c_driver_s *priv; + FAR struct i2c_transfer_s *transfer; + int ret; + + i2cvdbg("cmd=%d arg=%lu\n", cmd, arg); + + /* Get our private data structure */ + + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + + priv = (FAR struct i2c_driver_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Get exclusive access to the I2C driver state structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + int errcode = errno; + DEBUGASSERT(errcode < 0); + return -errcode; + } + + /* Process the IOCTL command */ + + switch (cmd) + { + /* Command: I2CIOC_TRANSFER + * Description: Perform an I2C transfer + * Argument: A reference to an instance of struct i2c_transfer_s. + * Dependencies: CONFIG_I2C_DRIVER + */ + + case I2CIOC_TRANSFER: + { + /* Get the reference to the i2c_transfer_s structure */ + + transfer = (FAR struct i2c_transfer_s *)((uintptr_t)arg); + DEBUGASSERT(transfer != NULL); + + /* Perform the transfer */ + + ret = I2C_TRANSFER(priv->i2c, transfer->msgv, transfer->msgc); + } + break; + +#ifdef CONFIG_I2C_RESET + /* Command: I2CIOC_RESET + * Description: Perform an I2C bus reset in an attempt to break loose + * stuck I2C devices. + * Argument: None + * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET + */ + + case I2CIOC_RESET: + { + ret = I2C_RESET(priv->i2c); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + sem_post(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * Name: i2cdrvr_unlink + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS +static int i2cdrvr_unlink(FAR struct inode *inode) +{ + FAR struct i2c_driver_s *priv; + int ret; + + /* Get our private data structure */ + + DEBUGASSERT(inode != NULL && inode->i_private != NULL); + priv = (FAR struct i2c_driver_s *)inode->i_private; + + /* Get exclusive access to the I2C driver state structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + int errcode = errno; + DEBUGASSERT(errcode < 0); + return -errcode; + } + + /* Are there open references to the driver data structure? */ + + if (priv->crefs <= 0) + { + sem_destroy(&priv->exclsem); + kmm_free(priv); + return OK; + } + + /* No... just mark the driver as unlinked and free the resouces when the + * last client closes their reference to the driver. + */ + + priv->unlinked = true; + sem_post(&priv->exclsem); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2c_register + * + * Description: + * Create and register the I2C character driver. + * + * The I2C character driver is a simple character driver that supports I2C + * transfers. The intent of this driver is to support I2C testing. It is + * not suitable for use in any real driver application. + * + * Input Parameters: + * i2c - An instance of the lower half I2C driver + * bus - The I2C bus number. This will be used as the I2C device minor + * number. The I2C character device will be registered as /dev/i2cN + * where N is the minor number + * + * Returned Value: + * OK if the driver was successfully register; A negated errno value is + * returned on any failure. + * + ****************************************************************************/ + +int i2c_register(FAR struct i2c_master_s *i2c, int bus) +{ + FAR struct i2c_driver_s *priv; + char devname[DEVNAME_FMTLEN]; + int ret; + + /* Sanity check */ + + DEBUGASSERT(i2c != NULL && (unsigned)bus < 1000); + + /* Allocate a I2C character device structure */ + + priv = (FAR struct i2c_driver_s *)kmm_zalloc(sizeof(struct i2c_driver_s)); + if (priv) + { + /* Initialize the I2C character device structure */ + + priv->i2c = i2c; +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + sem_init(&priv->exclsem, 0, 1); +#endif + + /* Create the character device name */ + + snprintf(devname, DEVNAME_FMTLEN, DEVNAME_FMT, bus); + ret = register_driver(devname, &i2cdrvr_fops, 0666, priv); + if (ret < 0) + { + /* Free the device structure if we failed to create the character + * device. + */ + + kmm_free(priv); + } + + /* Return the result of the registration */ + + return OK; + } + + + return -ENOMEM; +} + +#endif /* CONFIG_I2C_DRIVER */ \ No newline at end of file diff --git a/drivers/i2c/i2c_read.c b/drivers/i2c/i2c_read.c new file mode 100644 index 0000000000000000000000000000000000000000..b72523b4eeb88f2a3732dd09dcbab6b795319f4e --- /dev/null +++ b/drivers/i2c/i2c_read.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * drivers/i2c/i2c_read.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2c_read + * + * Description: + * Receive a block of data from I2C. Each read operation will be an + * 'atomic' operation in the sense that any other I2C actions will be + * serialized and pend until this read completes. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to a buffer of data to receive the data from the device + * buflen - The requested number of bytes to be read + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +int i2c_read(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + unsigned int flags; + + /* 7- or 10-bit? */ + + flags = (config->addrlen == 10) ? I2C_M_TEN : 0; + + /* Setup for the transfer */ + + msg.frequency = config->frequency, + msg.addr = config->address, + msg.flags = (flags | I2C_M_READ); + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(dev, &msg, 1); +} diff --git a/drivers/i2c/i2c_write.c b/drivers/i2c/i2c_write.c new file mode 100644 index 0000000000000000000000000000000000000000..30939806c364c5aa7600e4ccdfb345267e710ddc --- /dev/null +++ b/drivers/i2c/i2c_write.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * drivers/i2c/i2c_write.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2c_write + * + * Description: + * Send a block of data on I2C. Each write operation will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this write completes. + * + * Input Parameters: + * dev - Device-specific state data + * config - Described the I2C configuration + * buffer - A pointer to the read-only buffer of data to be written to device + * buflen - The number of bytes to send from the buffer + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +int i2c_write(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR const uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = config->frequency, + msg.addr = config->address; + msg.flags = (config->addrlen == 10) ? I2C_M_TEN : 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(dev, &msg, 1); +} diff --git a/drivers/i2c/i2c_writeread.c b/drivers/i2c/i2c_writeread.c new file mode 100644 index 0000000000000000000000000000000000000000..d5a09fd9e0b04c9f80bfd4b6e32429241cc4a4e0 --- /dev/null +++ b/drivers/i2c/i2c_writeread.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * drivers/i2c/i2c_writeread.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: i2c_writeread + * + * Description: + * Send a block of data on I2C followed by restarted read access. This + * provides a convenient wrapper to the transfer function. + * + * Input Parameters: + * dev - Device-specific state data + * config - Described the I2C configuration + * wbuffer - A pointer to the read-only buffer of data to be written to device + * wbuflen - The number of bytes to send from the buffer + * rbuffer - A pointer to a buffer of data to receive the data from the device + * rbuflen - The requested number of bytes to be read + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +int i2c_writeread(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR const uint8_t *wbuffer, int wbuflen, + FAR uint8_t *rbuffer, int rbuflen) +{ + struct i2c_msg_s msg[2]; + unsigned int flags; + + /* 7- or 10-bit address? */ + + DEBUGASSERT(config->addrlen == 10 || config->addrlen == 7); + flags = (config->addrlen == 10) ? I2C_M_TEN : 0; + + /* Format two messages: The first is a write */ + + msg[0].frequency = config->frequency, + msg[0].addr = config->address; + msg[0].flags = flags; + msg[0].buffer = (FAR uint8_t *)wbuffer; /* Override const */ + msg[0].length = wbuflen; + + /* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with + * no restart. + */ + + if (rbuflen > 0) + { + msg[1].flags = (flags | I2C_M_READ); + } + else + { + msg[1].flags = (flags | I2C_M_NORESTART); + rbuflen = -rbuflen; + } + + msg[1].frequency = config->frequency, + msg[1].addr = config->address; + msg[1].buffer = rbuffer; + msg[1].length = rbuflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(dev, msg, 2); +} + diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index cd2a096a813ee6d4d9d4abc8776322ee753098bf..ebf00232ee4a9cdc1652d013260a0d891b94f960 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -322,6 +322,49 @@ config STMPE811_REGDEBUG endif # INPUT_STMPE811 +config BUTTONS + bool "Button Inputs" + default n + ---help--- + Enable standard button upper half driver. + +if BUTTONS + +config BUTTONS_LOWER + bool "Generic Lower Half Button Dirver" + default n + depends on ARCH_BUTTONS && ARCH_IRQBUTTONS + ---help--- + If the board supports the standard button interfaces as + defined in include/nuttx/board.h header file, then this + standard button lower half driver might be usable. + + In order for this generic driver to be usable: + + 1. The board implementation must provide the button + interfaces as defined in include/nuttx/board.h + 2. The board implementation must support interrupts for each + button. + 3. The board.h header file must provide the definition + NUM_BUTTONS, and + 4. The board.h header file must not include any other + header files that are not accessibble in this context + (such as those in arch//src/) UNLESS those + inclusions are conditioned on __KERNEL__. button_lower.c + will undefine __KERNEL__ before included board.h. + + If your board does not meet these requirements, then the + button_lower.c file can still be copied to your your + board src/ directory and modified for your specific board + requirements. + +config BUTTONS_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + depends on !DISABLE_POLL + +endif # BUTTONS + config DJOYSTICK bool "Discrete Joystick" default n diff --git a/drivers/input/Make.defs b/drivers/input/Make.defs index dc01bda886bb8c67a56ba3af8665751ba8397bdd..8285bfda0f7c9386d782e8f34fbd11891cb151e6 100644 --- a/drivers/input/Make.defs +++ b/drivers/input/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/input/Make.defs # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -71,6 +71,14 @@ ifneq ($(CONFIG_INPUT_STMPE811_TEMP_DISABLE),y) endif endif +ifeq ($(CONFIG_BUTTONS),y) + CSRCS += button_upper.c +ifeq ($(CONFIG_BUTTONS_LOWER),y) + CSRCS += button_lower.c +endif + +endif + ifeq ($(CONFIG_DJOYSTICK),y) CSRCS += djoystick.c endif diff --git a/drivers/input/ads7843e.c b/drivers/input/ads7843e.c index f23fc7d5db238af93ce1b2e43e898b32ebf383b9..22b7606e63f9a1476d5bc2c316454e6552db5556 100644 --- a/drivers/input/ads7843e.c +++ b/drivers/input/ads7843e.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/input/ads7843e.c * - * Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * Diego Sanchez * @@ -63,6 +63,7 @@ #include #include +#include #include #include #include @@ -94,15 +95,8 @@ ****************************************************************************/ /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void ads7843e_configspi(FAR struct spi_dev_s *spi); -# define ads7843e_lock(spi) -# define ads7843e_unlock(spi) -#else -# define ads7843e_configspi(spi); static void ads7843e_lock(FAR struct spi_dev_s *spi); static void ads7843e_unlock(FAR struct spi_dev_s *spi); -#endif static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd); @@ -180,7 +174,6 @@ static struct ads7843e_dev_s *g_ads7843elist; * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void ads7843e_lock(FAR struct spi_dev_s *spi) { /* Lock the SPI bus because there are multiple devices competing for the @@ -197,18 +190,17 @@ static void ads7843e_lock(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY); SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); } -#endif /**************************************************************************** * Function: ads7843e_unlock * * Description: - * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS - * undefined) then we need to un-lock the SPI bus for each transfer, - * possibly losing the current configuration. + * Un-lock the SPI bus after each transfer, possibly losing the current + * configuration if we are sharing the bus with other devices. * * Parameters: * spi - Reference to the SPI driver structure @@ -220,48 +212,12 @@ static void ads7843e_lock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void ads7843e_unlock(FAR struct spi_dev_s *spi) { /* Relinquish the SPI bus. */ (void)SPI_LOCK(spi, false); } -#endif - -/**************************************************************************** - * Function: ads7843e_configspi - * - * Description: - * Configure the SPI for use with the ADS7843E. This function should be - * called once during touchscreen initialization to configure the SPI - * bus. Note that if CONFIG_SPI_OWNBUS is not defined, then this function - * does nothing. - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ads7843e_configspi(FAR struct spi_dev_s *spi) -{ - /* Configure SPI for the ADS7843. But only if we own the SPI bus. - * Otherwise, don't bother because it might change. - */ - - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); - SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY); - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); -} -#endif /**************************************************************************** * Name: ads7843e_sendcmd @@ -385,7 +341,7 @@ static int ads7843e_sample(FAR struct ads7843e_dev_s *priv, * from changing until it has been reported. */ - flags = irqsave(); + flags = enter_critical_section(); /* Is there new ADS7843E sample data available? */ @@ -395,7 +351,7 @@ static int ads7843e_sample(FAR struct ads7843e_dev_s *priv, * sampled data. */ - memcpy(sample, &priv->sample, sizeof(struct ads7843e_sample_s )); + memcpy(sample, &priv->sample, sizeof(struct ads7843e_sample_s)); /* Now manage state transitions */ @@ -420,7 +376,7 @@ static int ads7843e_sample(FAR struct ads7843e_dev_s *priv, ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -443,7 +399,7 @@ static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv, */ sched_lock(); - flags = irqsave(); + flags = enter_critical_section(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to @@ -480,7 +436,7 @@ static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv, ivdbg("Sampled\n"); - /* Re-acquire the semaphore that manages mutually exclusive access to + /* Re-acquire the semaphore that manages mutually exclusive access to * the device structure. We may have to wait here. But we have our sample. * Interrupts and pre-emption will be re-enabled while we wait. */ @@ -493,7 +449,7 @@ errout: * have pre-emption disabled. */ - irqrestore(flags); + leave_critical_section(flags); /* Restore pre-emption. We might get suspended here but that is okay * because we already have our sample. Note: this means that if there @@ -974,10 +930,10 @@ static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t le if (sample.contact == CONTACT_UP) { - /* Pen is now up. Is the positional data valid? This is important to - * know because the release will be sent to the window based on its - * last positional data. - */ + /* Pen is now up. Is the positional data valid? This is important to + * know because the release will be sent to the window based on its + * last positional data. + */ if (sample.valid) { @@ -1252,10 +1208,6 @@ int ads7843e_register(FAR struct spi_dev_s *spi, ads7843e_lock(spi); - /* Configure the SPI interface */ - - ads7843e_configspi(spi); - /* Enable the PEN IRQ */ ads7843e_sendcmd(priv, ADS7843_CMD_ENABPENIRQ); @@ -1284,7 +1236,7 @@ int ads7843e_register(FAR struct spi_dev_s *spi, #ifdef CONFIG_ADS7843E_MULTIPLE priv->flink = g_ads7843elist; g_ads7843elist = priv; - irqrestore(flags); + leave_critical_section(flags); #endif /* Schedule work to perform the initial sampling and to set the data diff --git a/drivers/input/ajoystick.c b/drivers/input/ajoystick.c index de4d52f4040c319e1f96e44db7e656632cee7539..6c916d9f398e44e6b578c904be0d574ab12ec773 100644 --- a/drivers/input/ajoystick.c +++ b/drivers/input/ajoystick.c @@ -61,17 +61,17 @@ #include #include -#include +#include /**************************************************************************** * Private Types ****************************************************************************/ -/* This structure provides the state of one discrete joystick driver */ +/* This structure provides the state of one analog joystick driver */ struct ajoy_upperhalf_s { - /* Saved binding to the lower half discrete joystick driver */ + /* Saved binding to the lower half analog joystick driver */ FAR const struct ajoy_lowerhalf_s *au_lower; @@ -143,7 +143,8 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv); static int ajoy_open(FAR struct file *filep); static int ajoy_close(FAR struct file *filep); -static ssize_t ajoy_read(FAR struct file *, FAR char *, size_t); +static ssize_t ajoy_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); static int ajoy_ioctl(FAR struct file *filep, int cmd, unsigned long arg); #ifndef CONFIG_DISABLE_POLL @@ -215,7 +216,7 @@ static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv) * interrupts must be disabled. */ - flags = irqsave(); + flags = enter_critical_section(); /* Visit each opened reference to the device */ @@ -265,7 +266,7 @@ static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv) lower->al_enable(lower, 0, 0, NULL, NULL); } - irqrestore(flags); + leave_critical_section(flags); } #endif @@ -313,7 +314,7 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv) * interrupts must be disabled. */ - flags = irqsave(); + flags = enter_critical_section(); /* Sample the new button state */ @@ -385,7 +386,7 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv) #endif priv->au_sample = sample; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -484,10 +485,10 @@ static int ajoy_close(FAR struct file *filep) * detection anyway. */ - flags = irqsave(); + flags = enter_critical_section(); closing = opriv->ao_closing; opriv->ao_closing = true; - irqrestore(flags); + leave_critical_section(flags); if (closing) { @@ -822,15 +823,15 @@ errout_with_dusem: * Name: ajoy_register * * Description: - * Bind the lower half discrete joystick driver to an instance of the - * upper half discrete joystick driver and register the composite character + * Bind the lower half analog joystick driver to an instance of the + * upper half analog joystick driver and register the composite character * driver as the specific device. * * Input Parameters: - * devname - The name of the discrete joystick device to be registers. + * devname - The name of the analog joystick device to be registers. * This should be a string of the form "/priv/ajoyN" where N is the the * minor device number. - * lower - An instance of the platform-specific discrete joystick lower + * lower - An instance of the platform-specific analog joystick lower * half driver. * * Returned Values: diff --git a/drivers/input/button_lower.c b/drivers/input/button_lower.c new file mode 100644 index 0000000000000000000000000000000000000000..868e1681a61249b168029f07d46e3c5daae95ddc --- /dev/null +++ b/drivers/input/button_lower.c @@ -0,0 +1,237 @@ +/**************************************************************************** + * drivers/input/button_lower.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include + +#undef __KERNEL__ +#include + +#if CONFIG_BUTTONS_LOWER + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static btn_buttonset_t btn_supported(FAR const struct btn_lowerhalf_s *lower); +static btn_buttonset_t btn_buttons(FAR const struct btn_lowerhalf_s *lower); +static void btn_enable(FAR const struct btn_lowerhalf_s *lower, + btn_buttonset_t press, btn_buttonset_t release, + btn_handler_t handler, FAR void *arg); + +static void btn_disable(void); +static int btn_interrupt(int irq, FAR void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the button button lower half driver interface */ + +static const struct btn_lowerhalf_s g_btnlower = +{ + .bl_supported = btn_supported, + .bl_buttons = btn_buttons, + .bl_enable = btn_enable, +}; + +/* Current interrupt handler and argument */ + +static btn_handler_t g_btnhandler; +static FAR void *g_btnarg; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_supported + * + * Description: + * Return the set of buttons supported + * + ****************************************************************************/ + +static btn_buttonset_t btn_supported(FAR const struct btn_lowerhalf_s *lower) +{ + ivdbg("NUM_BUTTONS: %02x\n", NUM_BUTTONS); + return (btn_buttonset_t)((1 << NUM_BUTTONS) - 1); +} + +/**************************************************************************** + * Name: btn_buttons + * + * Description: + * Return the current state of button data + * + ****************************************************************************/ + +static btn_buttonset_t btn_buttons(FAR const struct btn_lowerhalf_s *lower) +{ + return board_buttons(); +} + +/**************************************************************************** + * Name: btn_enable + * + * Description: + * Enable interrupts on the selected set of buttons. And empty set or + * a NULL handler will disable all interrupts. + * + ****************************************************************************/ + +static void btn_enable(FAR const struct btn_lowerhalf_s *lower, + btn_buttonset_t press, btn_buttonset_t release, + btn_handler_t handler, FAR void *arg) +{ + btn_buttonset_t mask; + btn_buttonset_t either = press | release; + irqstate_t flags; + int id; + + /* Start with all interrupts disabled */ + + flags = enter_critical_section(); + btn_disable(); + + illvdbg("press: %02x release: %02x handler: %p arg: %p\n", + press, release, handler, arg); + + /* If no events are indicated or if no handler is provided, then this + * must really be a request to disable interrupts. + */ + + if (either && handler) + { + /* Save the new the handler and argument */ + + g_btnhandler = handler; + g_btnarg = arg; + + /* Attach and enable each button interrupt */ + + for (id = 0; id < NUM_BUTTONS; id++) + { + mask = (1 << id); + if ((either & mask) != 0) + { + (void)board_button_irq(id, btn_interrupt); + } + } + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: btn_disable + * + * Description: + * Disable all button interrupts + * + ****************************************************************************/ + +static void btn_disable(void) +{ + irqstate_t flags; + int id; + + /* Disable each button interrupt */ + + flags = enter_critical_section(); + for (id = 0; id < NUM_BUTTONS; id++) + { + (void)board_button_irq(id, NULL); + } + + /* Nullify the handler and argument */ + + g_btnhandler = NULL; + g_btnarg = NULL; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: btn_interrupt + * + * Description: + * Discrete button interrupt handler (all buttons) + * + ****************************************************************************/ + +static int btn_interrupt(int irq, FAR void *context) +{ + DEBUGASSERT(g_btnhandler); + + if (g_btnhandler) + { + g_btnhandler(&g_btnlower, g_btnarg); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_lower_initialize + * + * Description: + * Initialize the generic button lower half driver, bind it and register + * it with the upper half button driver as devname. + * + ****************************************************************************/ + +int btn_lower_initialize(FAR const char *devname) +{ + board_button_initialize(); + return btn_register(devname, &g_btnlower); +} + +#endif /* CONFIG_BUTTONS_LOWER */ diff --git a/drivers/input/button_upper.c b/drivers/input/button_upper.c new file mode 100644 index 0000000000000000000000000000000000000000..5eadfd87e3b57daf34d9d6b2e677b0ede7f4c15d --- /dev/null +++ b/drivers/input/button_upper.c @@ -0,0 +1,882 @@ +/**************************************************************************** + * drivers/input/button_upper.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 file provides a driver for a button input devices. + * + * The buttons driver exports a standard character driver interface. By + * convention, the button driver is registered as an input device at + * /dev/btnN where N uniquely identifies the driver instance. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the state of one button driver */ + +struct btn_upperhalf_s +{ + /* Saved binding to the lower half button driver */ + + FAR const struct btn_lowerhalf_s *bu_lower; + + btn_buttonset_t bu_enabled; /* Set of currently enabled button interrupts */ + btn_buttonset_t bu_sample; /* Last sampled button states */ + sem_t bu_exclsem; /* Supports exclusive access to the device */ + + /* The following is a singly linked list of open references to the + * button device. + */ + + FAR struct btn_open_s *bu_open; +}; + +/* This structure describes the state of one open button driver instance */ + +struct btn_open_s +{ + /* Supports a singly linked list */ + + FAR struct btn_open_s *bo_flink; + + /* The following will be true if we are closing */ + + volatile bool bo_closing; + +#ifndef CONFIG_DISABLE_SIGNALS + /* Button event notification information */ + + pid_t bo_pid; + struct btn_notify_s bo_notify; +#endif + +#ifndef CONFIG_DISABLE_POLL + /* Poll event information */ + + struct btn_pollevents_s bo_pollevents; + + /* The following is a list if poll structures of threads waiting for + * driver events. + */ + + FAR struct pollfd *bo_fds[CONFIG_BUTTONS_NPOLLWAITERS]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Semaphore helpers */ + +static inline int btn_takesem(sem_t *sem); +#define btn_givesem(s) sem_post(s); + +/* Sampling and Interrupt handling */ + +#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) +static void btn_enable(FAR struct btn_upperhalf_s *priv); +static void btn_interrupt(FAR const struct btn_lowerhalf_s *lower, + FAR void *arg); +#endif + +/* Sampling */ + +static void btn_sample(FAR struct btn_upperhalf_s *priv); + +/* Character driver methods */ + +static int btn_open(FAR struct file *filep); +static int btn_close(FAR struct file *filep); +static ssize_t btn_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int btn_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +#ifndef CONFIG_DISABLE_POLL +static int btn_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations btn_fops = +{ + btn_open, /* open */ + btn_close, /* close */ + btn_read, /* read */ + 0, /* write */ + 0, /* seek */ + btn_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , btn_poll /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_takesem + ****************************************************************************/ + +static inline int btn_takesem(sem_t *sem) +{ + /* Take a count from the semaphore, possibly waiting */ + + if (sem_wait(sem) < 0) + { + /* EINTR is the only error that we expect */ + + int errcode = get_errno(); + DEBUGASSERT(errcode == EINTR); + return -errcode; + } + + return OK; +} + +/**************************************************************************** + * Name: btn_enable + ****************************************************************************/ + +#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) +static void btn_enable(FAR struct btn_upperhalf_s *priv) +{ + FAR const struct btn_lowerhalf_s *lower = priv->bu_lower; + FAR struct btn_open_s *opriv; + btn_buttonset_t press; + btn_buttonset_t release; + irqstate_t flags; +#ifndef CONFIG_DISABLE_POLL + int i; +#endif + + DEBUGASSERT(priv && priv->bu_lower); + lower = priv->bu_lower; + + /* This routine is called both task level and interrupt level, so + * interrupts must be disabled. + */ + + flags = enter_critical_section(); + + /* Visit each opened reference to the device */ + + press = 0; + release = 0; + + for (opriv = priv->bu_open; opriv; opriv = opriv->bo_flink) + { +#ifndef CONFIG_DISABLE_POLL + /* Are there any poll waiters? */ + + for (i = 0; i < CONFIG_BUTTONS_NPOLLWAITERS; i++) + { + if (opriv->bo_fds[i]) + { + /* Yes.. OR in the poll event buttons */ + + press |= opriv->bo_pollevents.ap_press; + release |= opriv->bo_pollevents.ap_release; + break; + } + } +#endif + +#ifndef CONFIG_DISABLE_SIGNALS + /* OR in the signal events */ + + press |= opriv->bo_notify.bn_press; + release |= opriv->bo_notify.bn_release; +#endif + } + + /* Enable/disable button interrupts */ + + DEBUGASSERT(lower->bl_enable); + if (press != 0 || release != 0) + { + /* Enable interrupts with the new button set */ + + lower->bl_enable(lower, press, release, + (btn_handler_t)btn_interrupt, priv); + } + else + { + /* Disable further interrupts */ + + lower->bl_enable(lower, 0, 0, NULL, NULL); + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: btn_interrupt + ****************************************************************************/ + +#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) +static void btn_interrupt(FAR const struct btn_lowerhalf_s *lower, + FAR void *arg) +{ + FAR struct btn_upperhalf_s *priv = (FAR struct btn_upperhalf_s *)arg; + + DEBUGASSERT(priv); + + /* Process the next sample */ + + btn_sample(priv); +} +#endif + +/**************************************************************************** + * Name: btn_sample + ****************************************************************************/ + +static void btn_sample(FAR struct btn_upperhalf_s *priv) +{ + FAR const struct btn_lowerhalf_s *lower = priv->bu_lower; + FAR struct btn_open_s *opriv; + btn_buttonset_t sample; +#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) + btn_buttonset_t change; + btn_buttonset_t press; + btn_buttonset_t release; +#endif + irqstate_t flags; +#ifndef CONFIG_DISABLE_POLL + int i; +#endif + + DEBUGASSERT(priv && priv->bu_lower); + lower = priv->bu_lower; + + /* This routine is called both task level and interrupt level, so + * interrupts must be disabled. + */ + + flags = enter_critical_section(); + + /* Sample the new button state */ + + DEBUGASSERT(lower->bl_buttons); + sample = lower->bl_buttons(lower); + +#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) + /* Determine which buttons have been newly pressed and which have been + * newly released. + */ + + change = sample ^ priv->bu_sample; + press = change & sample; + + DEBUGASSERT(lower->bl_supported); + release = change & (lower->bl_supported(lower) & ~sample); + + /* Visit each opened reference to the device */ + + for (opriv = priv->bu_open; opriv; opriv = opriv->bo_flink) + { +#ifndef CONFIG_DISABLE_POLL + /* Have any poll events occurred? */ + + if ((press & opriv->bo_pollevents.ap_press) != 0 || + (release & opriv->bo_pollevents.ap_release) != 0) + { + /* Yes.. Notify all waiters */ + + for (i = 0; i < CONFIG_BUTTONS_NPOLLWAITERS; i++) + { + FAR struct pollfd *fds = opriv->bo_fds[i]; + if (fds) + { + fds->revents |= (fds->events & POLLIN); + if (fds->revents != 0) + { + ivdbg("Report events: %02x\n", fds->revents); + sem_post(fds->sem); + } + } + } + } +#endif + +#ifndef CONFIG_DISABLE_SIGNALS + /* Have any signal events occurred? */ + + if ((press & opriv->bo_notify.bn_press) != 0 || + (release & opriv->bo_notify.bn_release) != 0) + { + /* Yes.. Signal the waiter */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; + value.sival_int = (int)sample; + (void)sigqueue(opriv->bo_pid, opriv->bo_notify.bn_signo, value); +#else + (void)sigqueue(opriv->bo_pid, opriv->bo_notify.dn.signo, + (FAR void *)sample); +#endif + } +#endif + } + + /* Enable/disable interrupt handling */ + + btn_enable(priv); +#endif + + priv->bu_sample = sample; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: btn_open + ****************************************************************************/ + +static int btn_open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct btn_upperhalf_s *priv; + FAR struct btn_open_s *opriv; +#ifndef CONFIG_DISABLE_POLL + FAR const struct btn_lowerhalf_s *lower; + btn_buttonset_t supported; +#endif + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct btn_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = btn_takesem(&priv->bu_exclsem); + if (ret < 0) + { + ivdbg("ERROR: btn_takesem failed: %d\n", ret); + return ret; + } + + /* Allocate a new open structure */ + + opriv = (FAR struct btn_open_s *)kmm_zalloc(sizeof(struct btn_open_s)); + if (!opriv) + { + ivdbg("ERROR: Failled to allocate open structure\n"); + ret = -ENOMEM; + goto errout_with_sem; + } + + /* Initialize the open structure */ + +#ifndef CONFIG_DISABLE_POLL + lower = priv->bu_lower; + DEBUGASSERT(lower && lower->bl_supported); + supported = lower->bl_supported(lower); + + opriv->bo_pollevents.ap_press = supported; + opriv->bo_pollevents.ap_release = supported; +#endif + + /* Attach the open structure to the device */ + + opriv->bo_flink = priv->bu_open; + priv->bu_open = opriv; + + /* Attach the open structure to the file structure */ + + filep->f_priv = (FAR void *)opriv; + ret = OK; + +errout_with_sem: + btn_givesem(&priv->bu_exclsem); + return ret; +} + +/**************************************************************************** + * Name: btn_close + ****************************************************************************/ + +static int btn_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct btn_upperhalf_s *priv; + FAR struct btn_open_s *opriv; + FAR struct btn_open_s *curr; + FAR struct btn_open_s *prev; + irqstate_t flags; + bool closing; + int ret; + + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct btn_upperhalf_s *)inode->i_private; + + /* Handle an improbable race conditions with the following atomic test + * and set. + * + * This is actually a pretty feeble attempt to handle this. The + * improbable race condition occurs if two different threads try to + * close the button driver at the same time. The rule: don't do + * that! It is feeble because we do not really enforce stale pointer + * detection anyway. + */ + + flags = enter_critical_section(); + closing = opriv->bo_closing; + opriv->bo_closing = true; + leave_critical_section(flags); + + if (closing) + { + /* Another thread is doing the close */ + + return OK; + } + + /* Get exclusive access to the driver structure */ + + ret = btn_takesem(&priv->bu_exclsem); + if (ret < 0) + { + ivdbg("ERROR: btn_takesem failed: %d\n", ret); + return ret; + } + + /* Find the open structure in the list of open structures for the device */ + + for (prev = NULL, curr = priv->bu_open; + curr && curr != opriv; + prev = curr, curr = curr->bo_flink); + + DEBUGASSERT(curr); + if (!curr) + { + ivdbg("ERROR: Failed to find open entry\n"); + ret = -ENOENT; + goto errout_with_exclsem; + } + + /* Remove the structure from the device */ + + if (prev) + { + prev->bo_flink = opriv->bo_flink; + } + else + { + priv->bu_open = opriv->bo_flink; + } + + /* And free the open structure */ + + kmm_free(opriv); + + /* Enable/disable interrupt handling */ + + btn_enable(priv); + ret = OK; + +errout_with_exclsem: + btn_givesem(&priv->bu_exclsem); + return ret; +} + +/**************************************************************************** + * Name: btn_read + ****************************************************************************/ + +static ssize_t btn_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + FAR struct inode *inode; + FAR struct btn_upperhalf_s *priv; + FAR const struct btn_lowerhalf_s *lower; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct btn_upperhalf_s *)inode->i_private; + + /* Make sure that the buffer is sufficiently large to hold at least one + * complete sample. + * + * REVISIT: Should also check buffer alignment. + */ + + if (len < sizeof(btn_buttonset_t)) + { + ivdbg("ERROR: buffer too small: %lu\n", (unsigned long)len); + return -EINVAL; + } + + /* Get exclusive access to the driver structure */ + + ret = btn_takesem(&priv->bu_exclsem); + if (ret < 0) + { + ivdbg("ERROR: btn_takesem failed: %d\n", ret); + return ret; + } + + /* Read and return the current state of the buttons */ + + lower = priv->bu_lower; + DEBUGASSERT(lower && lower->bl_buttons); + *(FAR btn_buttonset_t *)buffer = lower->bl_buttons(lower); + + btn_givesem(&priv->bu_exclsem); + return (ssize_t)sizeof(btn_buttonset_t); +} + +/**************************************************************************** + * Name: btn_ioctl + ****************************************************************************/ + +static int btn_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct btn_upperhalf_s *priv; + FAR struct btn_open_s *opriv; + FAR const struct btn_lowerhalf_s *lower; + int ret; + + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct btn_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = btn_takesem(&priv->bu_exclsem); + if (ret < 0) + { + ivdbg("ERROR: btn_takesem failed: %d\n", ret); + return ret; + } + + /* Handle the ioctl command */ + + ret = -EINVAL; + switch (cmd) + { + /* Command: BTNIOC_SUPPORTED + * Description: Report the set of button events supported by the hardware; + * Argument: A pointer to writeable integer value in which to return the + * set of supported buttons. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + + case BTNIOC_SUPPORTED: + { + FAR btn_buttonset_t *supported = (FAR btn_buttonset_t *)((uintptr_t)arg); + + if (supported) + { + lower = priv->bu_lower; + DEBUGASSERT(lower && lower->bl_supported); + + *supported = lower->bl_supported(lower); + ret = OK; + } + } + break; + +#ifndef CONFIG_DISABLE_POLL + /* Command: BTNIOC_POLLEVENTS + * Description: Specify the set of button events that can cause a poll() + * to awaken. The default is all button depressions and + * all button releases (all supported buttons); + * Argument: A read-only pointer to an instance of struct + * btn_pollevents_s + * Return: Zero (OK) on success. Minus one will be returned on + * failure with the errno value set appropriately. + */ + + case BTNIOC_POLLEVENTS: + { + FAR struct btn_pollevents_s *pollevents = + (FAR struct btn_pollevents_s *)((uintptr_t)arg); + + if (pollevents) + { + /* Save the poll events */ + + opriv->bo_pollevents.ap_press = pollevents->ap_press; + opriv->bo_pollevents.ap_release = pollevents->ap_release; + + /* Enable/disable interrupt handling */ + + btn_enable(priv); + ret = OK; + } + } + break; +#endif + +#ifndef CONFIG_DISABLE_SIGNALS + /* Command: BTNIOC_REGISTER + * Description: Register to receive a signal whenever there is a change + * in any of the discrete buttone inputs. This feature, + * of course, depends upon interrupt GPIO support from the + * platform. + * Argument: A read-only pointer to an instance of struct + * btn_notify_s + * Return: Zero (OK) on success. Minus one will be returned on + * failure with the errno value set appropriately. + */ + + case BTNIOC_REGISTER: + { + FAR struct btn_notify_s *notify = + (FAR struct btn_notify_s *)((uintptr_t)arg); + + if (notify) + { + /* Save the notification events */ + + opriv->bo_notify.bn_press = notify->bn_press; + opriv->bo_notify.bn_release = notify->bn_release; + opriv->bo_notify.bn_signo = notify->bn_signo; + opriv->bo_pid = getpid(); + + /* Enable/disable interrupt handling */ + + btn_enable(priv); + ret = OK; + } + } + break; +#endif + + default: + ivdbg("ERROR: Unrecognized command: %ld\n", cmd); + ret = -ENOTTY; + break; + } + + btn_givesem(&priv->bu_exclsem); + return ret; +} + +/**************************************************************************** + * Name: btn_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int btn_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + FAR struct inode *inode; + FAR struct btn_upperhalf_s *priv; + FAR struct btn_open_s *opriv; + int ret; + int i; + + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct btn_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = btn_takesem(&priv->bu_exclsem); + if (ret < 0) + { + ivdbg("ERROR: btn_takesem failed: %d\n", ret); + return ret; + } + + /* Are we setting up the poll? Or tearing it down? */ + + if (setup) + { + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference + */ + + for (i = 0; i < CONFIG_BUTTONS_NPOLLWAITERS; i++) + { + /* Find an available slot */ + + if (!opriv->bo_fds[i]) + { + /* Bind the poll structure and this slot */ + + opriv->bo_fds[i] = fds; + fds->priv = &opriv->bo_fds[i]; + break; + } + } + + if (i >= CONFIG_BUTTONS_NPOLLWAITERS) + { + ivdbg("ERROR: Too man poll waiters\n"); + fds->priv = NULL; + ret = -EBUSY; + goto errout_with_dusem; + } + } + else if (fds->priv) + { + /* This is a request to tear down the poll. */ + + FAR struct pollfd **slot = (FAR struct pollfd **)fds->priv; + +#ifdef CONFIG_DEBUG + if (!slot) + { + ivdbg("ERROR: Poll slot not found\n"); + ret = -EIO; + goto errout_with_dusem; + } +#endif + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->priv = NULL; + } + +errout_with_dusem: + btn_givesem(&priv->bu_exclsem); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_register + * + * Description: + * Bind the lower half button driver to an instance of the upper half + * button driver and register the composite character driver as the + * specified device. + * + * Input Parameters: + * devname - The name of the button device to be registered. + * This should be a string of the form "/dev/btnN" where N is the the + * minor device number. + * lower - An instance of the platform-specific button lower half driver. + * + * Returned Values: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int btn_register(FAR const char *devname, + FAR const struct btn_lowerhalf_s *lower) + +{ + FAR struct btn_upperhalf_s *priv; + int ret; + + DEBUGASSERT(devname && lower); + + /* Allocate a new button driver instance */ + + priv = (FAR struct btn_upperhalf_s *) + kmm_zalloc(sizeof(struct btn_upperhalf_s)); + + if (!priv) + { + ivdbg("ERROR: Failed to allocate device structure\n"); + return -ENOMEM; + } + + /* Make sure that all button interrupts are disabled */ + + DEBUGASSERT(lower->bl_enable); + lower->bl_enable(lower, 0, 0, NULL, NULL); + + /* Initialize the new button driver instance */ + + priv->bu_lower = lower; + sem_init(&priv->bu_exclsem, 0, 1); + + DEBUGASSERT(lower->bl_buttons); + priv->bu_sample = lower->bl_buttons(lower); + + /* And register the button driver */ + + ret = register_driver(devname, &btn_fops, 0666, priv); + if (ret < 0) + { + ivdbg("ERROR: register_driver failed: %d\n", ret); + goto errout_with_priv; + } + + return OK; + +errout_with_priv: + sem_destroy(&priv->bu_exclsem); + kmm_free(priv); + return ret; +} diff --git a/drivers/input/djoystick.c b/drivers/input/djoystick.c index 0e746634f2904eb7394cdd3386d3e96880e3ef95..5ea4cd7d28d54eeb16d6f1900e63b97fe17a88bf 100644 --- a/drivers/input/djoystick.c +++ b/drivers/input/djoystick.c @@ -61,7 +61,7 @@ #include #include -#include +#include /**************************************************************************** * Private Types @@ -143,7 +143,8 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv); static int djoy_open(FAR struct file *filep); static int djoy_close(FAR struct file *filep); -static ssize_t djoy_read(FAR struct file *, FAR char *, size_t); +static ssize_t djoy_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); static int djoy_ioctl(FAR struct file *filep, int cmd, unsigned long arg); #ifndef CONFIG_DISABLE_POLL @@ -215,7 +216,7 @@ static void djoy_enable(FAR struct djoy_upperhalf_s *priv) * interrupts must be disabled. */ - flags = irqsave(); + flags = enter_critical_section(); /* Visit each opened reference to the device */ @@ -265,7 +266,7 @@ static void djoy_enable(FAR struct djoy_upperhalf_s *priv) lower->dl_enable(lower, 0, 0, NULL, NULL); } - irqrestore(flags); + leave_critical_section(flags); } #endif @@ -313,7 +314,7 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv) * interrupts must be disabled. */ - flags = irqsave(); + flags = enter_critical_section(); /* Sample the new button state */ @@ -385,7 +386,7 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv) #endif priv->du_sample = sample; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -484,10 +485,10 @@ static int djoy_close(FAR struct file *filep) * detection anyway. */ - flags = irqsave(); + flags = enter_critical_section(); closing = opriv->do_closing; opriv->do_closing = true; - irqrestore(flags); + leave_critical_section(flags); if (closing) { @@ -585,7 +586,7 @@ static ssize_t djoy_read(FAR struct file *filep, FAR char *buffer, lower = priv->du_lower; DEBUGASSERT(lower && lower->dl_sample); priv->du_sample = lower->dl_sample(lower); - *(djoy_buttonset_t*)buffer = priv->du_sample; + *(FAR djoy_buttonset_t *)buffer = priv->du_sample; ret = sizeof(djoy_buttonset_t); djoy_givesem(&priv->du_exclsem); diff --git a/drivers/input/max11802.c b/drivers/input/max11802.c index c61b48188d5de47247b5872488b0c5e9cdad8b5d..2c3c1f7813307a249bf480cbcc5d78c25c4abc68 100644 --- a/drivers/input/max11802.c +++ b/drivers/input/max11802.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/input/max11802.c * - * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2014-2016 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * Petteri Aimonen * @@ -57,6 +57,7 @@ #include #include +#include #include #include #include @@ -88,16 +89,8 @@ ****************************************************************************/ /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void max11802_configspi(FAR struct spi_dev_s *spi); -# define max11802_lock(spi) -# define max11802_unlock(spi) -#else -# define max11802_configspi(spi); static void max11802_lock(FAR struct spi_dev_s *spi); static void max11802_unlock(FAR struct spi_dev_s *spi); -#endif - static uint16_t max11802_sendcmd(FAR struct max11802_dev_s *priv, uint8_t cmd, int *tags); @@ -181,7 +174,6 @@ static struct max11802_dev_s *g_max11802list; * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void max11802_lock(FAR struct spi_dev_s *spi) { /* Lock the SPI bus because there are multiple devices competing for the @@ -197,17 +189,16 @@ static void max11802_lock(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_MAX11802_SPIMODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_MAX11802_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_MAX11802_FREQUENCY); } -#endif /**************************************************************************** * Function: max11802_unlock * * Description: - * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS - * undefined) then we need to un-lock the SPI bus for each transfer, - * possibly losing the current configuration. + * Un-lock the SPI bus after each transfer, possibly losing the current + * configuration if we are sharing the SPI bus with other devices * * Parameters: * spi - Reference to the SPI driver structure @@ -219,46 +210,12 @@ static void max11802_lock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void max11802_unlock(FAR struct spi_dev_s *spi) { /* Relinquish the SPI bus. */ (void)SPI_LOCK(spi, false); } -#endif - -/**************************************************************************** - * Function: max11802_configspi - * - * Description: - * Configure the SPI for use with the MAX11802. This function should be - * called once during touchscreen initialization to configure the SPI - * bus. Note that if CONFIG_SPI_OWNBUS is not defined, then this function - * does nothing. - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void max11802_configspi(FAR struct spi_dev_s *spi) -{ - /* Configure SPI for the MAX11802. But only if we own the SPI bus. - * Otherwise, don't bother because it might change. - */ - - SPI_SETMODE(spi, CONFIG_MAX11802_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_MAX11802_FREQUENCY); -} -#endif /**************************************************************************** * Name: max11802_sendcmd @@ -285,7 +242,7 @@ static uint16_t max11802_sendcmd(FAR struct max11802_dev_s *priv, result = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1]; *tags = result & 0xF; - result >>= 4; // Get rid of tags + result >>= 4; /* Get rid of tags */ ivdbg("cmd:%02x response:%04x\n", cmd, result); return result; @@ -349,7 +306,7 @@ static int max11802_sample(FAR struct max11802_dev_s *priv, * from changing until it has been reported. */ - flags = irqsave(); + flags = enter_critical_section(); /* Is there new MAX11802 sample data available? */ @@ -359,7 +316,7 @@ static int max11802_sample(FAR struct max11802_dev_s *priv, * sampled data. */ - memcpy(sample, &priv->sample, sizeof(struct max11802_sample_s )); + memcpy(sample, &priv->sample, sizeof(struct max11802_sample_s)); /* Now manage state transitions */ @@ -384,7 +341,7 @@ static int max11802_sample(FAR struct max11802_dev_s *priv, ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -407,7 +364,7 @@ static int max11802_waitsample(FAR struct max11802_dev_s *priv, */ sched_lock(); - flags = irqsave(); + flags = enter_critical_section(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to @@ -457,7 +414,7 @@ errout: * have pre-emption disabled. */ - irqrestore(flags); + leave_critical_section(flags); /* Restore pre-emption. We might get suspended here but that is okay * because we already have our sample. Note: this means that if there @@ -980,10 +937,10 @@ static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer, if (sample.contact == CONTACT_UP) { - /* Pen is now up. Is the positional data valid? This is important to - * know because the release will be sent to the window based on its - * last positional data. - */ + /* Pen is now up. Is the positional data valid? This is important to + * know because the release will be sent to the window based on its + * last positional data. + */ if (sample.valid) { @@ -1254,11 +1211,8 @@ int max11802_register(FAR struct spi_dev_s *spi, max11802_lock(spi); - /* Configure the SPI interface */ - - max11802_configspi(spi); - /* Configure MAX11802 registers */ + SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true); (void)SPI_SEND(priv->spi, MAX11802_CMD_MODE_WR); (void)SPI_SEND(priv->spi, MAX11802_MODE); @@ -1314,10 +1268,10 @@ int max11802_register(FAR struct spi_dev_s *spi, */ #ifdef CONFIG_MAX11802_MULTIPLE - flags = irqsave(); + flags = enter_critical_section(); priv->flink = g_max11802list; g_max11802list = priv; - irqrestore(flags); + leave_critical_section(flags); #endif /* Schedule work to perform the initial sampling and to set the data diff --git a/drivers/input/mxt.c b/drivers/input/mxt.c index ca28f936e096457af07c68a8853d1591bae34152..1b370e9579be5154753636c5615bbd833c89f5d6 100644 --- a/drivers/input/mxt.c +++ b/drivers/input/mxt.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/input/mxt.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -58,10 +58,11 @@ #include #include +#include #include #include #include -#include +#include #include #include @@ -92,8 +93,8 @@ */ #define MXT_GETUINT16(p) \ - (((uint16_t)(((FAR uint8_t*)(p))[1]) << 8) | \ - (uint16_t)(((FAR uint8_t*)(p))[0])) + (((uint16_t)(((FAR uint8_t *)(p))[1]) << 8) | \ + (uint16_t)(((FAR uint8_t *)(p))[0])) /**************************************************************************** * Private Types @@ -165,7 +166,7 @@ struct mxt_dev_s * lower half configuration data. */ - FAR struct i2c_dev_s *i2c; + FAR struct i2c_master_s *i2c; FAR const struct mxt_lower_s *lower; /* This is the allocated array of object information */ @@ -315,20 +316,22 @@ static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, /* Set up to write the address */ - addrbuf[0] = regaddr & 0xff; - addrbuf[1] = (regaddr >> 8) & 0xff; + addrbuf[0] = regaddr & 0xff; + addrbuf[1] = (regaddr >> 8) & 0xff; - msg[0].addr = priv->lower->address; - msg[0].flags = 0; - msg[0].buffer = addrbuf; - msg[0].length = 2; + msg[0].frequency = priv->frequency; + msg[0].addr = priv->lower->address; + msg[0].flags = 0; + msg[0].buffer = addrbuf; + msg[0].length = 2; /* Followed by the read data */ - msg[1].addr = priv->lower->address; - msg[1].flags = I2C_M_READ; - msg[1].buffer = buffer; - msg[1].length = buflen; + msg[1].frequency = priv->frequency; + msg[1].addr = priv->lower->address; + msg[1].flags = I2C_M_READ; + msg[1].buffer = buffer; + msg[1].length = buflen; /* Read the register data. The returned value is the number messages * completed. @@ -342,10 +345,10 @@ static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, idbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - idbg("ERROR: up_i2creset failed: %d\n", ret); + idbg("ERROR: I2C_RESET failed: %d\n", ret); break; } #else @@ -387,20 +390,22 @@ static int mxt_putreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, /* Set up to write the address */ - addrbuf[0] = regaddr & 0xff; - addrbuf[1] = (regaddr >> 8) & 0xff; + addrbuf[0] = regaddr & 0xff; + addrbuf[1] = (regaddr >> 8) & 0xff; - msg[0].addr = priv->lower->address; - msg[0].flags = 0; - msg[0].buffer = addrbuf; - msg[0].length = 2; + msg[0].frequency = priv->frequency; + msg[0].addr = priv->lower->address; + msg[0].flags = 0; + msg[0].buffer = addrbuf; + msg[0].length = 2; /* Followed by the write data (with no repeated start) */ - msg[1].addr = priv->lower->address; - msg[1].flags = I2C_M_NORESTART; - msg[1].buffer = (FAR uint8_t *)buffer; - msg[1].length = buflen; + msg[1].frequency = priv->frequency; + msg[1].addr = priv->lower->address; + msg[1].flags = I2C_M_NORESTART; + msg[1].buffer = (FAR uint8_t *)buffer; + msg[1].length = buflen; /* Write the register data. The returned value is the number messages * completed. @@ -414,10 +419,10 @@ static int mxt_putreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, idbg("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - idbg("ERROR: up_i2creset failed: %d\n", ret); + idbg("ERROR: I2C_RESET failed: %d\n", ret); } #else idbg("ERROR: I2C_TRANSFER failed: %d\n", ret); @@ -669,7 +674,7 @@ static inline int mxt_waitsample(FAR struct mxt_dev_s *priv) * from changing until it has been reported. */ - flags = irqsave(); + flags = enter_critical_section(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to @@ -715,7 +720,7 @@ errout: * have pre-emption disabled. */ - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -1368,7 +1373,7 @@ static ssize_t mxt_read(FAR struct file *filep, FAR char *buffer, size_t len) memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(ncontacts)); report->npoints = ncontacts; - for (i = 0, j= 0; i < priv->nslots && j < ncontacts; i++) + for (i = 0, j = 0; i < priv->nslots && j < ncontacts; i++) { FAR struct mxt_sample_s *sample = &priv->sample[i]; @@ -1511,7 +1516,8 @@ static int mxt_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg); DEBUGASSERT(priv->lower != NULL && ptr != NULL); - priv->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr); + + priv->frequency = *ptr; } break; @@ -1734,7 +1740,7 @@ static int mxt_hwinitialize(FAR struct mxt_dev_s *priv) /* Set the selected I2C frequency */ - priv->frequency = I2C_SETFREQUENCY(priv->i2c, priv->lower->frequency); + priv->frequency = priv->lower->frequency; /* Read the info registers from the device */ @@ -1850,7 +1856,7 @@ errout_with_objtab: * ****************************************************************************/ -int mxt_register(FAR struct i2c_dev_s *i2c, +int mxt_register(FAR struct i2c_master_s *i2c, FAR const struct mxt_lower_s * const lower, int minor) { FAR struct mxt_dev_s *priv; diff --git a/drivers/input/stmpe811.h b/drivers/input/stmpe811.h index d96944f4c401ca8a342e063ca17c89dc8a0bc297..dea9f3a0a86fc5b90f1f1799b10adcd34d5b93f3 100644 --- a/drivers/input/stmpe811.h +++ b/drivers/input/stmpe811.h @@ -138,7 +138,7 @@ struct stmpe811_dev_s #ifdef CONFIG_STMPE811_SPI FAR struct spi_dev_s *spi; /* Saved SPI driver instance */ #else - FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */ + FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */ #endif uint8_t inuse; /* STMPE811 pins in use */ diff --git a/drivers/input/stmpe811_base.c b/drivers/input/stmpe811_base.c index f2bdf8bca898e614507935e15faf22339777e256..224b9eaefc9eaaef568b77a0549bd39336994cfd 100644 --- a/drivers/input/stmpe811_base.c +++ b/drivers/input/stmpe811_base.c @@ -101,7 +101,7 @@ static void stmpe811_worker(FAR void *arg) /* Check for a touchscreen interrupt */ #ifndef CONFIG_STMPE811_TSC_DISABLE - if ((regval & (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW)) != 0) + if ((regval & (INT_TOUCH_DET | INT_FIFO_TH | INT_FIFO_OFLOW)) != 0) { /* Dispatch the touchscreen interrupt if it was brought into the link */ @@ -112,8 +112,9 @@ static void stmpe811_worker(FAR void *arg) stmpe811_tscworker(priv, regval); } - stmpe811_putreg8(priv, STMPE811_INT_STA, (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW)); - regval &= ~(INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW); + stmpe811_putreg8(priv, STMPE811_INT_STA, + (INT_TOUCH_DET | INT_FIFO_TH | INT_FIFO_OFLOW)); + regval &= ~(INT_TOUCH_DET | INT_FIFO_TH | INT_FIFO_OFLOW); } #endif @@ -286,7 +287,7 @@ static void stmpe811_reset(FAR struct stmpe811_dev_s *priv) STMPE811_HANDLE stmpe811_instantiate(FAR struct spi_dev_s *dev, FAR struct stmpe811_config_s *config) #else -STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_dev_s *dev, +STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_master_s *dev, FAR struct stmpe811_config_s *config) #endif { @@ -323,14 +324,6 @@ STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_dev_s *dev, priv->spi = dev; #else priv->i2c = dev; - - /* Set the I2C address and frequency. REVISIT: This logic would be - * insufficient if we share the I2C bus with any other devices that also - * modify the address and frequency. - */ - - I2C_SETADDRESS(dev, config->address, 7); - I2C_SETFREQUENCY(dev, config->frequency); #endif /* Read and verify the STMPE811 chip ID */ @@ -408,19 +401,21 @@ uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr) /* Setup 8-bit STMPE811 address write message */ - msg[0].addr = priv->config->address; /* 7-bit address */ - msg[0].flags = 0; /* Write transaction, beginning with START */ - msg[0].buffer = ®addr; /* Transfer from this address */ - msg[0].length = 1; /* Send one byte following the address - * (no STOP) */ + msg[0].frequency = priv->config->frequency; /* I2C frequency */ + msg[0].addr = priv->config->address; /* 7-bit address */ + msg[0].flags = 0; /* Write transaction, beginning with START */ + msg[0].buffer = ®addr; /* Transfer from this address */ + msg[0].length = 1; /* Send one byte following the address + * (no STOP) */ /* Set up the 8-bit STMPE811 data read message */ - msg[1].addr = priv->config->address; /* 7-bit address */ - msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ - msg[1].buffer = ®val; /* Transfer to this address */ - msg[1].length = 1; /* Receive one byte following the address - * (then STOP) */ + msg[1].frequency = priv->config->frequency; /* I2C frequency */ + msg[1].addr = priv->config->address; /* 7-bit address */ + msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ + msg[1].buffer = ®val; /* Transfer to this address */ + msg[1].length = 1; /* Receive one byte following the address + * (then STOP) */ /* Perform the transfer */ @@ -472,10 +467,11 @@ void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv, /* Setup 8-bit STMPE811 address write message */ - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = txbuffer; /* Transfer from this address */ - msg.length = 2; /* Send two byte following the address + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = txbuffer; /* Transfer from this address */ + msg.length = 2; /* Send two byte following the address * (then STOP) */ /* Perform the transfer */ @@ -513,19 +509,21 @@ uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr) /* Setup 8-bit STMPE811 address write message */ - msg[0].addr = priv->config->address; /* 7-bit address */ - msg[0].flags = 0; /* Write transaction, beginning with START */ - msg[0].buffer = ®addr; /* Transfer from this address */ - msg[0].length = 1; /* Send one byte following the address - * (no STOP) */ + msg[0].frequency = priv->config->frequency; /* I2C frequency */ + msg[0].addr = priv->config->address; /* 7-bit address */ + msg[0].flags = 0; /* Write transaction, beginning with START */ + msg[0].buffer = ®addr; /* Transfer from this address */ + msg[0].length = 1; /* Send one byte following the address + * (no STOP) */ /* Set up the 8-bit STMPE811 data read message */ - msg[1].addr = priv->config->address; /* 7-bit address */ - msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ - msg[1].buffer = rxbuffer; /* Transfer to this address */ - msg[1].length = 2; /* Receive two bytes following the address - * (then STOP) */ + msg[1].frequency = priv->config->frequency; /* I2C frequency */ + msg[1].addr = priv->config->address; /* 7-bit address */ + msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ + msg[1].buffer = rxbuffer; /* Transfer to this address */ + msg[1].length = 2; /* Receive two bytes following the address + * (then STOP) */ /* Perform the transfer */ diff --git a/drivers/input/stmpe811_temp.c b/drivers/input/stmpe811_temp.c index 9b5e7e150fec95de85e298e4b0a0add0fc8531a0..0cb5c686c7d5d43d2e62ebddee77e79b2163f818 100644 --- a/drivers/input/stmpe811_temp.c +++ b/drivers/input/stmpe811_temp.c @@ -101,7 +101,8 @@ int stmpe811_tempinitialize(STMPE811_HANDLE handle) /* Aquire data enable */ - stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE)); + stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, + (TEMP_CTRL_ACQ | TEMP_CTRL_ENABLE)); return OK; } @@ -130,7 +131,8 @@ uint16_t stmpe811_tempread(STMPE811_HANDLE handle) /* Acquire data enable */ - stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE)); + stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, + (TEMP_CTRL_ACQ | TEMP_CTRL_ENABLE)); /* Read the temperature */ diff --git a/drivers/input/stmpe811_tsc.c b/drivers/input/stmpe811_tsc.c index 783e9f3dc48ab7b74d73a4f338cafe06c221ca2f..55dce44272fff86a46bbc6311154aaaba1a66c79 100644 --- a/drivers/input/stmpe811_tsc.c +++ b/drivers/input/stmpe811_tsc.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include @@ -307,7 +307,7 @@ static inline int stmpe811_waitsample(FAR struct stmpe811_dev_s *priv, if (ret < 0) { #ifdef CONFIG_DEBUG - // Sample the errno (debug output could change it) + /* Sample the errno (debug output could change it) */ int errval = errno; @@ -577,11 +577,11 @@ errout: /**************************************************************************** * Name: stmpe811_ioctl - * + * * Description: * Standard character driver ioctl method. * -****************************************************************************/ + ****************************************************************************/ static int stmpe811_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { @@ -615,7 +615,7 @@ static int stmpe811_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg); DEBUGASSERT(priv->config != NULL && ptr != NULL); - priv->config->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr); + priv->config->frequency = *ptr; } break; @@ -860,7 +860,7 @@ static inline void stmpe811_tscinitialize(FAR struct stmpe811_dev_s *priv) stmpe811_putreg8(priv, STMPE811_TSC_IDRIVE, TSC_IDRIVE_50MA); /* Enable the TSC. Use no tracking index, touch-screen controller - * operation mode (XYZ). + * operation mode (XYZ). */ stmpe811_putreg8(priv, STMPE811_TSC_CTRL, TSC_CTRL_EN); @@ -1019,7 +1019,7 @@ void stmpe811_tscworker(FAR struct stmpe811_dev_s *priv, uint8_t intsta) /* The pen is down... check for data in the FIFO */ - else if ((intsta & (INT_FIFO_TH|INT_FIFO_OFLOW)) != 0) + else if ((intsta & (INT_FIFO_TH | INT_FIFO_OFLOW)) != 0) { /* Read the next x and y positions from the FIFO. */ diff --git a/drivers/input/tsc2007.c b/drivers/input/tsc2007.c index c4ad2459421500850a1fa77d385fc1b7029cedc3..a27042400f28121fb3ffce722d906c649cfa06d4 100644 --- a/drivers/input/tsc2007.c +++ b/drivers/input/tsc2007.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/input/tsc2007.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -62,10 +62,11 @@ #include #include +#include #include #include #include -#include +#include #include #include @@ -165,7 +166,7 @@ struct tsc2007_dev_s sem_t waitsem; /* Used to wait for the availability of data */ FAR struct tsc2007_config_s *config; /* Board configuration data */ - FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */ + FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */ struct work_s work; /* Supports the interrupt handling "bottom half" */ struct tsc2007_sample_s sample; /* Last sampled touch point data */ @@ -299,7 +300,7 @@ static int tsc2007_sample(FAR struct tsc2007_dev_s *priv, * from changing until it has been reported. */ - flags = irqsave(); + flags = enter_critical_section(); /* Is there new TSC2007 sample data available? */ @@ -309,7 +310,7 @@ static int tsc2007_sample(FAR struct tsc2007_dev_s *priv, * sampled data. */ - memcpy(sample, &priv->sample, sizeof(struct tsc2007_sample_s )); + memcpy(sample, &priv->sample, sizeof(struct tsc2007_sample_s)); /* Now manage state transitions */ @@ -334,7 +335,7 @@ static int tsc2007_sample(FAR struct tsc2007_dev_s *priv, ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -357,7 +358,7 @@ static int tsc2007_waitsample(FAR struct tsc2007_dev_s *priv, */ sched_lock(); - flags = irqsave(); + flags = enter_critical_section(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to @@ -403,7 +404,7 @@ errout: * have pre-emption disabled. */ - irqrestore(flags); + leave_critical_section(flags); /* Restore pre-emption. We might get suspended here but that is okay * because we already have our sample. Note: this means that if there @@ -430,12 +431,13 @@ static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd) * activation command (ACKed). */ - data = TSC2007_SETUP; + data = TSC2007_SETUP; - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = &data; /* Transfer from this address */ - msg.length = 1; /* Send one byte following the address */ + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = &data; /* Transfer from this address */ + msg.length = 1; /* Send one byte following the address */ /* Ignore errors from the setup command (because it is not ACKed) */ @@ -443,12 +445,13 @@ static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd) /* Now activate the A/D converter */ - data = cmd; + data = cmd; - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = &data; /* Transfer from this address */ - msg.length = 1; /* Send one byte following the address */ + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = &data; /* Transfer from this address */ + msg.length = 1; /* Send one byte following the address */ ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0) @@ -483,10 +486,11 @@ static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd) * STOP condition... */ - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = &cmd; /* Transfer from this address */ - msg.length = 1; /* Send one byte following the address */ + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = &cmd; /* Transfer from this address */ + msg.length = 1; /* Send one byte following the address */ ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0) @@ -527,10 +531,11 @@ static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd) * data byte has been received... */ - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = I2C_M_READ; /* Read transaction, beginning with START */ - msg.buffer = data12; /* Transfer to this address */ - msg.length = 2; /* Read two bytes following the address */ + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = I2C_M_READ; /* Read transaction, beginning with START */ + msg.buffer = data12; /* Transfer to this address */ + msg.length = 2; /* Read two bytes following the address */ ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0) @@ -539,10 +544,10 @@ static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd) return ret; } - /* Get the MS 8 bits from the first byte and the remaining LS 4 bits from - * the second byte. The valid range of data is then from 0 to 4095 with - * the LSB unit corresponding to Vref/4096. - */ + /* Get the MS 8 bits from the first byte and the remaining LS 4 bits from + * the second byte. The valid range of data is then from 0 to 4095 with + * the LSB unit corresponding to Vref/4096. + */ ret = (unsigned int)data12[0] << 4 | (unsigned int)data12[1] >> 4; ivdbg("data: 0x%04x\n", ret); @@ -971,8 +976,8 @@ static ssize_t tsc2007_read(FAR struct file *filep, FAR char *buffer, size_t len if (sample.contact == CONTACT_UP) { - /* Pen is now up. Is the positional data valid? This is important to - * know because the release will be sent to the window based on its + /* Pen is now up. Is the positional data valid? This is important to + * know because the release will be sent to the window based on its * last positional data. */ @@ -1068,7 +1073,7 @@ static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg); DEBUGASSERT(priv->config != NULL && ptr != NULL); - priv->config->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr); + priv->config->frequency = *ptr; } break; @@ -1210,7 +1215,7 @@ errout: * ****************************************************************************/ -int tsc2007_register(FAR struct i2c_dev_s *dev, +int tsc2007_register(FAR struct i2c_master_s *dev, FAR struct tsc2007_config_s *config, int minor) { FAR struct tsc2007_dev_s *priv; @@ -1250,19 +1255,6 @@ int tsc2007_register(FAR struct i2c_dev_s *dev, sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ - /* Set the I2C frequency (saving the actual frequency) */ - - config->frequency = I2C_SETFREQUENCY(dev, config->frequency); - - /* Set the I2C address and address size */ - - ret = I2C_SETADDRESS(dev, config->address, 7); - if (ret < 0) - { - idbg("I2C_SETADDRESS failed: %d\n", ret); - goto errout_with_priv; - } - /* Make sure that interrupts are disabled */ config->clear(config); @@ -1306,10 +1298,10 @@ int tsc2007_register(FAR struct i2c_dev_s *dev, */ #ifdef CONFIG_TSC2007_MULTIPLE - flags = irqsave(); + flags = enter_critical_section(); priv->flink = g_tsc2007list; g_tsc2007list = priv; - irqrestore(flags); + leave_critical_section(flags); #endif /* Schedule work to perform the initial sampling and to set the data diff --git a/drivers/ioexpander/Kconfig b/drivers/ioexpander/Kconfig index 105604106376c26d8a666d0d3d3abef7235aac83..438beeed5ac891cb8d5bd140e60f0fcd8a2a5b6f 100644 --- a/drivers/ioexpander/Kconfig +++ b/drivers/ioexpander/Kconfig @@ -3,13 +3,6 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -config IOEXPANDER_MULTIPIN - bool "Support multi-pin access routines" - default n - ---help--- - This settings enable the definition of routines for - optimized simultaneous access to multiple pins. - config IOEXPANDER_PCA9555 bool "PCA9555 I2C IO expander" default n @@ -22,13 +15,28 @@ if IOEXPANDER_PCA9555 config PCA9555_MULTIPLE bool "Multiple PCA9555 Devices" default n + depends on EXPERIMENTAL ---help--- Can be defined to support multiple PCA9555 devices on board. -config PCA9555_INT_DISABLE - bool "Disable PCA9555 Interrupt Support" - default y +config PCA9555_INT_ENABLE + bool "Enable PCA9555 Interrupt Support" + default n + select IOEXPANDER_INT_ENABLE ---help--- - Disable driver interrupt functionality + Enable driver interrupt functionality endif # IOEXPANDER_PCA9555 + +config IOEXPANDER_INT_ENABLE + bool + default y if PCA9555_INT_ENABLE + ---help--- + This is the global INT supported flag for io expanders + +config IOEXPANDER_MULTIPIN + bool "Support multi-pin access routines" + default n + ---help--- + This settings enable the definition of routines for + optimized simultaneous access to multiple pins. diff --git a/drivers/ioexpander/Make.defs b/drivers/ioexpander/Make.defs index 7e34efa8b0ce58ec6e3dec401c041e938a31aeb5..aea59aea51d829d30b9150e14fd121ede7ab232c 100644 --- a/drivers/ioexpander/Make.defs +++ b/drivers/ioexpander/Make.defs @@ -33,17 +33,17 @@ # ############################################################################ -# Don't build anything if there is no support for io expander devices +# Check if I/O expander support is enabled ifeq ($(CONFIG_IOEXPANDER),y) -# Include the selected io expander drivers +# Include the selected I/O expander drivers ifeq ($(CONFIG_IOEXPANDER_PCA9555),y) CSRCS += pca9555.c endif -# Include io expander device driver build support +# Include ioexpander I/O device driver build support DEPPATH += --dep-path ioexpander VPATH += :ioexpander diff --git a/drivers/ioexpander/pca9555.c b/drivers/ioexpander/pca9555.c index f2f06fed6eae4510c83fb81f0af61d666a57dece..e8273ae817ffbcf0cca28728228e1111f8ea6050 100644 --- a/drivers/ioexpander/pca9555.c +++ b/drivers/ioexpander/pca9555.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/ioexpander/pca9555.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. * Author: Sebastien Lorquet * * References: @@ -43,11 +43,14 @@ #include +#include #include #include #include -#include +#include +#include +#include #include #include "pca9555.h" @@ -62,34 +65,32 @@ # warning I2C support is required (CONFIG_I2C) #endif -#ifndef CONFIG_I2C_WRITEREAD -# warning Support of the I2C writeread() method is required (CONFIG_I2C_WRITEREAD) -#endif - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -static int pca9555_direction (FAR struct ioexpander_dev_s *dev, - uint8_t pin, int dir); -static int pca9555_option (FAR struct ioexpander_dev_s *dev, - uint8_t pin, int opt, void *val); -static int pca9555_write (FAR struct ioexpander_dev_s *dev, - uint8_t pin, bool value); -static int pca9555_readpin (FAR struct ioexpander_dev_s *dev, - uint8_t pin, FAR bool *value); -static int pca9555_readbuf (FAR struct ioexpander_dev_s *dev, - uint8_t pin, FAR bool *value); +static inline int pca9555_write(FAR struct pca9555_dev_s *pca, + FAR const uint8_t *wbuffer, int wbuflen); +static inline int pca9555_writeread(FAR struct pca9555_dev_s *pca, + FAR const uint8_t *wbuffer, int wbuflen, FAR uint8_t *rbuffer, + int rbuflen); +static int pca9555_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin, + int dir); +static int pca9555_option(FAR struct ioexpander_dev_s *dev, uint8_t pin, + int opt, void *val); +static int pca9555_writepin(FAR struct ioexpander_dev_s *dev, uint8_t pin, + bool value); +static int pca9555_readpin(FAR struct ioexpander_dev_s *dev, uint8_t pin, + FAR bool *value); +static int pca9555_readbuf(FAR struct ioexpander_dev_s *dev, uint8_t pin, + FAR bool *value); #ifdef CONFIG_IOEXPANDER_MULTIPIN -static int pca9555_multiwrite (FAR struct ioexpander_dev_s *dev, - FAR uint8_t *pins, FAR bool *values, - int count); +static int pca9555_multiwritepin(FAR struct ioexpander_dev_s *dev, + FAR uint8_t *pins, FAR bool *values, int count); static int pca9555_multireadpin(FAR struct ioexpander_dev_s *dev, - FAR uint8_t *pins, FAR bool *values, - int count); + FAR uint8_t *pins, FAR bool *values, int count); static int pca9555_multireadbuf(FAR struct ioexpander_dev_s *dev, - FAR uint8_t *pins, FAR bool *values, - int count); + FAR uint8_t *pins, FAR bool *values, int count); #endif /**************************************************************************** @@ -113,11 +114,11 @@ static const struct ioexpander_ops_s g_pca9555_ops = { pca9555_direction, pca9555_option, - pca9555_write, + pca9555_writepin, pca9555_readpin, pca9555_readbuf, #ifdef CONFIG_IOEXPANDER_MULTIPIN - pca9555_multiwrite, + pca9555_multiwritepin, pca9555_multireadpin, pca9555_multireadbuf, #endif @@ -127,6 +128,75 @@ static const struct ioexpander_ops_s g_pca9555_ops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: pca9555_lock + * + * Description: + * Get exclusive access to the PCA9555 + * + ****************************************************************************/ + +static void pca9555_lock(FAR struct pca9555_dev_s *pca) +{ + while (sem_wait(&pca->exclsem) < 0) + { + /* EINTR is the only expected error from sem_wait() */ + + DEBUGASSERT(errno == EINTR); + } +} + +#define pca9555_unlock(p) sem_post(&(p)->exclsem) + +/**************************************************************************** + * Name: pca9555_write + * + * Description: + * Write to the I2C device. + * + ****************************************************************************/ + +static inline int pca9555_write(FAR struct pca9555_dev_s *pca, + FAR const uint8_t *wbuffer, int wbuflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = pca->config->frequency; + msg.addr = pca->config->address; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)wbuffer; /* Override const */ + msg.length = wbuflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(pca->i2c, &msg, 1); +} + +/**************************************************************************** + * Name: pca9555_writeread + * + * Description: + * Write to then read from the I2C device. + * + ****************************************************************************/ + +static inline int pca9555_writeread(FAR struct pca9555_dev_s *pca, + FAR const uint8_t *wbuffer, int wbuflen, + FAR uint8_t *rbuffer, int rbuflen) +{ + struct i2c_config_s config; + + /* Set up the configuration and perform the write-read operation */ + + config.frequency = pca->config->frequency; + config.address = pca->config->address; + config.addrlen = 7; + + return i2c_writeread(pca->i2c, &config, wbuffer, wbuflen, rbuffer, rbuflen); +} + /**************************************************************************** * Name: pca9555_setbit * @@ -135,12 +205,11 @@ static const struct ioexpander_ops_s g_pca9555_ops = * ****************************************************************************/ -static int pca9555_setbit(FAR struct i2c_dev_s *i2c, uint8_t addr, +static int pca9555_setbit(FAR struct pca9555_dev_s *pca, uint8_t addr, uint8_t pin, int bitval) { - int ret; uint8_t buf[2]; - buf[0] = addr; + int ret; if (pin > 15) { @@ -148,11 +217,13 @@ static int pca9555_setbit(FAR struct i2c_dev_s *i2c, uint8_t addr, } else if (pin > 7) { - addr += 1; + addr++; pin -= 8; } - ret = I2C_WRITEREAD(i2c, &addr, 1, &buf[1], 1); + buf[0] = addr; + + ret = pca9555_writeread(pca, &buf[0], 1, &buf[1], 1); if (ret < 0) { return ret; @@ -167,7 +238,7 @@ static int pca9555_setbit(FAR struct i2c_dev_s *i2c, uint8_t addr, buf[1] &= ~(1 << pin); } - return I2C_WRITE(i2c, buf, 2); + return pca9555_write(pca, buf, 2); } /**************************************************************************** @@ -178,7 +249,7 @@ static int pca9555_setbit(FAR struct i2c_dev_s *i2c, uint8_t addr, * ****************************************************************************/ -static int pca9555_getbit(FAR struct i2c_dev_s *i2c, uint8_t addr, +static int pca9555_getbit(FAR struct pca9555_dev_s *pca, uint8_t addr, uint8_t pin, FAR bool *val) { uint8_t buf; @@ -194,7 +265,7 @@ static int pca9555_getbit(FAR struct i2c_dev_s *i2c, uint8_t addr, pin -= 8; } - ret = I2C_WRITEREAD(i2c, &addr, 1, &buf, 1); + ret = pca9555_writeread(pca, &addr, 1, &buf, 1); if (ret < 0) { return ret; @@ -215,9 +286,16 @@ static int pca9555_getbit(FAR struct i2c_dev_s *i2c, uint8_t addr, static int pca9555_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin, int direction) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_setbit(pca->i2c, PCA9555_REG_CONFIG, pin, - (direction == IOEXPANDER_DIRECTION_IN)); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_setbit(pca, PCA9555_REG_CONFIG, pin, + (direction == IOEXPANDER_DIRECTION_IN)); + pca9555_unlock(pca); + return ret; } /**************************************************************************** @@ -229,32 +307,44 @@ static int pca9555_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin, ****************************************************************************/ static int pca9555_option(FAR struct ioexpander_dev_s *dev, uint8_t pin, - int opt, void *val) + int opt, FAR void *val) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; int ival = (int)val; + int ret = -EINVAL; if (opt == IOEXPANDER_OPTION_INVERT) { - return pca9555_setbit(pca->i2c, PCA9555_REG_POLINV, pin, ival); + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_setbit(pca, PCA9555_REG_POLINV, pin, ival); + pca9555_unlock(pca); } - return -EINVAL; + return ret; } /**************************************************************************** - * Name: pca9555_write + * Name: pca9555_writepin * * Description: * See include/nuttx/ioexpander/ioexpander.h * ****************************************************************************/ -static int pca9555_write(FAR struct ioexpander_dev_s *dev, uint8_t pin, - bool value) +static int pca9555_writepin(FAR struct ioexpander_dev_s *dev, uint8_t pin, + bool value) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_setbit(pca->i2c, PCA9555_REG_OUTPUT, pin, value); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_setbit(pca, PCA9555_REG_OUTPUT, pin, value); + pca9555_unlock(pca); + return ret; } /**************************************************************************** @@ -268,8 +358,15 @@ static int pca9555_write(FAR struct ioexpander_dev_s *dev, uint8_t pin, static int pca9555_readpin(FAR struct ioexpander_dev_s *dev, uint8_t pin, FAR bool *value) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_getbit(pca->i2c, PCA9555_REG_INPUT, pin, value); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_getbit(pca, PCA9555_REG_INPUT, pin, value); + pca9555_unlock(pca); + return ret; } /**************************************************************************** @@ -283,8 +380,15 @@ static int pca9555_readpin(FAR struct ioexpander_dev_s *dev, uint8_t pin, static int pca9555_readbuf(FAR struct ioexpander_dev_s *dev, uint8_t pin, FAR bool *value) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_getbit(pca->i2c, PCA9555_REG_OUTPUT, pin, value); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_getbit(pca, PCA9555_REG_OUTPUT, pin, value); + pca9555_unlock(pca); + return ret; } #ifdef CONFIG_IOEXPANDER_MULTIPIN @@ -297,7 +401,7 @@ static int pca9555_readbuf(FAR struct ioexpander_dev_s *dev, uint8_t pin, * ****************************************************************************/ -static int pca9555_getmultibits(FAR struct i2c_dev_s *i2c, uint8_t addr, +static int pca9555_getmultibits(FAR struct pca9555_dev_s *pca, uint8_t addr, FAR uint8_t *pins, FAR bool *values, int count) { @@ -307,8 +411,7 @@ static int pca9555_getmultibits(FAR struct i2c_dev_s *i2c, uint8_t addr, int index; int pin; - ret = I2C_WRITEREAD(i2c, &addr, 1, buf, 2); - + ret = pca9555_writeread(pca, &addr, 1, buf, 2); if (ret < 0) { return ret; @@ -337,18 +440,18 @@ static int pca9555_getmultibits(FAR struct i2c_dev_s *i2c, uint8_t addr, } /**************************************************************************** - * Name: pca9555_multiwrite + * Name: pca9555_multiwritepin * * Description: * See include/nuttx/ioexpander/ioexpander.h * ****************************************************************************/ -static int pca9555_multiwrite(FAR struct ioexpander_dev_s *dev, - FAR uint8_t *pins, FAR bool *values, - int count) +static int pca9555_multiwritepin(FAR struct ioexpander_dev_s *dev, + FAR uint8_t *pins, FAR bool *values, + int count) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; uint8_t addr = PCA9555_REG_OUTPUT; uint8_t buf[3]; int ret; @@ -356,13 +459,19 @@ static int pca9555_multiwrite(FAR struct ioexpander_dev_s *dev, int index; int pin; + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + /* Start by reading both registers, whatever the pins to change. We could * attempt to read one port only if all pins were on the same port, but * this would not save much. */ - ret = I2C_WRITEREAD(pca->i2c, &addr, 1, &buf[1], 2); + ret = pca9555_writeread(pca, &addr, 1, &buf[1], 2); if (ret < 0) { + + pca9555_unlock(pca); return ret; } @@ -374,6 +483,7 @@ static int pca9555_multiwrite(FAR struct ioexpander_dev_s *dev, pin = pins[i]; if (pin > 15) { + pca9555_unlock(pca); return -ENXIO; } else if(pin > 7) @@ -395,7 +505,10 @@ static int pca9555_multiwrite(FAR struct ioexpander_dev_s *dev, /* Now write back the new pins states */ buf[0] = addr; - return I2C_WRITE(pca->i2c, buf, 3); + ret = pca9555_write(pca, buf, 3); + + pca9555_unlock(pca); + return ret; } /**************************************************************************** @@ -410,9 +523,16 @@ static int pca9555_multireadpin(FAR struct ioexpander_dev_s *dev, FAR uint8_t *pins, FAR bool *values, int count) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_getmultibits(pca->i2c, PCA9555_REG_INPUT, - pins, values, count); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_getmultibits(pca, PCA9555_REG_INPUT, + pins, values, count); + pca9555_unlock(pca); + return ret; } /**************************************************************************** @@ -427,65 +547,112 @@ static int pca9555_multireadbuf(FAR struct ioexpander_dev_s *dev, FAR uint8_t *pins, FAR bool *values, int count) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return pca9555_getmultibits(pca->i2c, PCA9555_REG_OUTPUT, - pins, values, count); + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev; + int ret; + + /* Get exclusive access to the PCA555 */ + + pca9555_lock(pca); + ret = pca9555_getmultibits(pca, PCA9555_REG_OUTPUT, + pins, values, count); + pca9555_unlock(pca); + return ret; } #endif -#ifndef CONFIG_PCA9555_INT_DISABLE +#ifdef CONFIG_PCA9555_INT_ENABLE /**************************************************************************** - * Name: pca9555_gpioworker + * Name: pca9555_irqworker * * Description: - * See include/nuttx/ioexpander/ioexpander.h + * Handle GPIO interrupt events (this function actually executes in the + * context of the worker thread). * ****************************************************************************/ -static int pca9555_attach(FAR struct ioexpander_dev_s *dev, uint8_t pin, - ioexpander_handler_t handler) +static void pca9555_irqworker(void *arg) { - FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s*)dev; - return 0; + uint8_t addr = PCA9555_REG_INPUT; + uint8_t buf[2]; + int ret, bits; + FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)arg; + + /* Read inputs */ + + ret = pca9555_writeread(pca, &addr, 1, buf, 2); + if (ret != OK) + { + return; + } + + bits = (buf[0] << 8) | buf[1]; + + /* If signal PID is registered, enqueue signal. */ + + if (pca->dev.sigpid) + { +#ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; + value.sival_int = bits; + ret = sigqueue(pca->dev.sigpid, pca->dev.sigval, value); +#else + ret = sigqueue(pca->dev.sigpid, pca->dev.sigval, (FAR void *)bits); +#endif + dbg("pca signal %04X (sig %d to pid %d)\n", + bits, pca->dev.sigval, pca->dev.sigpid); + } + else + { + dbg("no handler registered\n"); + } + + /* Re-enable */ + + pca->config->enable(pca->config, TRUE); } /**************************************************************************** - * Name: pca9555_irqworker + * Name: pca9555_interrupt * * Description: - * Handle GPIO interrupt events (this function actually executes in the - * context of the worker thread). + * Handle GPIO interrupt events (this function executes in the + * context of the interrupt). * ****************************************************************************/ -static void pca9555_irqworker(FAR struct pca9555_dev_s *priv) +static int pca9555_interrupt(int irq, FAR void *context) { - uint8_t regval; - uint8_t pinmask; - int pin; +#ifdef CONFIG_PCA9555_MULTIPLE + /* To support multiple devices, + * retrieve the pca structure using the irq number. + */ - /* Get the set of pending GPIO interrupts */ +# warning Missing logic - /* Look at each pin */ +#else + register FAR struct pca9555_dev_s *pca = &g_pca9555; +#endif - for (pin = 0; pin < PCA9555_GPIO_NPINS; pin++) - { - /* Check if we have a handler for this interrupt (there should - * be one) - */ + /* In complex environments, we cannot do I2C transfers from the interrupt + * handler because semaphores are probably used to lock the I2C bus. In + * this case, we will defer processing to the worker thread. This is also + * much kinder in the use of system resources and is, therefore, probably + * a good thing to do in any event. + */ - /* Interrupt is pending... dispatch the interrupt to the - * callback - */ + DEBUGASSERT(work_available(&pca->dev.work)); - /* Clear the pending GPIO interrupt by writing a '1' to the - * pin position in the status register. - */ + /* Notice that further GPIO interrupts are disabled until the work is + * actually performed. This is to prevent overrun of the worker thread. + * Interrupts are re-enabled in pca9555_irqworker() when the work is completed. + */ - } + pca->config->enable(pca->config, FALSE); + return work_queue(HPWORK, &pca->dev.work, pca9555_irqworker, (FAR void *)pca, 0); } + #endif /**************************************************************************** @@ -502,7 +669,7 @@ static void pca9555_irqworker(FAR struct pca9555_dev_s *priv) * ****************************************************************************/ -FAR struct ioexpander_dev_s *pca9555_initialize(FAR struct i2c_dev_s *i2cdev, +FAR struct ioexpander_dev_s *pca9555_initialize(FAR struct i2c_master_s *i2cdev, FAR struct pca9555_config_s *config) { FAR struct pca9555_dev_s *pcadev; @@ -535,17 +702,15 @@ FAR struct ioexpander_dev_s *pca9555_initialize(FAR struct i2c_dev_s *i2cdev, pcadev->i2c = i2cdev; pcadev->dev.ops = &g_pca9555_ops; + pcadev->config = config; - /* Set the I2C address and frequency. REVISIT: This logic would be - * insufficient if we share the I2C bus with any other devices that also - * modify the address and frequency. - */ - - I2C_SETADDRESS(i2cdev, config->address, 7); - I2C_SETFREQUENCY(i2cdev, config->frequency); +#ifdef CONFIG_PCA9555_INT_ENABLE + pcadev->config->attach(pcadev->config, pca9555_interrupt); + pcadev->config->enable(pcadev->config, TRUE); +#endif + sem_init(&pcadev->exclsem, 0, 1); return &pcadev->dev; } #endif /* CONFIG_IOEXPANDER_PCA9555 */ - diff --git a/drivers/ioexpander/pca9555.h b/drivers/ioexpander/pca9555.h index ef0495a9f4cca622f0cceb94b5bce0cde8d25452..39435f23d61e23e8c76315a0d129564f80c31050 100644 --- a/drivers/ioexpander/pca9555.h +++ b/drivers/ioexpander/pca9555.h @@ -46,13 +46,14 @@ #include +#include + #include #include -#include #include #include -#include +#include #include #if defined(CONFIG_IOEXPANDER) && defined(CONFIG_IOEXPANDER_PCA9555) @@ -64,8 +65,6 @@ /* Prerequisites: * CONFIG_I2C * I2C support is required - * CONFIG_I2C_WRITEREAD - * Support for the I2C writeread method is required. * CONFIG_IOEXPANDER * Enables support for the PCA9555 I/O expander * @@ -95,12 +94,6 @@ #error "CONFIG_I2C is required by PCA9555" #endif -#ifndef CONFIG_PCA9555_INT_DISABLE -#ifndef CONFIG_SCHED_WORKQUEUE -#error "Work queue support required. CONFIG_SCHED_WORKQUEUE must be selected." -#endif -#endif - #define PCA9555_MAXDEVS 8 /* I2C frequency */ @@ -123,19 +116,16 @@ struct pca9555_dev_s { - struct ioexpander_dev_s dev; /* Nested structure to allow casting as public gpio expander. */ + struct ioexpander_dev_s dev; /* Nested structure to allow casting as public gpio + * expander. */ #ifdef CONFIG_PCA9555_MULTIPLE - FAR struct pca9555_dev_s *flink; /* Supports a singly linked list of drivers */ + FAR struct pca9555_dev_s *flink; /* Supports a singly linked list of drivers */ #endif - FAR struct pca9555_config_s *config; /* Board configuration data */ - FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */ - -#ifndef CONFIG_PCA9555_INT_DISABLE - struct work_s work; /* Supports the interrupt handling "bottom half" */ - pca9555_handler_t handlers[PCA9555_GPIO_NPINS]; /* GPIO "interrupt handlers" */ -#endif + FAR struct pca9555_config_s *config; /* Board configuration data */ + FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */ + sem_t exclsem; /* Mutual exclusion */ }; #endif /* CONFIG_IOEXPANDER && CONFIG_IOEXPANDER_PCA9555 */ diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index ceceaad84db2ec5b9ac9c2d2241b3646cc98ec7f..a7be77550c3d10e7cac58eed5e99367549cc3780 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -366,6 +366,186 @@ config SSD1306_I2CFREQ endif # LCD_SSD1306_I2C +config LCD_SSD1351 + bool "SSD1351 OLED Display Module" + default n + ---help--- + OLED Display Module, SSD1351, Solomon Systech. + +if LCD_SSD1351 + +choice + prompt "Interface" + default SSD1351_SPI4WIRE + +config SSD1351_PARALLEL8BIT + bool "8-bit Parallel Interface" + ---help--- + Enables support for the 8-bit parallel interface. + +config SSD1351_SPI3WIRE + bool "3-wire SPI Interface" + select SPI + ---help--- + Enables support for the 3-wire SPI interface. + +config SSD1351_SPI4WIRE + bool "4-wire SPI Interface" + select SPI + select SPI_CMDDATA + ---help--- + Enables support for the 4-wire SPI interface. + +endchoice + +if SSD1351_SPI3WIRE || SSD1351_SPI4WIRE + +config SSD1351_SPIMODE + int "SPI Mode" + default 0 + range 0 3 + ---help--- + Specifies the SPI mode. + +config SSD1351_SPIFREQ + int "SPI Frequency" + default 1000000 + ---help--- + Specifies the SPI frequency. + +endif + +config SSD1351_NINTERFACES + int "Number of SSD1351 Devices" + default 1 + range 1 1 + ---help--- + Specifies the number of physical SSD1351 devices that will + be supported. + +config SSD1351_XRES + int "X Resolution" + default 128 + range 1 128 + ---help--- + Specifies the X resolution of the display. + +config SSD1351_YRES + int "Y Resolution" + default 128 + range 1 128 + ---help--- + Specifies the Y resolution of the display. + +config SSD1351_MIRRORX + bool "Mirror X" + default n + ---help--- + Mirrors the display along the X axis. + +config SSD1351_MIRRORY + bool "Mirror Y" + default n + ---help--- + Mirrors the display along the Y axis. + +config SSD1351_INVERT + bool "Invert Display" + default n + ---help--- + Inverts the display. + +config SSD1351_VDDEXT + bool "External VDD" + default n + ---help--- + Specifies that VDD is external. + +config SSD1351_TRST + int "Reset Period" + default 5 + range 5 31 + ---help--- + Specifies the reset period in DCLKs. + +config SSD1351_TPRECHG1 + int "First Pre-charge Period" + default 8 + range 3 15 + ---help--- + Specifies the first pre-charge period in DCLKs. + +config SSD1351_PERFENHANCE + bool "Enhance Display Performance" + default n + ---help--- + Enhances the display performance. + +config SSD1351_CLKDIV + int "Clock Divider" + default 0 + range 0 10 + ---help--- + Specifies the clock divider. + +config SSD1351_OSCFREQ + int "Oscillator Frequency" + default 15 + range 0 15 + ---help--- + Specifies the oscillator frequency. + +config SSD1351_TPRECHG2 + int "Second Pre-charge Period" + default 8 + range 1 15 + ---help--- + Specifies the second pre-charge period in DCLKs. + +config SSD1351_VPRECHG + int "Voltage Pre-charge Level" + default 50 + range 20 60 + ---help--- + Specifies the pre-charge voltage level as a percentage of VCC. + +config SSD1351_VCOMH + int "COM Deselect Voltage Level" + default 82 + range 72 86 + ---help--- + Specifies the COM deselect voltage level as a percentage of VCC. + +config SSD1351_CONTRASTA + int "Color A Contrast" + default 138 + range 0 255 + ---help--- + Specifies the contrast of color A. + +config SSD1351_CONTRASTB + int "Color B Contrast" + default 81 + range 0 255 + ---help--- + Specifies the contrast of color B. + +config SSD1351_CONTRASTC + int "Color C Contrast" + default 138 + range 0 255 + ---help--- + Specifies the contrast of color C. + +config SSD1351_MSTRCONTRAST + int "Master Contrast Ratio" + default 16 + range 1 16 + ---help--- + Specifies the master contrast ratio in sixteenths. + +endif + config LCD_ST7565 bool "ST7565 LCD Display Module" default n @@ -384,6 +564,9 @@ choice config NHD_C12864KGZ bool "like NHD C12864KGZ" +config ERC_12864_3 + bool "like ERC12864-3" + endchoice config ST7565_NINTERFACES diff --git a/drivers/lcd/Make.defs b/drivers/lcd/Make.defs index 6c46771f0953ec97de43f8fe05cf8f00728bc362..1becc0fa97360fdf515fa68c84f2499b8b6a9917 100644 --- a/drivers/lcd/Make.defs +++ b/drivers/lcd/Make.defs @@ -71,6 +71,10 @@ ifeq ($(CONFIG_LCD_SSD1289),y) CSRCS += ssd1289.c endif +ifeq ($(CONFIG_LCD_SSD1351),y) + CSRCS += ssd1351.c +endif + ifeq ($(CONFIG_LCD_MIO283QT2),y) CSRCS += mio283qt2.c endif diff --git a/drivers/lcd/ili9341.c b/drivers/lcd/ili9341.c index 66c186bf404afbe8827fe03ade3f1153ae20fee2..1c19187ab547cf7ce8f3d0c97cad640810edc679 100644 --- a/drivers/lcd/ili9341.c +++ b/drivers/lcd/ili9341.c @@ -1,4 +1,4 @@ -/****************************************************************************** +/**************************************************************************** * drivers/lcd/ili9341.c * * LCD driver for the ILI9341 LCD Single Chip Driver @@ -37,11 +37,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ******************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -58,12 +58,11 @@ #include -/****************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ -/* - * This is the generic lcd driver interface for the ili9341 Single Chip LCD +/* This is the generic lcd driver interface for the ili9341 Single Chip LCD * driver. The driver supports multiple displays, each connected with an own * ili9341 Single Chip LCD driver. The communication with the LCD single chip * driver must be provide by a subdriver accessable trough the ili9341_dev_s @@ -157,8 +156,7 @@ /* Memory access control (MADCTL) */ -/* - * Landscape: 00100000 / 00101000 / h28 +/* Landscape: 00100000 / 00101000 / h28 * * MY: 0 * MX: 0 @@ -186,8 +184,7 @@ ILI9341_MADCTL_LANDSCAPE_BGR | \ ILI9341_MADCTL_LANDSCAPE_MH) -/* - * Portrait: 00000000 / 00001000 / h08 +/* Portrait: 00000000 / 00001000 / h08 * * MY: 0 * MX: 0 @@ -198,9 +195,9 @@ */ #define ILI9341_MADCTL_PORTRAIT_MY 0 -#define ILI9341_MADCTL_PORTRAIT_MX 0 +#define ILI9341_MADCTL_PORTRAIT_MX ILI9341_MEMORY_ACCESS_CONTROL_MX #define ILI9341_MADCTL_PORTRAIT_MV 0 -#define ILI9341_MADCTL_PORTRAIT_ML 0 +#define ILI9341_MADCTL_PORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML #ifdef CONFIG_BIG_ENDIAN # define ILI9341_MADCTL_PORTRAIT_BGR 0 #else @@ -214,8 +211,7 @@ ILI9341_MADCTL_PORTRAIT_ML | \ ILI9341_MADCTL_PORTRAIT_BGR | \ ILI9341_MADCTL_PORTRAIT_MH) -/* - * RLandscape: 01100000 / 01101000 / h68 +/* RLandscape: 01100000 / 01101000 / h68 * * MY: 0 * MX: 1 @@ -225,7 +221,7 @@ * MH: 0 */ -#define ILI9341_MADCTL_RLANDSCAPE_MY 0 +#define ILI9341_MADCTL_RLANDSCAPE_MY ILI9341_MEMORY_ACCESS_CONTROL_MY #define ILI9341_MADCTL_RLANDSCAPE_MX ILI9341_MEMORY_ACCESS_CONTROL_MX #define ILI9341_MADCTL_RLANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV #define ILI9341_MADCTL_RLANDSCAPE_ML 0 @@ -244,8 +240,7 @@ ILI9341_MADCTL_RLANDSCAPE_BGR | \ ILI9341_MADCTL_RLANDSCAPE_MH) -/* - * RPortrait: 11000000 / 11001000 / hc8 +/* RPortrait: 11000000 / 11001000 / hc8 * * MY: 1 * MX: 1 @@ -257,9 +252,9 @@ */ #define ILI9341_MADCTL_RPORTRAIT_MY ILI9341_MEMORY_ACCESS_CONTROL_MY -#define ILI9341_MADCTL_RPORTRAIT_MX ILI9341_MEMORY_ACCESS_CONTROL_MX +#define ILI9341_MADCTL_RPORTRAIT_MX 0 #define ILI9341_MADCTL_RPORTRAIT_MV 0 -#define ILI9341_MADCTL_RPORTRAIT_ML 0 +#define ILI9341_MADCTL_RPORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML #ifdef CONFIG_BIG_ENDIAN # define ILI9341_MADCTL_RPORTRAIT_BGR 0 #else @@ -292,8 +287,7 @@ #define ILI9341_PIXSET_16BITMCU_PARAM1 (ILI9341_PIXSET_16BITDPI | \ ILI9341_PIXSET_16BITDBI) -/* - * 18-bit MCU: 01100110 / h66 (not supported by nuttx until now) +/* 18-bit MCU: 01100110 / h66 (not supported by nuttx until now) * * DPI: 6 (RGB18-666 RGB interface) * DBI: 6 (RGB18-666 MCU interface) @@ -324,16 +318,16 @@ /* First LCD display */ #ifdef CONFIG_LCD_ILI9341_IFACE0 -# ifdef CONFIG_LCD_ILI9341_IFACE0_LANDSCAPE +# if defined(CONFIG_LCD_ILI9341_IFACE0_LANDSCAPE) # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1 # define ILI9341_IFACE0_STRIDE ILI9341_YRES -# elif CONFIG_LCD_ILI9341_IFACE0_PORTRAIT +# elif defined(CONFIG_LCD_ILI9341_IFACE0_PORTRAIT) # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1 # define ILI9341_IFACE0_STRIDE ILI9341_XRES -# elif CONFIG_LCD_ILI9341_IFACE0_RLANDSCAPE +# elif defined(CONFIG_LCD_ILI9341_IFACE0_RLANDSCAPE) # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1 # define ILI9341_IFACE0_STRIDE ILI9341_YRES -# elif CONFIG_LCD_ILI9341_IFACE0_RPORTRAIT +# elif defined(CONFIG_LCD_ILI9341_IFACE0_RPORTRAIT) # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1 # define ILI9341_IFACE0_STRIDE ILI9341_XRES # endif @@ -383,12 +377,11 @@ # define lcdvdbg(x...) #endif -/****************************************************************************** +/**************************************************************************** * Private Type Definition - ******************************************************************************/ + ****************************************************************************/ -/* - * Each single connected ili9341 LCD driver needs an own driver instance +/* Each single connected ili9341 LCD driver needs an own driver instance * to provide a unique getrun and putrun method. Also store fundamental * parameter in driver internal structure. This minimal overhead should be * acceptable. @@ -436,9 +429,9 @@ struct ili9341_dev_s }; -/****************************************************************************** +/**************************************************************************** * Private Function Protototypes - ******************************************************************************/ + ****************************************************************************/ /* Internal low level helpers */ @@ -453,14 +446,14 @@ static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col, static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer, size_t npixels); #endif -/* - * Definition of the public visible getrun / putrun methods + +/* Definition of the public visible getrun / putrun methods * each for a single LCD driver */ #ifdef CONFIG_LCD_ILI9341_IFACE0 static int ili9341_putrun0(fb_coord_t row, fb_coord_t col, - FAR const uint8_t * buffer, size_t npixsels); + FAR const uint8_t *buffer, size_t npixsels); #endif #ifdef CONFIG_LCD_ILI9341_IFACE1 static int ili9341_putrun1(fb_coord_t row, fb_coord_t col, @@ -492,9 +485,9 @@ static int ili9341_setpower(struct lcd_dev_s *dev, int power); static int ili9341_getcontrast(struct lcd_dev_s *dev); static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); -/****************************************************************************** +/**************************************************************************** * Private Data - ******************************************************************************/ + ****************************************************************************/ /* Initialize driver instance 1 < LCD_ILI9341_NINTERFACES */ @@ -537,11 +530,11 @@ static struct ili9341_dev_s g_lcddev[CONFIG_LCD_ILI9341_NINTERFACES] = #endif }; -/****************************************************************************** +/**************************************************************************** * Private Functions - ******************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Name: ili9341_getxres * * Description: @@ -555,7 +548,7 @@ static struct ili9341_dev_s g_lcddev[CONFIG_LCD_ILI9341_NINTERFACES] = * * Horicontal resolution * - ******************************************************************************/ + ****************************************************************************/ static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev) { @@ -569,7 +562,7 @@ static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev) } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getyres * * Description: @@ -583,7 +576,7 @@ static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev) * * Vertical resolution * - ******************************************************************************/ + ****************************************************************************/ static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev) { @@ -597,7 +590,7 @@ static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev) } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_selectarea * * Description: @@ -610,7 +603,7 @@ static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev) * x1 - End x position * y1 - End y position * - ******************************************************************************/ + ****************************************************************************/ static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) @@ -633,7 +626,7 @@ static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd, } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_putrun * * Description: @@ -652,14 +645,14 @@ static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col, FAR const uint8_t * buffer, size_t npixels) { FAR struct ili9341_dev_s *dev = &g_lcddev[devno]; FAR struct ili9341_lcd_s *lcd = dev->lcd; - FAR const uint16_t *src = (const uint16_t*)buffer; + FAR const uint16_t *src = (FAR const uint16_t *)buffer; DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); @@ -693,7 +686,7 @@ static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col, } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getrun * * Description: @@ -712,7 +705,7 @@ static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ # ifndef CONFIG_LCD_NOGETRUN static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col, @@ -720,7 +713,7 @@ static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col, { FAR struct ili9341_dev_s *dev = &g_lcddev[devno]; FAR struct ili9341_lcd_s *lcd = dev->lcd; - FAR uint16_t *dest = (uint16_t*)buffer; + FAR uint16_t *dest = (FAR uint16_t *)buffer; DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); @@ -754,7 +747,7 @@ static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col, } #endif -/******************************************************************************* +/**************************************************************************** * Name: ili9341_hwinitialize * * Description: @@ -768,7 +761,7 @@ static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col, * On success - OK * On error - EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev) { @@ -846,11 +839,11 @@ static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev) } -/******************************************************************************* +/**************************************************************************** * Public Functions - ******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: ili9341_putrunx * * Description: @@ -868,7 +861,7 @@ static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev) * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_LCD_ILI9341_IFACE0 static int ili9341_putrun0(fb_coord_t row, fb_coord_t col, @@ -887,7 +880,7 @@ static int ili9341_putrun1(fb_coord_t row, fb_coord_t col, #endif -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getrunx * * Description: @@ -905,7 +898,7 @@ static int ili9341_putrun1(fb_coord_t row, fb_coord_t col, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_LCD_NOGETRUN # ifdef CONFIG_LCD_ILI9341_IFACE0 @@ -926,7 +919,7 @@ static int ili9341_getrun1(fb_coord_t row, fb_coord_t col, #endif -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getvideoinfo * * Description: @@ -941,7 +934,7 @@ static int ili9341_getrun1(fb_coord_t row, fb_coord_t col, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev, FAR struct fb_videoinfo_s *vinfo) @@ -964,7 +957,7 @@ static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev, return -EINVAL; } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getplaneinfo * * Description: @@ -980,7 +973,7 @@ static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, FAR struct lcd_planeinfo_s *pinfo) @@ -994,7 +987,7 @@ static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, pinfo->getrun = priv->getrun; #endif pinfo->bpp = priv->bpp; - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ + pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */ lcdvdbg("planeno: %d bpp: %d\n", planeno, pinfo->bpp); @@ -1004,7 +997,7 @@ static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, return -EINVAL; } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getpower * * Description: @@ -1019,7 +1012,7 @@ static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_getpower(FAR struct lcd_dev_s *dev) { @@ -1035,7 +1028,7 @@ static int ili9341_getpower(FAR struct lcd_dev_s *dev) return -EINVAL; } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_setpower * * Description: @@ -1051,7 +1044,7 @@ static int ili9341_getpower(FAR struct lcd_dev_s *dev) * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power) { @@ -1092,7 +1085,7 @@ static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power) return -EINVAL; } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_getcontrast * * Description: @@ -1106,7 +1099,7 @@ static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power) * On success - current contrast value * On error - -ENOSYS, not supported by the ili9341. * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_getcontrast(struct lcd_dev_s *dev) { @@ -1114,7 +1107,7 @@ static int ili9341_getcontrast(struct lcd_dev_s *dev) return -ENOSYS; } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_setcontrast * * Description: @@ -1128,7 +1121,7 @@ static int ili9341_getcontrast(struct lcd_dev_s *dev) * On success - OK * On error - -ENOSYS, not supported by the ili9341. * - ******************************************************************************/ + ****************************************************************************/ static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) { @@ -1137,7 +1130,7 @@ static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) } -/******************************************************************************* +/**************************************************************************** * Name: ili9341_initialize * * Description: @@ -1158,7 +1151,7 @@ static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) * On success, this function returns a reference to the LCD driver object for * the specified LCD driver. NULL is returned on any failure. * - ******************************************************************************/ + ****************************************************************************/ FAR struct lcd_dev_s *ili9341_initialize( FAR struct ili9341_lcd_s *lcd, int devno) @@ -1201,7 +1194,7 @@ FAR struct lcd_dev_s *ili9341_initialize( } -/****************************************************************************** +/**************************************************************************** * Name: ili9341_clear * * Description: @@ -1219,7 +1212,7 @@ FAR struct lcd_dev_s *ili9341_initialize( * On success - OK * On error - -EINVAL * - ******************************************************************************/ + ****************************************************************************/ int ili9341_clear(FAR struct lcd_dev_s *dev, uint16_t color) { diff --git a/drivers/lcd/memlcd.c b/drivers/lcd/memlcd.c index 578c30a1c39f08e17d6c92aac62cd45c66d0a3f4..e960e27612a097b7314f43c5108d0a5817be2897 100644 --- a/drivers/lcd/memlcd.c +++ b/drivers/lcd/memlcd.c @@ -1,4 +1,4 @@ -/****************************************************************************** +/**************************************************************************** * drivers/lcd/memlcd.c * Driver for Sharp Memory LCD. * @@ -33,11 +33,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ******************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -55,9 +55,9 @@ #include -/****************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ /* Configuration */ @@ -119,9 +119,9 @@ # define lcdvdbg(x...) #endif -/****************************************************************************** +/**************************************************************************** * Private Type Definition - ******************************************************************************/ + ****************************************************************************/ struct memlcd_dev_s { @@ -144,20 +144,14 @@ struct memlcd_dev_s uint8_t fb[MEMLCD_FBSIZE]; }; -/****************************************************************************** +/**************************************************************************** * Private Function Protototypes - ******************************************************************************/ + ****************************************************************************/ /* Low-level spi helpers */ -static inline void memlcd_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_SPI_OWNBUS -static inline void memlcd_select(FAR struct spi_dev_s *spi); -static inline void memlcd_deselect(FAR struct spi_dev_s *spi); -#else static void memlcd_select(FAR struct spi_dev_s *spi); static void memlcd_deselect(FAR struct spi_dev_s *spi); -#endif /* lcd data transfer methods */ @@ -180,9 +174,9 @@ static int memlcd_setpower(struct lcd_dev_s *dev, int power); static int memlcd_getcontrast(struct lcd_dev_s *dev); static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); -/****************************************************************************** +/**************************************************************************** * Private Data - ******************************************************************************/ + ****************************************************************************/ static uint8_t g_runbuffer[MEMLCD_BPP * MEMLCD_XRES / 8]; @@ -226,11 +220,11 @@ static struct memlcd_dev_s g_memlcddev = }, }; -/****************************************************************************** +/**************************************************************************** * Private Functions - ******************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * __set_bit - Set a bit in memory * * @nr: the bit to set @@ -240,7 +234,7 @@ static struct memlcd_dev_s g_memlcddev = * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. * - ******************************************************************************/ + ****************************************************************************/ #define BIT(nr) (1 << (nr)) #define BITS_PER_BYTE 8 @@ -266,48 +260,7 @@ static inline int __test_bit(int nr, const volatile uint8_t * addr) return 1 & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE - 1))); } -/****************************************************************************** - * Name: memlcd_configspi - * - * Description: - * Configure the SPI for use with the Sharp Memory LCD - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - ******************************************************************************/ - -static inline void memlcd_configspi(FAR struct spi_dev_s *spi) -{ -#ifdef CONFIG_MEMLCD_SPI_FREQUENCY - lcddbg("Mode: %d Bits: %d Frequency: %d\n", - MEMLCD_SPI_MODE, MEMLCD_SPI_BITS, CONFIG_MEMLCD_SPI_FREQUENCY); -#else - lcddbg("Mode: %d Bits: %d Frequency: %d\n", - MEMLCD_SPI_MODE, MEMLCD_SPI_BITS, MEMLCD_SPI_FREQUENCY); -#endif - - /* Configure SPI for the Memory LCD. But only if we own the SPI bus. - * Otherwise, don't bother because it might change. - */ - -#ifdef CONFIG_SPI_OWNBUS - SPI_SETMODE(spi, MEMLCD_SPI_MODE); - SPI_SETBITS(spi, MEMLCD_SPI_BITS); -# ifdef CONFIG_MEMLCD_SPI_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY); -# else - SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY); -# endif -#endif -} - -/******************************************************************************* +/**************************************************************************** * Name: memlcd_select * * Description: @@ -321,40 +274,32 @@ static inline void memlcd_configspi(FAR struct spi_dev_s *spi) * * Assumptions: * - ******************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void memlcd_select(FAR struct spi_dev_s *spi) -{ - /* we own the spi bus, so just select the chip */ - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} + ****************************************************************************/ -#else static void memlcd_select(FAR struct spi_dev_s *spi) { - /* - * Select memlcd (locking the SPI bus in case there are multiple + /* Select memlcd (locking the SPI bus in case there are multiple * devices competing for the SPI bus */ + SPI_LOCK(spi, true); SPI_SELECT(spi, SPIDEV_DISPLAY, true); - /* - * Now make sure that the SPI bus is configured for the memlcd (it + /* Now make sure that the SPI bus is configured for the memlcd (it * might have gotten configured for a different device while unlocked) */ + SPI_SETMODE(spi, MEMLCD_SPI_MODE); SPI_SETBITS(spi, MEMLCD_SPI_BITS); + (void)SPI_HWFEATURES(spi, 0); # ifdef CONFIG_MEMLCD_SPI_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY); + (void)SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY); # else - SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY); + (void)SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY); # endif } -#endif -/******************************************************************************* +/**************************************************************************** * Name: memlcd_deselect * * Description: @@ -368,24 +313,17 @@ static void memlcd_select(FAR struct spi_dev_s *spi) * * Assumptions: * - ******************************************************************************/ + ****************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void memlcd_deselect(FAR struct spi_dev_s *spi) -{ - /* we own the spi bus, so just de-select the chip */ - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else static void memlcd_deselect(FAR struct spi_dev_s *spi) { - /* de-select memlcd and relinquish the spi bus. */ + /* De-select memlcd and relinquish the spi bus. */ + SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); } -#endif -/******************************************************************************* +/**************************************************************************** * Name: memlcd_clear * * Description: @@ -396,7 +334,7 @@ static void memlcd_deselect(FAR struct spi_dev_s *spi) * * Assumptions: * - ******************************************************************************/ + ****************************************************************************/ static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd) { @@ -409,7 +347,7 @@ static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd) memlcd_deselect(mlcd->spi); } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_extcominisr * * Description: @@ -427,7 +365,7 @@ static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd) * Assumptions: * Board specific logic needs to be provided to support it. * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_extcominisr(int irq, FAR void *context) { @@ -435,9 +373,8 @@ static int memlcd_extcominisr(int irq, FAR void *context) struct memlcd_dev_s *mlcd = &g_memlcddev; #ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW # error "CONFIG_MEMLCD_EXTCOMIN_MODE_HW unsupported yet!" - /* - * start a worker thread, do it in bottom half? - */ + /* Start a worker thread, do it in bottom half? */ + #else pol = !pol; mlcd->priv->setpolarity(pol); @@ -445,7 +382,7 @@ static int memlcd_extcominisr(int irq, FAR void *context) return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_putrun * * Description: @@ -458,7 +395,7 @@ static int memlcd_extcominisr(int irq, FAR void *context) * npixels - The number of pixels to write to the LCD * (range: 0 < npixels <= xres-col) * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t * buffer, size_t npixels) @@ -538,7 +475,7 @@ static int memlcd_putrun(fb_coord_t row, fb_coord_t col, return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_getrun * * Description: @@ -550,7 +487,7 @@ static int memlcd_putrun(fb_coord_t row, fb_coord_t col, * npixels - The number of pixels to read from the LCD * (range: 0 < npixels <= xres-col) * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer, size_t npixels) @@ -609,13 +546,13 @@ static int memlcd_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer, return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_getvideoinfo * * Description: * Get information about the LCD video controller configuration. * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_getvideoinfo(FAR struct lcd_dev_s *dev, FAR struct fb_videoinfo_s *vinfo) { @@ -627,13 +564,13 @@ static int memlcd_getvideoinfo(FAR struct lcd_dev_s *dev, return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_getplaneinfo * * Description: * Get information about the configuration of each LCD color plane. * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, FAR struct lcd_planeinfo_s *pinfo) @@ -644,14 +581,14 @@ static int memlcd_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_getpower * * Description: * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full on. * On backlit LCDs, this setting may correspond to the backlight setting. * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_getpower(FAR struct lcd_dev_s *dev) { @@ -661,14 +598,14 @@ static int memlcd_getpower(FAR struct lcd_dev_s *dev) return mlcd->power; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_setpower * * Description: * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). * On backlit LCDs, this setting may correspond to the backlight setting. * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_setpower(FAR struct lcd_dev_s *dev, int power) { @@ -690,13 +627,13 @@ static int memlcd_setpower(FAR struct lcd_dev_s *dev, int power) return OK; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_getcontrast * * Description: * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_getcontrast(struct lcd_dev_s *dev) { @@ -706,13 +643,13 @@ static int memlcd_getcontrast(struct lcd_dev_s *dev) return mlcd->contrast; } -/******************************************************************************* +/**************************************************************************** * Name: memlcd_setcontrast * * Description: * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). * - ******************************************************************************/ + ****************************************************************************/ static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) { @@ -734,11 +671,11 @@ static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) return OK; } -/******************************************************************************* +/**************************************************************************** * Public Functions - ******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: memlcd_initialize * * Description: @@ -757,7 +694,7 @@ static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) * On success, this function returns a reference to the LCD object for * the specified LCD. NULL is returned on any failure. * - ******************************************************************************/ + ****************************************************************************/ FAR struct lcd_dev_s *memlcd_initialize(FAR struct spi_dev_s *spi, FAR struct memlcd_priv_s *priv, unsigned int devno) @@ -766,11 +703,10 @@ FAR struct lcd_dev_s *memlcd_initialize(FAR struct spi_dev_s *spi, DEBUGASSERT(spi && priv && devno == 0); - /* register board specific functions */ - mlcd->priv = priv; + /* Register board specific functions */ + mlcd->priv = priv; mlcd->spi = spi; - memlcd_configspi(spi); mlcd->priv->attachirq(memlcd_extcominisr); diff --git a/drivers/lcd/mio283qt2.c b/drivers/lcd/mio283qt2.c index 6b87c670e52d6ec244d7d47a741475f9c21fb7c4..2d078e1ff09ff1c5dc1ec3dc90ecddd2c4978782 100644 --- a/drivers/lcd/mio283qt2.c +++ b/drivers/lcd/mio283qt2.c @@ -529,7 +529,7 @@ static int mio283qt2_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *b { FAR struct mio283qt2_dev_s *priv = &g_lcddev; FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - FAR const uint16_t *src = (FAR const uint16_t*)buffer; + FAR const uint16_t *src = (FAR const uint16_t *)buffer; int i; /* Buffer must be provided and aligned to a 16-bit address boundary */ @@ -578,7 +578,7 @@ static int mio283qt2_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, #ifndef CONFIG_LCD_NOGETRUN FAR struct mio283qt2_dev_s *priv = &g_lcddev; FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; + FAR uint16_t *dest = (FAR uint16_t *)buffer; uint16_t accum; int i; @@ -658,10 +658,10 @@ static int mio283qt2_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planen DEBUGASSERT(dev && pinfo && planeno == 0); lcdvdbg("planeno: %d bpp: %d\n", planeno, MIO283QT2_BPP); - pinfo->putrun = mio283qt2_putrun; /* Put a run into LCD memory */ - pinfo->getrun = mio283qt2_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = MIO283QT2_BPP; /* Bits-per-pixel */ + pinfo->putrun = mio283qt2_putrun; /* Put a run into LCD memory */ + pinfo->getrun = mio283qt2_getrun; /* Get a run from LCD memory */ + pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */ + pinfo->bpp = MIO283QT2_BPP; /* Bits-per-pixel */ return OK; } @@ -937,7 +937,7 @@ static inline int mio283qt2_hwinitialize(FAR struct mio283qt2_dev_s *priv) return ret; } - /************************************************************************************* +/************************************************************************************** * Public Functions **************************************************************************************/ diff --git a/drivers/lcd/mio283qt9a.c b/drivers/lcd/mio283qt9a.c index 8ec36a3abdc1571893983ebebfea1e924378c851..d98935f84f252685cc038e7cdee9147e2e0a75c8 100644 --- a/drivers/lcd/mio283qt9a.c +++ b/drivers/lcd/mio283qt9a.c @@ -382,16 +382,15 @@ static inline uint16_t mio283qt9a_gramread(FAR struct mio283qt9a_lcd_s *lcd, static void mio283qt9a_setarea(FAR struct mio283qt9a_lcd_s *lcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - //lcddbg("setarea x0=%d, y0=%d, x1=%d, y1=%d\n", x0, y0, x1, y1); - - mio283qt9a_putreg(lcd, 0x2a, (x0 >> 8)); /* set column address x0 */ - lcd->write(lcd, (x0 & 0xff)); /* set x0 */ - lcd->write(lcd, (x1 >> 8)); /* set x1 */ - lcd->write(lcd, (x1 & 0xff)); /* set x1 */ - mio283qt9a_putreg(lcd, 0x2b, (y0 >> 8)); /* set page address y0 */ - lcd->write(lcd, (y0 & 0xff)); /* set y0 */ - lcd->write(lcd, (y1 >> 8)); /* set y1 */ - lcd->write(lcd, (y1 & 0xff)); /* set y1 */ + mio283qt9a_putreg(lcd, 0x2a, (x0 >> 8)); /* Set column address x0 */ + lcd->write(lcd, (x0 & 0xff)); /* Set x0 */ + lcd->write(lcd, (x1 >> 8)); /* Set x1 */ + lcd->write(lcd, (x1 & 0xff)); /* Set x1 */ + + mio283qt9a_putreg(lcd, 0x2b, (y0 >> 8)); /* Set page address y0 */ + lcd->write(lcd, (y0 & 0xff)); /* Set y0 */ + lcd->write(lcd, (y1 >> 8)); /* Set y1 */ + lcd->write(lcd, (y1 & 0xff)); /* Set y1 */ } /************************************************************************************** @@ -445,12 +444,11 @@ static int mio283qt9a_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t * { FAR struct mio283qt9a_dev_s *priv = &g_lcddev; FAR struct mio283qt9a_lcd_s *lcd = priv->lcd; - FAR const uint16_t *src = (FAR const uint16_t*)buffer; + FAR const uint16_t *src = (FAR const uint16_t *)buffer; int i; /* Buffer must be provided and aligned to a 16-bit address boundary */ - //lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); /* Select the LCD */ @@ -494,7 +492,7 @@ static int mio283qt9a_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer #ifndef CONFIG_LCD_NOGETRUN FAR struct mio283qt9a_dev_s *priv = &g_lcddev; FAR struct mio283qt9a_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; + FAR uint16_t *dest = (FAR uint16_t *)buffer; uint16_t accum, test; int i; @@ -520,8 +518,7 @@ static int mio283qt9a_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer for (i = 0; i < npixels; i++) { - test= mio283qt9a_gramread(lcd, &accum); - // lcddbg("read 0x%04x\n", test); + test = mio283qt9a_gramread(lcd, &accum); *dest++ = test; } @@ -572,10 +569,10 @@ static int mio283qt9a_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int plane DEBUGASSERT(dev && pinfo && planeno == 0); lcdvdbg("planeno: %d bpp: %d\n", planeno, MIO283QT9A_BPP); - pinfo->putrun = mio283qt9a_putrun; /* Put a run into LCD memory */ - pinfo->getrun = mio283qt9a_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = MIO283QT9A_BPP; /* Bits-per-pixel */ + pinfo->putrun = mio283qt9a_putrun; /* Put a run into LCD memory */ + pinfo->getrun = mio283qt9a_getrun; /* Get a run from LCD memory */ + pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */ + pinfo->bpp = MIO283QT9A_BPP; /* Bits-per-pixel */ return OK; } @@ -833,7 +830,7 @@ static inline int mio283qt9a_hwinitialize(FAR struct mio283qt9a_dev_s *priv) return ret; } - /************************************************************************************* +/************************************************************************************** * Public Functions **************************************************************************************/ diff --git a/drivers/lcd/nokia6100.c b/drivers/lcd/nokia6100.c index 3677d8bfe35f6aae2031e8e94e5c1a0644f8d46c..5a7e6ab976f0dcf53a1da18068078b350cb60d77 100644 --- a/drivers/lcd/nokia6100.c +++ b/drivers/lcd/nokia6100.c @@ -338,14 +338,8 @@ struct nokia_dev_s /* SPI support */ -static inline void nokia_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_select(FAR struct spi_dev_s *spi); -static inline void nokia_deselect(FAR struct spi_dev_s *spi); -#else static void nokia_select(FAR struct spi_dev_s *spi); static void nokia_deselect(FAR struct spi_dev_s *spi); -#endif static void nokia_sndcmd(FAR struct spi_dev_s *spi, const uint8_t cmd); static void nokia_cmdarray(FAR struct spi_dev_s *spi, int len, const uint8_t *cmddata); static void nokia_clrram(FAR struct spi_dev_s *spi); @@ -435,10 +429,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = nokia_putrun, /* Put a run into LCD memory */ - .getrun = nokia_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = NOKIA_BPP, /* Bits-per-pixel */ + .putrun = nokia_putrun, /* Put a run into LCD memory */ + .getrun = nokia_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = NOKIA_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -477,21 +471,21 @@ static struct nokia_dev_s g_lcddev = #if 1 // CONFIG_NOKIA6100_BPP == 12 static const uint8_t g_disctl[] = { - S1D15G10_DISCTL, /* Display control */ - DISCTL_CLDIV_2|DISCTL_PERIOD_8, /* P1: Divide clock by 2; switching period = 8 */ -//DISCTL_CLDIV_NONE|DISCTL_PERIOD_8, /* P1: No clock division; switching period = 8 */ - 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ - 0, /* P3: No inversely highlighted lines */ - 0 /* P4: No disperion */ + S1D15G10_DISCTL, /* Display control */ + DISCTL_CLDIV_2 | DISCTL_PERIOD_8, /* P1: Divide clock by 2; switching period = 8 */ +//DISCTL_CLDIV_NONE | DISCTL_PERIOD_8, /* P1: No clock division; switching period = 8 */ + 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ + 0, /* P3: No inversely highlighted lines */ + 0 /* P4: No disperion */ }; #else /* CONFIG_NOKIA6100_BPP == 8 */ static const uint8_t g_disctl[] = { - S1D15G10_DISCTL, /* Display control */ - DISCTL_CLDIV_2|DISCTL_PERIOD_FLD, /* P1: Divide clock by 2; switching period = field */ - 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ - 0, /* P3: No inversely highlighted lines */ - 0 /* P4: No disperion */ + S1D15G10_DISCTL, /* Display control */ + DISCTL_CLDIV_2 | DISCTL_PERIOD_FLD, /* P1: Divide clock by 2; switching period = field */ + 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ + 0, /* P3: No inversely highlighted lines */ + 0 /* P4: No disperion */ }; #endif @@ -501,8 +495,8 @@ static const uint8_t g_disctl[] = static const uint8_t g_comscn[] = { - S1D15G10_COMSCN, /* Common scan direction */ - 1 /* 0x01 = Scan 1->68, 132<-69 */ + S1D15G10_COMSCN, /* Common scan direction */ + 1 /* 0x01 = Scan 1->68, 132<-69 */ }; /* Power control: @@ -513,7 +507,7 @@ static const uint8_t g_comscn[] = static const uint8_t g_pwrctr[] = { S1D15G10_PWRCTR, /* Power control */ - PWCTR_REFVOLTAGE|PWCTR_REGULATOR|PWCTR_BOOSTER2|PWCTR_BOOSTER1 + PWCTR_REFVOLTAGE | PWCTR_REGULATOR | PWCTR_BOOSTER2 | PWCTR_BOOSTER1 }; /* Data control: @@ -528,13 +522,13 @@ static const uint8_t g_datctl[] = S1D15G10_DATCTL, /* Data control */ 0 #if CONFIG_NOKIA6100_MY != 0 /* Display row direction */ - |DATCTL_PGADDR_INV /* Page address inverted */ + | DATCTL_PGADDR_INV /* Page address inverted */ #endif #if CONFIG_NOKIA6100_MX != 0 /* Display column direction */ - |DATCTL_COLADDR_REV /* Column address reversed */ + | DATCTL_COLADDR_REV /* Column address reversed */ #endif #if CONFIG_NOKIA6100_V != 0 /* Display address direction */ - |DATCTL_ADDR_PGDIR /* Address scan in page direction */ + | DATCTL_ADDR_PGDIR /* Address scan in page direction */ #endif , #if CONFIG_NOKIA6100_RGBORD != 0 @@ -617,22 +611,22 @@ static const uint8_t g_colmod[] = static const uint8_t g_madctl[] = { - PCF8833_MADCTL, /* Memory data access control*/ + PCF8833_MADCTL, /* Memory data access control */ 0 #ifdef CONFIG_NOKIA6100_RGBORD != 0 - |MADCTL_RGB /* RGB->BGR */ + | MADCTL_RGB /* RGB->BGR */ #endif -#ifdef CONFIG_NOKIA6100_MY != 0 /* Display row direction */ - |MADCTL_MY /* Mirror Y */ +#ifdef CONFIG_NOKIA6100_MY != 0 /* Display row direction */ + | MADCTL_MY /* Mirror Y */ #endif -#ifdef CONFIG_NOKIA6100_MX != 0 /* Display column direction */ - |MADCTL_MX /* Mirror X */ +#ifdef CONFIG_NOKIA6100_MX != 0 /* Display column direction */ + | MADCTL_MX /* Mirror X */ #endif -#ifdef CONFIG_NOKIA6100_V != 0 /* Display address direction */ - |MADCTL_V /* ertical RAM write; in Y direction */ +#ifdef CONFIG_NOKIA6100_V != 0 /* Display address direction */ + | MADCTL_V /* ertical RAM write; in Y direction */ #endif -#ifdef CONFIG_NOKIA6100_ML != 0 /* Display scan direction */ - |MADCTL_LAO /* Line address order bottom to top */ +#ifdef CONFIG_NOKIA6100_ML != 0 /* Display scan direction */ + | MADCTL_LAO /* Line address order bottom to top */ #endif }; @@ -650,38 +644,6 @@ static const uint8_t g_setcon[] = * Private Functions **************************************************************************************/ -/************************************************************************************** - * Function: nokia_configspi - * - * Description: - * Configure the SPI for use with the Nokia 6100 - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -static inline void nokia_configspi(FAR struct spi_dev_s *spi) -{ - lcddbg("Mode: %d Bits: %d Frequency: %d\n", - CONFIG_NOKIA6100_SPIMODE, CONFIG_NOKIA6100_WORDWIDTH, CONFIG_NOKIA6100_FREQUENCY); - - /* Configure SPI for the Nokia 6100. But only if we own the SPI bus. Otherwise, don't - * bother because it might change. - */ - -#ifdef CONFIG_SPI_OWNBUS - SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); - SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); - SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY) -#endif -} - /************************************************************************************** * Function: nokia_select * @@ -698,15 +660,6 @@ static inline void nokia_configspi(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - lcddbg("SELECTED\n"); - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else static void nokia_select(FAR struct spi_dev_s *spi) { /* Select Nokia 6100 chip (locking the SPI bus in case there are multiple @@ -723,9 +676,9 @@ static void nokia_select(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); - SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY); } -#endif /************************************************************************************** * Function: nokia_deselect @@ -743,15 +696,6 @@ static void nokia_select(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - lcddbg("DE-SELECTED\n"); - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else static void nokia_deselect(FAR struct spi_dev_s *spi) { /* De-select Nokia 6100 chip and relinquish the SPI bus. */ @@ -760,7 +704,6 @@ static void nokia_deselect(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); } -#endif /************************************************************************************** * Name: nokia_sndcmd @@ -931,7 +874,7 @@ static int nokia_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffe #if NOKIA_YBIAS > 0 row += NOKIA_YBIAS; #endif - DEBUGASSERT(buffer && col >=0 && (col + npixels) <= NOKIA_XRES && row >= 0 && row < NOKIA_YRES); + DEBUGASSERT(buffer && col >= 0 && (col + npixels) <= NOKIA_XRES && row >= 0 && row < NOKIA_YRES); /* Set up to write the run. */ @@ -1130,6 +1073,13 @@ static int nokia_initialize(struct nokia_dev_s *priv) { struct spi_dev_s *spi = priv->spi; + /* Configure SPI */ + + SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); + SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY); + /* Configure the display */ nokia_cmdarray(spi, sizeof(g_disctl), g_disctl); /* Display control */ @@ -1153,6 +1103,7 @@ static int nokia_initialize(struct nokia_dev_s *priv) nokia_cmdarray(spi, sizeof(g_paset), g_caset); /* Column address set */ nokia_clrram(spi); nokia_sndcmd(spi, S1D15G10_DISON); /* Display on */ + return OK; } #endif @@ -1162,6 +1113,15 @@ static int nokia_initialize(struct nokia_dev_s *priv) { struct struct spi_dev_s *spi = priv->spi; + /* Configure SPI */ + + SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); + SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY); + + /* Configure the display */ + nokia_sndcmd(spi, PCF8833_SLEEPOUT); /* Exit sleep mode */ nokia_sndcmd(spi, PCF8833_BSTRON); /* Turn on voltage booster */ #ifdef CONFIG_NOKIA6100_INVERT @@ -1175,6 +1135,7 @@ static int nokia_initialize(struct nokia_dev_s *priv) nokia_sndcmd(spi, PCF8833_NOP); /* No operation */ nokia_clrram(spi); nokia_sndcmd(spi, PCF8833_DISPON); /* Display on */ + return OK; } #endif /* CONFIG_NOKIA6100_PCF8833 */ @@ -1216,9 +1177,8 @@ FAR struct lcd_dev_s *nokia_lcdinitialize(FAR struct spi_dev_s *spi, unsigned in priv->spi = spi; /* Save the SPI instance */ priv->contrast = NOKIA_DEFAULT_CONTRAST; /* Initial contrast setting */ - /* Configure and enable the LCD controller */ + /* Enable the LCD controller */ - nokia_configspi(spi); if (nokia_initialize(priv) == OK) { /* Turn on the backlight */ @@ -1226,5 +1186,6 @@ FAR struct lcd_dev_s *nokia_lcdinitialize(FAR struct spi_dev_s *spi, unsigned in nokia_backlight(CONFIG_NOKIA6100_BLINIT); return &priv->dev; } + return NULL; } diff --git a/drivers/lcd/p14201.c b/drivers/lcd/p14201.c index dbd69a271d4acd7a9206aeac1ec215c1d3b1b147..8d51c77a97695823e8629b96ffc7eb8c05911ede 100644 --- a/drivers/lcd/p14201.c +++ b/drivers/lcd/p14201.c @@ -205,14 +205,8 @@ struct rit_dev_s /* Low-level SPI helpers */ -static inline void rit_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_select(FAR struct spi_dev_s *spi); -static inline void rit_deselect(FAR struct spi_dev_s *spi); -#else static void rit_select(FAR struct spi_dev_s *spi); static void rit_deselect(FAR struct spi_dev_s *spi); -#endif static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer, size_t buflen, bool cmd); static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table); @@ -283,20 +277,20 @@ static uint8_t g_framebuffer[RIT_YRES * RIT_XRES / 2]; static const struct fb_videoinfo_s g_videoinfo = { - .fmt = RIT_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = RIT_XRES, /* Horizontal resolution in pixel columns */ - .yres = RIT_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ + .fmt = RIT_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ + .xres = RIT_XRES, /* Horizontal resolution in pixel columns */ + .yres = RIT_YRES, /* Vertical resolution in pixel rows */ + .nplanes = 1, /* Number of color planes supported */ }; /* This is the standard, NuttX Plane information object */ static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = rit_putrun, /* Put a run into LCD memory */ - .getrun = rit_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = RIT_BPP, /* Bits-per-pixel */ + .putrun = rit_putrun, /* Put a run into LCD memory */ + .getrun = rit_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = RIT_BPP, /* Bits-per-pixel */ }; /* This is the OLED driver instance (only a single device is supported for now) */ @@ -347,8 +341,8 @@ static const uint8_t g_initcmds[] = (31 << 1) | SSD1329_PRECHRG2_DBL, /* Pre-charge speed == 32, doubled */ SSD1329_NOOP, 3, SSD1329_GDDRAM_REMAP, /* Set GDDRAM re-map */ - (SSD1329_COM_SPLIT| /* Enable COM slip even/odd */ - SSD1329_COM_REMAP| /* Enable COM re-map */ + (SSD1329_COM_SPLIT | /* Enable COM slip even/odd */ + SSD1329_COM_REMAP | /* Enable COM re-map */ SSD1329_NIBBLE_REMAP), /* Enable nibble re-map */ SSD1329_NOOP, 3, SSD1329_VERT_START, /* Set Display Start Line */ @@ -405,7 +399,7 @@ static const uint8_t g_sleepon[] = static const uint8_t g_horzinc[] = { SSD1329_GDDRAM_REMAP, - (SSD1329_COM_SPLIT|SSD1329_COM_REMAP|SSD1329_NIBBLE_REMAP), + (SSD1329_COM_SPLIT | SSD1329_COM_REMAP | SSD1329_NIBBLE_REMAP), }; /* The following set a window that covers the entire display */ @@ -428,44 +422,6 @@ static const uint8_t g_setallrow[] = * Private Functions **************************************************************************************/ -/************************************************************************************** - * Name: rit_configspi - * - * Description: - * Configure the SPI for use with the P14201 - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -static inline void rit_configspi(FAR struct spi_dev_s *spi) -{ -#ifdef CONFIG_P14201_FREQUENCY - ritdbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_P14201_SPIMODE, CONFIG_P14201_FREQUENCY); -#else - ritdbg("Mode: %d Bits: 8\n", CONFIG_P14201_SPIMODE); -#endif - - /* Configure SPI for the P14201. But only if we own the SPI bus. Otherwise, don't - * bother because it might change. - */ - -#ifdef CONFIG_SPI_OWNBUS - SPI_SETMODE(spi, CONFIG_P14201_SPIMODE); - SPI_SETBITS(spi, 8); -#ifdef CONFIG_P14201_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY) -#endif -#endif -} - /************************************************************************************** * Name: rit_select * @@ -482,14 +438,6 @@ static inline void rit_configspi(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else static void rit_select(FAR struct spi_dev_s *spi) { /* Select P14201 chip (locking the SPI bus in case there are multiple @@ -505,11 +453,11 @@ static void rit_select(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_P14201_SPIMODE); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); #ifdef CONFIG_P14201_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY); + (void)SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY); #endif } -#endif /************************************************************************************** * Name: rit_deselect @@ -527,14 +475,6 @@ static void rit_select(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else static void rit_deselect(FAR struct spi_dev_s *spi) { /* De-select P14201 chip and relinquish the SPI bus. */ @@ -542,7 +482,6 @@ static void rit_deselect(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); } -#endif /************************************************************************************** * Name: rit_sndbytes @@ -570,7 +509,7 @@ static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer, uint8_t tmp; ritdbg("buflen: %d cmd: %s [%02x %02x %02x]\n", - buflen, cmd ? "YES" : "NO", buffer[0], buffer[1], buffer[2] ); + buflen, cmd ? "YES" : "NO", buffer[0], buffer[1], buffer[2]); DEBUGASSERT(spi); /* Clear/set the D/Cn bit to enable command or data mode */ @@ -769,19 +708,19 @@ static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, memcpy(&run[start], buffer, aend - start); } - /* An even number of byte-aligned pixel pairs have been written (where - * zero counts as an even number). If npixels was was odd (including - * npixels == 1), then handle the final, byte aligned pixel. - */ + /* An even number of byte-aligned pixel pairs have been written (where + * zero counts as an even number). If npixels was was odd (including + * npixels == 1), then handle the final, byte aligned pixel. + */ - if (aend != end) - { - /* The leftmost column is contained in source bits 7:4 and in - * destination bits 7:4 - */ + if (aend != end) + { + /* The leftmost column is contained in source bits 7:4 and in + * destination bits 7:4 + */ - run[aend] = (run[aend] & 0x0f) | (buffer[aend - start] & 0xf0); - } + run[aend] = (run[aend] & 0x0f) | (buffer[aend - start] & 0xf0); + } } /* CASE 2: First pixel X position is byte aligned @@ -825,10 +764,10 @@ static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, run[i] = (last << 4) | (curr >> 4); } - /* An odd number of unaligned pixel have been written (where npixels - * may have been as small as one). If npixels was was even, then handle - * the final, unaligned pixel. - */ + /* An odd number of unaligned pixel have been written (where npixels + * may have been as small as one). If npixels was was even, then handle + * the final, unaligned pixel. + */ if (aend != end) { @@ -1227,7 +1166,6 @@ FAR struct lcd_dev_s *rit_initialize(FAR struct spi_dev_s *spi, unsigned int dev /* Select the SD1329 controller */ - rit_configspi(spi); rit_select(spi); /* Clear the display */ diff --git a/drivers/lcd/pcf8833.h b/drivers/lcd/pcf8833.h index 36dc65ac3f5d4735ac2d7ca0e092b525c29f7e27..bc58ea6f5aa433a26539d3400a467ed346e3f651 100644 --- a/drivers/lcd/pcf8833.h +++ b/drivers/lcd/pcf8833.h @@ -149,4 +149,4 @@ /* Byte 4: All zero */ -#endif /* __DRIVERS_LCD_PCF8833_H */ \ No newline at end of file +#endif /* __DRIVERS_LCD_PCF8833_H */ diff --git a/drivers/lcd/ra8875.c b/drivers/lcd/ra8875.c index 53fb9736192319f17703db28506a9038bef38c6b..aa8758ab649baa083f5354e03e0b23d1d1185978 100644 --- a/drivers/lcd/ra8875.c +++ b/drivers/lcd/ra8875.c @@ -391,9 +391,10 @@ static void ra8875_waitreg(FAR struct ra8875_lcd_s *lcd, uint8_t regaddr, uint8_ { int i = 20000/100; - while (i-- && ra8875_readreg(lcd, regaddr) & mask) { - up_udelay(100); - } + while (i-- && ra8875_readreg(lcd, regaddr) & mask) + { + up_udelay(100); + } } #endif @@ -624,9 +625,9 @@ static int ra8875_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buff #if RA8875_BPP == 16 DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - FAR const uint16_t *src = (FAR const uint16_t*)buffer; + FAR const uint16_t *src = (FAR const uint16_t *)buffer; #else - FAR const uint8_t *src = (FAR const uint8_t*)buffer; + FAR const uint8_t *src = (FAR const uint8_t *)buffer; #endif int i; @@ -733,7 +734,7 @@ static int ra8875_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, #ifndef CONFIG_LCD_NOGETRUN FAR struct ra8875_dev_s *priv = &g_lcddev; FAR struct ra8875_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; + FAR uint16_t *dest = (FAR uint16_t *)buffer; int i; /* Buffer must be provided and aligned to a 16-bit address boundary */ @@ -854,10 +855,10 @@ static int ra8875_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, DEBUGASSERT(dev && pinfo && planeno == 0); lcdvdbg("planeno: %d bpp: %d\n", planeno, RA8875_BPP); - pinfo->putrun = ra8875_putrun; /* Put a run into LCD memory */ - pinfo->getrun = ra8875_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = RA8875_BPP; /* Bits-per-pixel */ + pinfo->putrun = ra8875_putrun; /* Put a run into LCD memory */ + pinfo->getrun = ra8875_getrun; /* Get a run from LCD memory */ + pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */ + pinfo->bpp = RA8875_BPP; /* Bits-per-pixel */ return OK; } @@ -990,7 +991,7 @@ static inline int ra8875_hwinitialize(FAR struct ra8875_dev_s *priv) uint8_t rv; FAR struct ra8875_lcd_s *lcd = priv->lcd; - /*@@TODO: Maybe some of these values needs to be configurable?? */ + /* REVISIT: Maybe some of these values needs to be configurable?? */ lcdvdbg("hwinitialize\n"); @@ -1079,7 +1080,7 @@ static inline int ra8875_hwinitialize(FAR struct ra8875_dev_s *priv) return OK; } - /************************************************************************************* +/************************************************************************************** * Public Functions **************************************************************************************/ diff --git a/drivers/lcd/s1d15g10.h b/drivers/lcd/s1d15g10.h index 9b5f7738fe2b09b0334aecde1f68ac633a5d51b2..09cd7286dc3e16ee6aa5d4de00ec041fa72476f6 100644 --- a/drivers/lcd/s1d15g10.h +++ b/drivers/lcd/s1d15g10.h @@ -138,4 +138,4 @@ #define S1D15G10_SR_RRATIO 0x07 /* Bits 0-2: Built-in resistance ratio */ -#endif /* __DRIVERS_LCD_S1D15G10_H */ \ No newline at end of file +#endif /* __DRIVERS_LCD_S1D15G10_H */ diff --git a/drivers/lcd/skeleton.c b/drivers/lcd/skeleton.c index 2154ed5aea263f805703a47fe21351911fe71f92..454fdcc41a20f2a1e1bbfe68965f12866e4d7006 100644 --- a/drivers/lcd/skeleton.c +++ b/drivers/lcd/skeleton.c @@ -178,10 +178,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = skel_putrun, /* Put a run into LCD memory */ - .getrun = skel_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = SKEL_BPP, /* Bits-per-pixel */ + .putrun = skel_putrun, /* Put a run into LCD memory */ + .getrun = skel_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = SKEL_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -395,7 +395,7 @@ FAR struct lcd_dev_s *up_oledinitialize(FAR struct spi_dev_s *spi) #warning "Missing logic" /* Configure and enable LCD */ - #warning "Missing logic" +#warning "Missing logic" return &g_lcddev.dev; } diff --git a/drivers/lcd/ssd1289.c b/drivers/lcd/ssd1289.c index bcc3348324407f62f86b0c2bc320b5d9d2a12ec2..f5cef7996c1aafe0485af965eecb94cc469e440d 100644 --- a/drivers/lcd/ssd1289.c +++ b/drivers/lcd/ssd1289.c @@ -588,7 +588,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf { FAR struct ssd1289_dev_s *priv = &g_lcddev; FAR struct ssd1289_lcd_s *lcd = priv->lcd; - FAR const uint16_t *src = (FAR const uint16_t*)buffer; + FAR const uint16_t *src = (FAR const uint16_t *)buffer; int i; /* Buffer must be provided and aligned to a 16-bit address boundary */ @@ -718,7 +718,7 @@ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, #ifndef CONFIG_LCD_NOGETRUN FAR struct ssd1289_dev_s *priv = &g_lcddev; FAR struct ssd1289_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; + FAR uint16_t *dest = (FAR uint16_t *)buffer; uint16_t accum; int i; @@ -872,10 +872,10 @@ static int ssd1289_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, DEBUGASSERT(dev && pinfo && planeno == 0); lcdvdbg("planeno: %d bpp: %d\n", planeno, SSD1289_BPP); - pinfo->putrun = ssd1289_putrun; /* Put a run into LCD memory */ - pinfo->getrun = ssd1289_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = SSD1289_BPP; /* Bits-per-pixel */ + pinfo->putrun = ssd1289_putrun; /* Put a run into LCD memory */ + pinfo->getrun = ssd1289_getrun; /* Get a run from LCD memory */ + pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */ + pinfo->bpp = SSD1289_BPP; /* Bits-per-pixel */ return OK; } @@ -1284,7 +1284,7 @@ static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv) return ret; } - /************************************************************************************* +/************************************************************************************** * Public Functions **************************************************************************************/ diff --git a/drivers/lcd/ssd1306.h b/drivers/lcd/ssd1306.h index 8dbb4f1a8316c45ad72f94de526a0c7aca78525d..6c008e7a9b530dcc69d28d4e85ff6d7222794d58 100644 --- a/drivers/lcd/ssd1306.h +++ b/drivers/lcd/ssd1306.h @@ -234,7 +234,7 @@ struct ssd1306_dev_s #ifdef CONFIG_LCD_SSD1306_SPI FAR struct spi_dev_s *spi; /* Cached SPI device reference */ #else - FAR struct i2c_dev_s *i2c; /* Cached SPI device reference */ + FAR struct i2c_master_s *i2c; /* Cached SPI device reference */ uint8_t addr; /* 7-bit I2C address */ #endif uint8_t contrast; /* Current contrast setting */ @@ -258,10 +258,7 @@ void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) #ifdef CONFIG_LCD_SSD1306_SPI void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs); void ssd1306_cmddata(FAR struct ssd1306_dev_s *priv, bool cmd); - -#ifndef CONFIG_SPI_OWNBUS static inline void ssd1306_configspi(FAR struct spi_dev_s *spi) -#endif #else # define ssd1306_select(priv, cs) diff --git a/drivers/lcd/ssd1306_base.c b/drivers/lcd/ssd1306_base.c index 5186850d89d2be55860087bcd582a3f2f140a22d..db94d9ea834500a406181f92314809574a8b45ce 100644 --- a/drivers/lcd/ssd1306_base.c +++ b/drivers/lcd/ssd1306_base.c @@ -129,7 +129,7 @@ #include #include -#include +#include #include #include #include @@ -208,10 +208,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = ssd1306_putrun, /* Put a run into LCD memory */ - .getrun = ssd1306_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = SSD1306_DEV_BPP, /* Bits-per-pixel */ + .putrun = ssd1306_putrun, /* Put a run into LCD memory */ + .getrun = ssd1306_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = SSD1306_DEV_BPP, /* Bits-per-pixel */ }; /* This is the OLED driver instance (only a single device is supported for now) */ @@ -807,7 +807,7 @@ static int ssd1306_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) #ifdef CONFIG_LCD_SSD1306_SPI FAR struct lcd_dev_s *ssd1306_initialize(FAR struct spi_dev_s *dev, unsigned int devno) #else -FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_dev_s *dev, unsigned int devno) +FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_master_s *dev, unsigned int devno) #endif { FAR struct ssd1306_dev_s *priv = &g_oleddev; @@ -818,36 +818,15 @@ FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_dev_s *dev, unsigned int #ifdef CONFIG_LCD_SSD1306_SPI priv->spi = dev; - /* If this SPI bus is not shared, then we can config it now. - * If it is shared, then other device could change our config, - * then just configure before sending data. - */ - -# ifdef CONFIG_SPI_OWNBUS - /* Configure SPI */ - - SPI_SETMODE(priv->spi, CONFIG_SSD1306_SPIMODE); - SPI_SETBITS(priv->spi, 8); - SPI_SETFREQUENCY(priv->spi, CONFIG_SSD1306_FREQUENCY); -# else - /* Configure the SPI */ + /* Configure the SPI */ - ssd1306_configspi(priv->spi); -# endif + ssd1306_configspi(priv->spi); #else /* Remember the I2C configuration */ priv->i2c = dev; priv->addr = CONFIG_SSD1306_I2CADDR; - - /* Set the I2C address and frequency. REVISIT: This logic would be - * insufficient if we share the I2C bus with any other devices that also - * modify the address and frequency. - */ - - I2C_SETADDRESS(priv->i2c, CONFIG_SSD1306_I2CADDR, 7); - I2C_SETFREQUENCY(priv->i2c, CONFIG_SSD1306_I2CFREQ); #endif /* Lock and select device */ @@ -864,40 +843,40 @@ FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_dev_s *dev, unsigned int /* Configure the device */ - ssd1306_sendbyte(priv, SSD1306_DISPOFF); /* Display off 0xae */ - ssd1306_sendbyte(priv, SSD1306_SETCOLL(0)); /* Set lower column address 0x00 */ - ssd1306_sendbyte(priv, SSD1306_SETCOLH(0)); /* Set higher column address 0x10 */ - ssd1306_sendbyte(priv, SSD1306_STARTLINE(0)); /* Set display start line 0x40 */ - /* ssd1306_sendbyte(priv, SSD1306_PAGEADDR(0));*//* Set page address (Can ignore)*/ - ssd1306_sendbyte(priv, SSD1306_CONTRAST_MODE); /* Contrast control 0x81 */ - ssd1306_sendbyte(priv,SSD1306_CONTRAST(SSD1306_DEV_CONTRAST)); /* Default contrast 0xCF */ - ssd1306_sendbyte(priv, SSD1306_REMAPPLEFT); /* Set segment remap left 95 to 0 | 0xa1 */ - /* ssd1306_sendbyte(priv, SSD1306_EDISPOFF); */ /* Normal display off 0xa4 (Can ignore)*/ - ssd1306_sendbyte(priv, SSD1306_NORMAL); /* Normal (un-reversed) display mode 0xa6 */ - ssd1306_sendbyte(priv, SSD1306_MRATIO_MODE); /* Multiplex ratio 0xa8 */ + ssd1306_sendbyte(priv, SSD1306_DISPOFF); /* Display off 0xae */ + ssd1306_sendbyte(priv, SSD1306_SETCOLL(0)); /* Set lower column address 0x00 */ + ssd1306_sendbyte(priv, SSD1306_SETCOLH(0)); /* Set higher column address 0x10 */ + ssd1306_sendbyte(priv, SSD1306_STARTLINE(0)); /* Set display start line 0x40 */ + //ssd1306_sendbyte(priv, SSD1306_PAGEADDR(0)); /* Set page address (Can ignore) */ + ssd1306_sendbyte(priv, SSD1306_CONTRAST_MODE); /* Contrast control 0x81 */ + ssd1306_sendbyte(priv, SSD1306_CONTRAST(SSD1306_DEV_CONTRAST)); /* Default contrast 0xCF */ + ssd1306_sendbyte(priv, SSD1306_REMAPPLEFT); /* Set segment remap left 95 to 0 | 0xa1 */ + //ssd1306_sendbyte(priv, SSD1306_EDISPOFF); /* Normal display off 0xa4 (Can ignore) */ + ssd1306_sendbyte(priv, SSD1306_NORMAL); /* Normal (un-reversed) display mode 0xa6 */ + ssd1306_sendbyte(priv, SSD1306_MRATIO_MODE); /* Multiplex ratio 0xa8 */ ssd1306_sendbyte(priv, SSD1306_MRATIO(SSD1306_DEV_DUTY)); /* Duty = 1/64 or 1/32 */ - /* ssd1306_sendbyte(priv, SSD1306_SCANTOCOM0);*/ /* Com scan direction: Scan from COM[n-1] to COM[0] (Can ignore)*/ - ssd1306_sendbyte(priv, SSD1306_DISPOFFS_MODE); /* Set display offset 0xd3 */ + //ssd1306_sendbyte(priv, SSD1306_SCANTOCOM0); /* Com scan direction: Scan from COM[n-1] to COM[0] (Can ignore) */ + ssd1306_sendbyte(priv, SSD1306_DISPOFFS_MODE); /* Set display offset 0xd3 */ ssd1306_sendbyte(priv, SSD1306_DISPOFFS(0)); - ssd1306_sendbyte(priv, SSD1306_CLKDIV_SET); /* Set clock divider 0xd5*/ - ssd1306_sendbyte(priv, SSD1306_CLKDIV(8,0)); /* 0x80*/ + ssd1306_sendbyte(priv, SSD1306_CLKDIV_SET); /* Set clock divider 0xd5 */ + ssd1306_sendbyte(priv, SSD1306_CLKDIV(8, 0)); /* 0x80 */ - ssd1306_sendbyte(priv, SSD1306_CHRGPER_SET); /* Set pre-charge period 0xd9 */ - ssd1306_sendbyte(priv, SSD1306_CHRGPER(0x0f,1)); /* 0xf1 or 0x22 Enhanced mode */ + ssd1306_sendbyte(priv, SSD1306_CHRGPER_SET); /* Set pre-charge period 0xd9 */ + ssd1306_sendbyte(priv, SSD1306_CHRGPER(0x0f, 1)); /* 0xf1 or 0x22 Enhanced mode */ - ssd1306_sendbyte(priv, SSD1306_CMNPAD_CONFIG); /* Set common pads / set com pins hardware configuration 0xda */ + ssd1306_sendbyte(priv, SSD1306_CMNPAD_CONFIG); /* Set common pads / set com pins hardware configuration 0xda */ ssd1306_sendbyte(priv, SSD1306_CMNPAD(SSD1306_DEV_CMNPAD)); /* 0x12 or 0x02 */ - ssd1306_sendbyte(priv, SSD1306_VCOM_SET); /* set vcomh 0xdb*/ + ssd1306_sendbyte(priv, SSD1306_VCOM_SET); /* set vcomh 0xdb */ ssd1306_sendbyte(priv, SSD1306_VCOM(0x40)); - ssd1306_sendbyte(priv, SSD1306_CHRPUMP_SET); /* Set Charge Pump enable/disable 0x8d ssd1306 */ - ssd1306_sendbyte(priv, SSD1306_CHRPUMP_ON); /* 0x14 close 0x10 */ + ssd1306_sendbyte(priv, SSD1306_CHRPUMP_SET); /* Set Charge Pump enable/disable 0x8d ssd1306 */ + ssd1306_sendbyte(priv, SSD1306_CHRPUMP_ON); /* 0x14 close 0x10 */ - /* ssd1306_sendbyte(priv, SSD1306_DCDC_MODE); */ /* DC/DC control mode: on (SSD1306 Not supported) */ - /* ssd1306_sendbyte(priv, SSD1306_DCDC_ON); */ + //ssd1306_sendbyte(priv, SSD1306_DCDC_MODE); /* DC/DC control mode: on (SSD1306 Not supported) */ + //ssd1306_sendbyte(priv, SSD1306_DCDC_ON); - ssd1306_sendbyte(priv, SSD1306_DISPON); /* Display ON 0xaf */ + ssd1306_sendbyte(priv, SSD1306_DISPON); /* Display ON 0xaf */ /* De-select and unlock the device */ diff --git a/drivers/lcd/ssd1306_i2c.c b/drivers/lcd/ssd1306_i2c.c index 7164d890bef49cc22f5789f298efb436fca7b09d..1a5edaa6d1f2ef95ae46620116d5da95383c29b7 100644 --- a/drivers/lcd/ssd1306_i2c.c +++ b/drivers/lcd/ssd1306_i2c.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include "ssd1306.h" @@ -82,11 +82,12 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) /* Setup 8-bit SSD1306 address write message */ - msg.addr = priv->addr; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = txbuffer; /* Transfer from this address */ - msg.length = 1; /* Send one byte following the address - * (then STOP) */ + msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ + msg.addr = priv->addr; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = txbuffer; /* Transfer from this address */ + msg.length = 1; /* Send one byte following the address + * (then STOP) */ /* Perform the transfer */ @@ -117,11 +118,12 @@ void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) /* Setup 8-bit SSD1306 address write message */ - msg.addr = priv->addr; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = data; /* Transfer from this address */ - msg.length = len; /* Send one byte following the address - * (then STOP) */ + msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ + msg.addr = priv->addr; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = data; /* Transfer from this address */ + msg.length = len; /* Send one byte following the address + * (then STOP) */ /* Perform the transfer */ diff --git a/drivers/lcd/ssd1306_spi.c b/drivers/lcd/ssd1306_spi.c index 78fcdbb60145deabe33d9c1fa2d2c0ea3e17ff08..b17466c40ea1cdb4a54f1c05b232f22b5fabba4e 100644 --- a/drivers/lcd/ssd1306_spi.c +++ b/drivers/lcd/ssd1306_spi.c @@ -61,7 +61,6 @@ * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void ssd1306_configspi(FAR struct spi_dev_s *spi) { lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n", @@ -71,9 +70,9 @@ static inline void ssd1306_configspi(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_SSD1306_SPIMODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_SSD1306_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_SSD1306_FREQUENCY); } -#endif /**************************************************************************** * Public Functions @@ -123,7 +122,6 @@ void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs) { -#ifndef CONFIG_SPI_OWNBUS /* If we are selecting the device */ if (cs == true) @@ -133,13 +131,11 @@ void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs) (void)SPI_LOCK(priv->spi, true); ssd1306_configspi(priv->spi); } -#endif /* Select/deselect SPI device */ SPI_SELECT(priv->spi, SPIDEV_DISPLAY, cs); -#ifndef CONFIG_SPI_OWNBUS /* If we are deselecting the device */ if (cs == false) @@ -148,7 +144,6 @@ void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs) (void)SPI_LOCK(priv->spi, false); } -#endif } /**************************************************************************** diff --git a/drivers/lcd/ssd1351.c b/drivers/lcd/ssd1351.c new file mode 100644 index 0000000000000000000000000000000000000000..c56cc2b682347c0dde91ca7f70ca95da24c4825f --- /dev/null +++ b/drivers/lcd/ssd1351.c @@ -0,0 +1,1197 @@ +/**************************************************************************** + * drivers/lcd/ssd1351.c + * LCD driver for the Solomon Systech SSD1351 OLED controller + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_LCD_SSD1351 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* SSD1351 configuration settings: + * CONFIG_SSD1351_PARALLEL8BIT - 8-bit parallel interface + * CONFIG_SSD1351_SPI3WIRE - 3-wire SPI interface + * CONFIG_SSD1351_SPI4WIRE - 4-wire SPI interface + * CONFIG_SSD1351_SPIMODE - SPI mode + * CONFIG_SSD1351_SPIFREQ - SPI frequency + * CONFIG_SSD1351_NINTERFACES - number of physical devices supported + * CONFIG_SSD1351_XRES - X resolution + * CONFIG_SSD1351_YRES - Y resolution + * CONFIG_SSD1351_MIRRORX - mirror along the X axis + * CONFIG_SSD1351_MIRRORY - mirror along the Y axis + * CONFIG_SSD1351_INVERT - invert the display + * CONFIG_SSD1351_VDDEXT - external VDD + * CONFIG_SSD1351_TRST - reset period + * CONFIG_SSD1351_TPRECHG1 - first pre-charge period + * CONFIG_SSD1351_PERFENHANCE - enhace display performance + * CONFIG_SSD1351_CLKDIV - clock divider + * CONFIG_SSD1351_OSCFREQ - oscillator frequency + * CONFIG_SSD1351_TPRECHG2 - second pre-charge period + * CONFIG_SSD1351_VPRECHG - pre-charge voltage level + * CONFIG_SSD1351_VCOMH - COM deselect voltage level + * CONFIG_SSD1351_CONTRASTA - color A contrast + * CONFIG_SSD1351_CONTRASTB - color B contrast + * CONFIG_SSD1351_CONTRASTC - color C contrast + * CONFIG_SSD1351_MSTRCONTRAST - master contrast ratio + * + * Required LCD driver settings: + * CONFIG_LCD_SSD1351 - enables SSD1351 support + * CONFIG_LCD_MAXPOWER - maximum power, must be 1 + * + * Additional LCD driver settings: + * CONFIG_LCD_LANDSCAPE - landscape + * CONFIG_LCD_RLANDSCAPE - reverse landscape + * CONFIG_LCD_PORTRAIT - portrait + * CONFIG_LCD_RPORTRAIT - reverse portrait + * + * Required SPI driver settings: + * CONFIG_SPI - enables support for SPI + * CONFIG_SPI_CMDDATA - enables support for cmd/data selection + * (if using 4-wire SPI) + * + * NX settings that must be undefined: + * CONFIG_NX_DISABLE_16BPP - disables 16 bpp support + */ + +/* Verify that all configuration requirements have been met */ + +/* Number of bits per pixel */ + +#ifdef CONFIG_NX_DISABLE_16BPP +# error "Requires support for 16 bits per pixel" +#endif + +/* Max power */ + +#if CONFIG_LCD_MAXPOWER != 1 +# error "CONFIG_LCD_MAXPOWER should be 1" +#endif + +/* 9-bit SPI */ + +#ifdef CONFIG_SSD1351_SPI3WIRE +# define SSD1351_SPICMD 0 +# define SSD1351_SPIDATA (1 << 8) +# define SSD1351_SPIBITS 9 +#else +# define SSD1351_SPIBITS 8 +#endif + +/* Macro Helpers ************************************************************/ + +#define SSD1351_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define SSD1351_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define SSD1351_CLAMP(n, a, b) SSD1351_MIN(SSD1351_MAX(n, a), b) + +/* Fundamental Commands *****************************************************/ + +/* Set column address. Two data bytes. + * Data 1: start address (0-127) + * Data 2: end address (0-127) + */ + +#define SSD1351_CMD_COLADDR 0x15 + +/* Set row address. Two data bytes. + * Data 1: start address (0-127) + * Data 2: end address (0-127) + */ + +#define SSD1351_CMD_ROWADDR 0x75 + +/* Write data bytes to RAM. */ + +#define SSD1351_CMD_RAMWRITE 0x5c + +/* Read data bytes from RAM. */ + +#define SSD1351_CMD_RAMREAD 0x5d + +/* Set address increment, column address mapping, color sequence, + * scan direction, COM split, and color depth. + * One data byte. + */ + +#define SSD1351_CMD_ORIENTATION 0xa0 +#define SSD1351_ADDRINCHORIZ 0x00 /* Horizontal address increment */ +#define SSD1351_ADDRINCVERT 0x01 /* Vertical address increment */ +#define SSD1351_REMAPCOL0 0x00 /* Column address 0 mapped to SEG0 */ +#define SSD1351_REMAPCOL127 0x02 /* Column address 127 mapped to SEG0 */ +#define SSD1351_COLORABC 0x00 /* Color sequence ABC */ +#define SSD1351_COLORCBA 0x04 /* Color sequence CBA */ +#define SSD1351_SCANFROMCOM0 0x00 /* Scan from COM0 */ +#define SSD1351_SCANTOCOM0 0x10 /* Scan to COM0 */ +#define SSD1351_SPLITDIS 0x00 /* Disable COM split odd even */ +#define SSD1351_SPLITEN 0x20 /* Enable COM split odd even */ +#define SSD1351_DEPTH65K 0x00 /* 65k color depth */ +#define SSD1351_DEPTH262K1 0x80 /* 262k color depth format 1 */ +#define SSD1351_DEPTH262K2 0xc0 /* 262k color depth format 2 */ + +/* Set vertical scroll by RAM (0-128). One data byte. */ + +#define SSD1351_CMD_STARTLINE 0xa1 +#define SSD1351_STARTLINE(n) SSD1351_CLAMP(n, 0, 128) + +/* Set vertical scroll by row (0-128). One data byte. */ + +#define SSD1351_CMD_OFFSET 0xa2 +#define SSD1351_OFFSET(n) SSD1351_CLAMP(n, 0, 128) + +/* Set all pixels off. No data bytes. */ + +#define SSD1351_CMD_ALLOFF 0xa4 + +/* Set all pixels on. No data bytes. */ + +#define SSD1351_CMD_ALLON 0xa5 + +/* Set normal display. No data bytes. */ + +#define SSD1351_CMD_NORMAL 0xa6 + +/* Set inverse display. No data bytes. */ + +#define SSD1351_CMD_INVERSE 0xa7 + +/* Set VDD and interface. One data byte. */ + +#define SSD1351_CMD_VDDIFACE 0xab +#define SSD1351_VDDEXT 0x00 /* external VDD */ +#define SSD1351_VDDINT 0x01 /* internal VDD */ +#define SSD1351_IFACE8BIT 0x00 /* 8-bit parallel */ +#define SSD1351_IFACE16BIT 0x40 /* 16-bit parallel */ +#define SSD1351_IFACE18BIT 0xc0 /* 18-bit parallel */ + +/* Set display off (sleep mode on). No data bytes. */ + +#define SSD1351_CMD_DISPOFF 0xae + +/* Set display on (sleep mode off). No data bytes. */ + +#define SSD1351_CMD_DISPON 0xaf + +/* Set reset period in DCLKs (5-31) and first pre-charge period + * in DCLKs (3-15). One data byte. + */ + +#define SSD1351_CMD_TRSTTPRECHG1 0xb1 +#define SSD1351_TRST(n) (SSD1351_CLAMP(n, 5, 31) / 2) +#define SSD1351_TPRECHG1(n) (SSD1351_CLAMP(n, 3, 15) << 4) + +/* Set display performance. Three data bytes. */ + +#define SSD1351_CMD_PERF 0xb2 +#define SSD1351_PERFNORMAL 0x00 /* Data 1: normal performance */ +#define SSD1351_PERFENHANCED 0xa4 /* Data 1: enhanced performance */ +#define SSD1351_PERFDATA2 0x00 +#define SSD1351_PERFDATA3 0x00 + +/* Set clock divider (0-10) and oscillator frequency (0-15). + * One data byte. + */ + +#define SSD1351_CMD_DIVFREQ 0xb3 +#define SSD1351_CLKDIV(r) (SSD1351_CLAMP(r, 0, 10) << 0) +#define SSD1351_OSCFREQ(r) (SSD1351_CLAMP(r, 0, 15) << 4) + +/* Set segment low voltage. Three data bytes. */ + +#define SSD1351_CMD_VSL 0xb4 +#define SSD1351_VSLEXT 0xa0 /* Data 1: external VSL */ +#define SSD1351_VSLDATA2 0xb5 +#define SSD1351_VSLDATA3 0x55 + +/* Set GPIO pins. One data byte. */ + +#define SSD1351_CMD_GPIO 0xb5 +#define SSD1351_GPIODIS 0x00 /* High impedance, disabled */ +#define SSD1351_GPIOEN 0x01 /* High impedance, enabled */ +#define SSD1351_GPIOLOW 0x02 /* Output low */ +#define SSD1351_GPIOHIGH 0x03 /* Output high */ +#define SSD1351_GPIO0(n) (((n) & 3) << 0) +#define SSD1351_GPIO1(n) (((n) & 3) << 2) + +/* Set second pre-charge period in DCLKs (1-15). One data byte. */ + +#define SSD1351_CMD_TPRECHG2 0xb6 +#define SSD1351_TPRECHG2(n) SSD1351_CLAMP(n, 1, 15) + +/* Set lookup table for grayscale pulse width. 63 data bytes. */ + +#define SSD1351_CMD_LUT 0xb8 + +/* Use built-in linear lookup table. No data bytes. */ + +#define SSD1351_CMD_LINEARLUT 0xb9 + +/* Set pre-charge voltage level as a percentage of VCC (20-60). + * One data byte. + */ + +#define SSD1351_CMD_VPRECHG 0xbb +#define SSD1351_VPRECHG(n) (100 * (SSD1351_CLAMP(n, 20, 60) - 20) / \ + (100 * (60 - 20) / 31)) + +/* Set COM deselect voltage level as a percentage of VCC (72-86). + * One data byte. + */ + +#define SSD1351_CMD_VCOMH 0xbe +#define SSD1351_VCOMH(n) ((SSD1351_CLAMP(n, 72, 86) - 72) / 2) + +/* Set contrast for colors A (0-255), B (0-255), and C (0-255). + * Three data bytes. + * Data 1: color A + * Data 2: color B + * Data 3: color C + */ + +#define SSD1351_CMD_CONTRAST 0xc1 +#define SSD1351_CONTRAST(n) SSD1351_CLAMP(n, 0, 255) + +/* Set master contrast ratio in sixteenths (1-16). One data byte. */ + +#define SSD1351_CMD_MSTRCONTRAST 0xc7 +#define SSD1351_MSTRCONTRAST(n) (SSD1351_CLAMP(n, 1, 16) - 1) + +/* Set multiplex ratio (16-128). One data byte. */ + +#define SSD1351_CMD_MUXRATIO 0xca +#define SSD1351_MUXRATIO(n) (SSD1351_CLAMP(n, 16, 128) - 1) + +/* Set command lock. One data byte. */ + +#define SSD1351_CMD_LOCK 0xfd +#define SSD1351_UNLOCK 0x12 /* Unlock commands */ +#define SSD1351_LOCK 0x16 /* Lock commands */ +#define SSD1351_INACCESSIBLE 0xb0 /* Make some commands inaccessible */ +#define SSD1351_ACCESSIBLE 0xb1 /* Make some commands accessible */ + +/* Graphic Acceleration Commands ********************************************/ + +/* Set horizontal scroll. Five data bytes. + * Data 1: 0x00: no scrolling + * 0x01-0x3f: scroll towards SEG127 with 1 column offset + * 0x40-0xff: scroll towards SEG0 with 1 column offset + * Data 2: start row address + * Data 3: number of rows to scroll + */ + +#define SSD1351_CMD_HSCROLL 0x96 +#define SSD1351_HSCROLLDATA4 0x00 /* Data 4 */ +#define SSD1351_HSCROLLTEST 0x00 /* Data 5: test mode */ +#define SSD1351_HSCROLLNORMAL 0x01 /* Data 5: normal */ +#define SSD1351_HSCROLLSLOW 0x02 /* Data 5: slow */ +#define SSD1351_HSCROLLSLOWEST 0x03 /* Data 5: slowest */ + +/* Start horizontal scroll. No data bytes. */ + +#define SSD1351_CMD_STARTHSCROLL 0x9e + +/* Stop horizontal scroll. No data bytes. */ + +#define SSD1351_CMD_STOPHSCROLL 0x9f + +/* Color Properties *********************************************************/ + +/* Display resolution */ + +#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) +#define SSD1351_XRES CONFIG_SSD1351_XRES +#define SSD1351_YRES CONFIG_SSD1351_YRES +#else +#define SSD1351_XRES CONFIG_SSD1351_YRES +#define SSD1351_YRES CONFIG_SSD1351_XRES +#endif + +/* Color depth and format */ + +#define SSD1351_BPP 16 +#define SSD1351_COLORFMT FB_FMT_RGB16_565 +#define SSD1351_STRIDE (2 * SSD1351_XRES) +#define SSD1351_PIX2BYTES(p) (2 * (p)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of this driver */ + +struct ssd1351_dev_s +{ + /* Publically visible device structure */ + + struct lcd_dev_s dev; + + /* Private LCD-specific information follows */ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT + FAR struct ssd1351_lcd_s *lcd; /* Contained platform-specific interface */ +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) + FAR struct spi_dev_s *spi; /* Contained SPI driver instance */ +#endif + uint8_t power; /* Current power (backlight) setting */ + + /* This is working memory allocated by the LCD driver for each LCD device + * and for each color plane. This memory will hold one raster line of + * data. The size of the allocated run buffer must therefore be at least + * (bpp * xres / 8). Actual alignment of the buffer must conform to the + * bitwidth of the underlying pixel type. + * + * If there are multiple planes, they may share the same working buffer + * because different planes will not be operate on concurrently. However, + * if there are multiple LCD devices, they must each have unique run + * buffers. + */ + + uint16_t runbuffer[SSD1351_XRES]; + + /* This is another buffer, but used internally by the LCD driver in order + * to expand the pixel data into 9-bit data needed by the LCD. There are + * some customizations that would eliminate the need for this extra buffer + * and for the extra expansion/copy, but those customizations would require + * a special, non-standard SPI driver that could expand 8- to 9-bit data on + * the fly. + */ + +#ifdef CONFIG_SSD1351_SPI3WIRE + uint16_t rowbuffer[SSD1351_STRIDE+1]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT +#define ssd1351_select(priv) +#define ssd1351_deselect(priv) +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +static void ssd1351_select(FAR struct ssd1351_dev_s *priv); +static void ssd1351_deselect(FAR struct ssd1351_dev_s *priv); +#endif + +#if defined(CONFIG_SSD1351_PARALLEL8BIT) && !defined(CONFIG_LCD_NOGETRUN) +static void ssd1351_read(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR uint8_t *data, size_t datlen); +#endif +static void ssd1351_write(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR const uint8_t *data, size_t datlen); + +/* LCD Data Transfer Methods */ + +static int ssd1351_putrun(fb_coord_t row, fb_coord_t col, + FAR const uint8_t *buffer, size_t npixels); +static int ssd1351_getrun(fb_coord_t row, fb_coord_t col, + FAR uint8_t *buffer, size_t npixels); + +/* LCD Configuration */ + +static int ssd1351_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo); +static int ssd1351_getplaneinfo(FAR struct lcd_dev_s *dev, + unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo); + +/* LCD RGB Mapping */ + +#ifdef CONFIG_FB_CMAP +# error "RGB color mapping not supported by this driver" +#endif + +/* Cursor Controls */ + +#ifdef CONFIG_FB_HWCURSOR +# error "Cursor control not supported by this driver" +#endif + +/* LCD Specific Controls */ + +static int ssd1351_getpower(struct lcd_dev_s *dev); +static int ssd1351_setpower(struct lcd_dev_s *dev, int power); +static int ssd1351_getcontrast(struct lcd_dev_s *dev); +static int ssd1351_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); + +/* Initialization */ + +static inline void ssd1351_hwinitialize(FAR struct ssd1351_dev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the standard, NuttX LCD driver object */ + +static struct ssd1351_dev_s g_lcddev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ssd1351_select + * + * Description: + * Select the SPI, locking and re-configuring if necessary. + * + ****************************************************************************/ + +#if defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +static void ssd1351_select(FAR struct ssd1351_dev_s *priv) +{ + FAR struct spi_dev_s *spi = priv->spi; + + /* Select the chip, locking the SPI bus in case there are multiple devices + * competing for the SPI bus + */ + + gdbg("SELECTED\n"); + SPI_LOCK(spi, true); + SPI_SELECT(spi, SPIDEV_DISPLAY, true); + + /* Now make sure that the SPI bus is configured for this device (it might + * have gotten configured for a different device while unlocked) + */ + + SPI_SETMODE(spi, CONFIG_SSD1351_SPIMODE); + SPI_SETBITS(spi, SSD1351_SPIBITS); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_SSD1351_SPIFREQ); +} +#endif + +/**************************************************************************** + * Name: ssd1351_deselect + * + * Description: + * De-select the SPI. + * + ****************************************************************************/ + +#if defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +static void ssd1351_deselect(FAR struct ssd1351_dev_s *priv) +{ + FAR struct spi_dev_s *spi = priv->spi; + + /* De-select the chip and relinquish the SPI bus */ + + gdbg("DE-SELECTED\n"); + SPI_SELECT(spi, SPIDEV_DISPLAY, false); + SPI_LOCK(spi, false); +} +#endif + +/**************************************************************************** + * Name: ssd1351_read + * + * Description: + * Send a 1-byte command and read datlen data bytes. + * + ****************************************************************************/ + +#if defined(CONFIG_SSD1351_PARALLEL8BIT) && !defined(CONFIG_LCD_NOGETRUN) +static void ssd1351_read(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR uint8_t *data, size_t datlen) +{ + FAR struct ssd1351_lcd_s *lcd = priv->lcd; + size_t i; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + DEBUGASSERT((data == NULL && datlen == 0) || (data != NULL && datlen > 0)); + + /* Send the command */ + + lcd->cmd(lcd, cmd); + + /* Discard the first data read if reading from the display */ + + if (cmd == SSD1351_CMD_RAMREAD) + { + (void)lcd->read(lcd); + } + + /* Read all of the data */ + + for (i = 0; i < datlen; i++) + { + data[i] = lcd->read(lcd); + } +} +#endif + +/**************************************************************************** + * Name: ssd1351_write + * + * Description: + * Send a 1-byte command followed by datlen data bytes. + * + ****************************************************************************/ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT +static void ssd1351_write(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR const uint8_t *data, size_t datlen) +{ + FAR struct ssd1351_lcd_s *lcd = priv->lcd; + size_t i; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + DEBUGASSERT((data == NULL && datlen == 0) || (data != NULL && datlen > 0)); + + /* Send the command */ + + lcd->cmd(lcd, cmd); + + /* Write all of the data */ + + for (i = 0; i < datlen; i++) + { + lcd->write(lcd, data[i]); + } +} +#elif defined(CONFIG_SSD1351_SPI3WIRE) +static void ssd1351_write(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR const uint8_t *data, size_t datlen) +{ + size_t i; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + DEBUGASSERT((data == NULL && datlen == 0) || (data != NULL && datlen > 0)); + DEBUGASSERT(datlen <= SSD1351_STRIDE); + + /* Copy the command into the line buffer */ + + priv->rowbuffer[0] = (uint16_t)cmd | SSD1351_SPICMD; + + /* Copy any data after the command into the line buffer */ + + for (i = 0; i < datlen; i++) + { + priv->rowbuffer[i+1] = (uint16_t)data[i] | SSD1351_SPIDATA; + } + + /* Send the line buffer */ + + (void)SPI_SNDBLOCK(priv->spi, priv->rowbuffer, datlen+1); +} +#elif defined(CONFIG_SSD1351_SPI4WIRE) +static void ssd1351_write(FAR struct ssd1351_dev_s *priv, uint8_t cmd, + FAR const uint8_t *data, size_t datlen) +{ + FAR struct spi_dev_s *spi = priv->spi; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + DEBUGASSERT((data == NULL && datlen == 0) || (data != NULL && datlen > 0)); + + /* Select command transfer */ + + (void)SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); + + /* Send the command */ + + (void)SPI_SEND(spi, cmd); + + /* Do we have any data to send? */ + + if (datlen > 0) + { + /* Yes, select data transfer */ + + (void)SPI_CMDDATA(spi, SPIDEV_DISPLAY, false); + + /* Transfer all of the data */ + + (void)SPI_SNDBLOCK(spi, data, datlen); + } +} +#endif + +/**************************************************************************** + * Name: ssd1351_setcursor + * + * Description: + * Set the cursor position. + * + ****************************************************************************/ + +static void ssd1351_setcursor(FAR struct ssd1351_dev_s *priv, uint8_t col, + uint8_t row) +{ + uint8_t buf[2]; + +#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) + /* Set the column address to the column */ + + buf[0] = col; + buf[1] = SSD1351_XRES - 1; + ssd1351_write(priv, SSD1351_CMD_COLADDR, buf, 2); + + /* Set the row address to the row */ + + buf[0] = row; + buf[1] = SSD1351_YRES - 1; + ssd1351_write(priv, SSD1351_CMD_ROWADDR, buf, 2); +#elif defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) + /* Set the column address to the row */ + + buf[0] = row; + buf[1] = SSD1351_YRES - 1; + ssd1351_write(priv, SSD1351_CMD_COLADDR, buf, 2); + + /* Set the row address to the column */ + + buf[0] = col; + buf[1] = SSD1351_XRES - 1; + ssd1351_write(priv, SSD1351_CMD_ROWADDR, buf, 2); +#endif +} + +/**************************************************************************** + * Name: ssd1351_putrun + * + * Description: + * This method can be used to write a partial raster line to the LCD: + * + * Input Parameters: + * row - Starting row to write to (range: 0 <= row < yres) + * col - Starting column to write to (range: 0 <= col <= xres-npixels + * buffer - The buffer containing the run to be written to the LCD + * npixels - The number of pixels to write to the LCD + * (range: 0 < npixels <= xres-col) + * + ****************************************************************************/ + +static int ssd1351_putrun(fb_coord_t row, fb_coord_t col, + FAR const uint8_t *buffer, size_t npixels) +{ + FAR struct ssd1351_dev_s *priv = &g_lcddev; + + /* Sanity check */ + + DEBUGASSERT(buffer != NULL && ((uintptr_t)buffer & 1) == 0 && + col >= 0 && col+npixels <= SSD1351_XRES && + row >= 0 && row < SSD1351_YRES); + + /* Select and lock the device */ + + ssd1351_select(priv); + + /* Set the starting position for the run */ + + ssd1351_setcursor(priv, col, row); + + /* Write all of the data */ + + ssd1351_write(priv, SSD1351_CMD_RAMWRITE, buffer, + SSD1351_PIX2BYTES(npixels)); + + /* Unlock and de-select the device */ + + ssd1351_deselect(priv); + + return OK; +} + +/**************************************************************************** + * Name: ssd1351_getrun + * + * Description: + * This method can be used to read a partial raster line from the LCD. + * + * Input Parameters: + * row - Starting row to read from (range: 0 <= row < yres) + * col - Starting column to read from (range: 0 <= col <= xres-npixels) + * buffer - The buffer in which to return the run read from the LCD + * npixels - The number of pixels to read from the LCD + * (range: 0 < npixels <= xres-col) + * + ****************************************************************************/ + +static int ssd1351_getrun(fb_coord_t row, fb_coord_t col, + FAR uint8_t *buffer, size_t npixels) +{ +#if defined(CONFIG_SSD1351_PARALLEL8BIT) && !defined(CONFIG_LCD_NOGETRUN) + FAR struct ssd1351_dev_s *priv = &g_lcddev; + + /* Sanity check */ + + DEBUGASSERT(buffer != NULL && ((uintptr_t)buffer & 1) == 0 && + col >= 0 && col+npixels <= SSD1351_XRES && + row >= 0 && row < SSD1351_YRES); + + /* Select and lock the device */ + + ssd1351_select(priv); + + /* Set the starting position for the run */ + + ssd1351_setcursor(priv, col, row); + + /* Read all of the data */ + + ssd1351_read(priv, SSD1351_CMD_RAMREAD, buffer, + SSD1351_PIX2BYTES(npixels)); + + /* Unlock and de-select the device */ + + ssd1351_deselect(priv); + + return OK; +#else + return -ENOSYS; +#endif +} + +/**************************************************************************** + * Name: ssd1351_getvideoinfo + * + * Description: + * Get information about the LCD video controller configuration. + * + ****************************************************************************/ + +static int ssd1351_getvideoinfo(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo) +{ + DEBUGASSERT(dev != NULL && vinfo != NULL); + + vinfo->fmt = SSD1351_COLORFMT; + vinfo->xres = SSD1351_XRES; + vinfo->yres = SSD1351_YRES; + vinfo->nplanes = 1; + + gvdbg("fmt: %u xres: %u yres: %u nplanes: %u\n", + vinfo->fmt, vinfo->xres, vinfo->yres, vinfo->nplanes); + return OK; +} + +/**************************************************************************** + * Name: ssd1351_getplaneinfo + * + * Description: + * Get information about the configuration of each LCD color plane. + * + ****************************************************************************/ + +static int ssd1351_getplaneinfo(FAR struct lcd_dev_s *dev, + unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo) +{ + FAR struct ssd1351_dev_s *priv = (FAR struct ssd1351_dev_s *)dev; + + DEBUGASSERT(dev != NULL && pinfo != NULL && planeno == 0); + + pinfo->putrun = ssd1351_putrun; + pinfo->getrun = ssd1351_getrun; + pinfo->buffer = (uint8_t *)priv->runbuffer; + pinfo->bpp = SSD1351_BPP; + + gvdbg("planeno: %u bpp: %u\n", planeno, pinfo->bpp); + return OK; +} + +/**************************************************************************** + * Name: ssd1351_getpower + * + * Description: + * Get the LCD panel power status + * (0: full off - CONFIG_LCD_MAXPOWER: full on). + * On backlit LCDs, this setting may correspond to the backlight setting. + * + ****************************************************************************/ + +static int ssd1351_getpower(FAR struct lcd_dev_s *dev) +{ + FAR struct ssd1351_dev_s *priv = (FAR struct ssd1351_dev_s *)dev; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + gvdbg("power: %d\n", priv->power); + + return priv->power; +} + +/**************************************************************************** + * Name: ssd1351_setpower + * + * Description: + * Enable/disable LCD panel power + * (0: full off - CONFIG_LCD_MAXPOWER: full on). + * On backlit LCDs, this setting may correspond to the backlight setting. + * + ****************************************************************************/ + +static int ssd1351_setpower(FAR struct lcd_dev_s *dev, int power) +{ + FAR struct ssd1351_dev_s *priv = (FAR struct ssd1351_dev_s *)dev; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL && (unsigned int)power <= LCD_FULL_ON); + gvdbg("power: %d\n", power); + + /* Select and lock the device */ + + ssd1351_select(priv); + + if (power > LCD_FULL_OFF) + { + /* Turn the display on */ + + ssd1351_write(priv, SSD1351_CMD_DISPON, NULL, 0); + priv->power = LCD_FULL_ON; + } + else + { + /* Turn the display off */ + + ssd1351_write(priv, SSD1351_CMD_DISPOFF, NULL, 0); + priv->power = LCD_FULL_OFF; + } + + /* Unlock and de-select the device */ + + ssd1351_deselect(priv); + + return OK; +} + +/**************************************************************************** + * Name: ssd1351_getcontrast + * + * Description: + * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). + * + ****************************************************************************/ + +static int ssd1351_getcontrast(FAR struct lcd_dev_s *dev) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ssd1351_setcontrast + * + * Description: + * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). + * + ****************************************************************************/ + +static int ssd1351_setcontrast(FAR struct lcd_dev_s *dev, + unsigned int contrast) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ssd1351_hwinitialize + * + * Description: + * Initialize the video hardware. + * + ****************************************************************************/ + +static inline void ssd1351_hwinitialize(FAR struct ssd1351_dev_s *priv) +{ + size_t i; + uint8_t buf[3]; + + /* Select and lock the device */ + + ssd1351_select(priv); + + /* Unlock most commands */ + + buf[0] = SSD1351_UNLOCK; + ssd1351_write(priv, SSD1351_CMD_LOCK, buf, 1); + + /* Unlock the rest of the commands */ + + buf[0] = SSD1351_ACCESSIBLE; + ssd1351_write(priv, SSD1351_CMD_LOCK, buf, 1); + + /* Turn the display off */ + + ssd1351_write(priv, SSD1351_CMD_DISPOFF, NULL, 0); + + /* Set the address increment, the column address mapping, the color + * sequence, the scan direction, the COM split, and the color depth + */ + + buf[0] = SSD1351_COLORABC | SSD1351_SPLITEN | SSD1351_DEPTH65K; +#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) + buf[0] |= SSD1351_ADDRINCHORIZ; +#else + buf[0] |= SSD1351_ADDRINCVERT; +#endif +#if (defined(CONFIG_LCD_LANDSCAPE) && !defined(CONFIG_SSD1351_MIRRORX)) || \ + (defined(CONFIG_LCD_RLANDSCAPE) && defined(CONFIG_SSD1351_MIRRORX)) || \ + (defined(CONFIG_LCD_PORTRAIT) && !defined(CONFIG_SSD1351_MIRRORY)) || \ + (defined(CONFIG_LCD_RPORTRAIT) && defined(CONFIG_SSD1351_MIRRORY)) + buf[0] |= SSD1351_REMAPCOL0; +#else + buf[0] |= SSD1351_REMAPCOL127; +#endif +#if (defined(CONFIG_LCD_LANDSCAPE) && !defined(CONFIG_SSD1351_MIRRORY)) || \ + (defined(CONFIG_LCD_RLANDSCAPE) && defined(CONFIG_SSD1351_MIRRORY)) || \ + (defined(CONFIG_LCD_PORTRAIT) && defined(CONFIG_SSD1351_MIRRORX)) || \ + (defined(CONFIG_LCD_RPORTRAIT) && !defined(CONFIG_SSD1351_MIRRORX)) + buf[0] |= SSD1351_SCANTOCOM0; +#else + buf[0] |= SSD1351_SCANFROMCOM0; +#endif + ssd1351_write(priv, SSD1351_CMD_ORIENTATION, buf, 1); + + /* Set the vertical scroll by RAM */ + +#if (defined(CONFIG_LCD_LANDSCAPE) && !defined(CONFIG_SSD1351_MIRRORY)) || \ + (defined(CONFIG_LCD_RLANDSCAPE) && defined(CONFIG_SSD1351_MIRRORY)) || \ + (defined(CONFIG_LCD_PORTRAIT) && defined(CONFIG_SSD1351_MIRRORX)) || \ + (defined(CONFIG_LCD_RPORTRAIT) && !defined(CONFIG_SSD1351_MIRRORX)) + buf[0] = SSD1351_STARTLINE(CONFIG_SSD1351_YRES); +#else + buf[0] = SSD1351_STARTLINE(0); +#endif + ssd1351_write(priv, SSD1351_CMD_STARTLINE, buf, 1); + + /* Set the vertical scroll by row */ + + buf[0] = SSD1351_OFFSET(0); + ssd1351_write(priv, SSD1351_CMD_OFFSET, buf, 1); + + /* Set the display to normal or inverse */ + +#ifdef CONFIG_SSD1351_INVERT + ssd1351_write(priv, SSD1351_CMD_INVERSE, NULL, 0); +#else + ssd1351_write(priv, SSD1351_CMD_NORMAL, NULL, 0); +#endif + + /* Set the VDD and the interface */ + +#ifdef CONFIG_SSD1351_VDDEXT + buf[0] = SSD1351_VDDEXT; +#else + buf[0] = SSD1351_VDDINT; +#endif + buf[0] |= SSD1351_IFACE8BIT; + ssd1351_write(priv, SSD1351_CMD_VDDIFACE, buf, 1); + + /* Set the reset period and the first pre-charge period */ + + buf[0] = SSD1351_TRST(CONFIG_SSD1351_TRST) | + SSD1351_TPRECHG1(CONFIG_SSD1351_TPRECHG1); + ssd1351_write(priv, SSD1351_CMD_TRSTTPRECHG1, buf, 1); + + /* Set the display performance */ + +#ifdef CONFIG_SSD1351_PERFENHANCE + buf[0] = SSD1351_PERFENHANCE; +#else + buf[0] = SSD1351_PERFNORMAL; +#endif + buf[1] = SSD1351_PERFDATA2; + buf[2] = SSD1351_PERFDATA3; + ssd1351_write(priv, SSD1351_CMD_PERF, buf, 3); + + /* Set the clock divider and the oscillator frequency */ + + buf[0] = SSD1351_CLKDIV(CONFIG_SSD1351_CLKDIV) | + SSD1351_OSCFREQ(CONFIG_SSD1351_OSCFREQ); + ssd1351_write(priv, SSD1351_CMD_DIVFREQ, buf, 1); + + /* Set the segment low voltage */ + + buf[0] = SSD1351_VSLEXT; + buf[1] = SSD1351_VSLDATA2; + buf[2] = SSD1351_VSLDATA3; + ssd1351_write(priv, SSD1351_CMD_VSL, buf, 3); + + /* Set the GPIO pins */ + + buf[0] = SSD1351_GPIO0(SSD1351_GPIOLOW) | SSD1351_GPIO1(SSD1351_GPIOLOW); + ssd1351_write(priv, SSD1351_CMD_GPIO, buf, 1); + + /* Set the second pre-charge period */ + + buf[0] = SSD1351_TPRECHG2(CONFIG_SSD1351_TPRECHG2); + ssd1351_write(priv, SSD1351_CMD_TPRECHG2, buf, 1); + + /* Use the built-in linear lookup table */ + + ssd1351_write(priv, SSD1351_CMD_LINEARLUT, NULL, 0); + + /* Set the pre-charge voltage level */ + + buf[0] = SSD1351_VPRECHG(CONFIG_SSD1351_VPRECHG); + ssd1351_write(priv, SSD1351_CMD_VPRECHG, buf, 1); + + /* Set the COM deselect voltage level */ + + buf[0] = SSD1351_VCOMH(CONFIG_SSD1351_VCOMH); + ssd1351_write(priv, SSD1351_CMD_VCOMH, buf, 1); + + /* Set the contrast */ + + buf[0] = SSD1351_CONTRAST(CONFIG_SSD1351_CONTRASTA); + buf[1] = SSD1351_CONTRAST(CONFIG_SSD1351_CONTRASTB); + buf[2] = SSD1351_CONTRAST(CONFIG_SSD1351_CONTRASTC); + ssd1351_write(priv, SSD1351_CMD_CONTRAST, buf, 3); + + /* Set the master contrast ratio */ + + buf[0] = SSD1351_MSTRCONTRAST(CONFIG_SSD1351_MSTRCONTRAST); + ssd1351_write(priv, SSD1351_CMD_MSTRCONTRAST, buf, 1); + + /* Set the multiplex ratio */ + + buf[0] = SSD1351_MUXRATIO(128); + ssd1351_write(priv, SSD1351_CMD_MUXRATIO, buf, 1); + + /* Lock some of the commands */ + + buf[0] = SSD1351_INACCESSIBLE; + ssd1351_write(priv, SSD1351_CMD_LOCK, buf, 1); + + /* Set the cursor position */ + + ssd1351_setcursor(priv, 0, 0); + + /* Clear the display memory */ + + buf[0] = 0; + buf[1] = 0; + for (i = 0; i < SSD1351_XRES * SSD1351_YRES; i++) + { + ssd1351_write(priv, SSD1351_CMD_RAMWRITE, buf, 2); + } + + /* Unlock and de-select the device */ + + ssd1351_deselect(priv); +} + +/**************************************************************************** + * Name: ssd1351_initialize + * + * Description: + * Initialize the video hardware. The initial state of the device + * is fully initialized, display memory cleared, and ready to use, + * but with the power setting at 0 (full off == sleep mode). + * + * Input Parameters: + * lcd - A reference to the platform-specific interface. + * spi - A reference to the SPI driver instance. + * devno - A value in the range of 0 through CONFIG_SSD1351_NINTERFACES-1. + * This allows support for multiple devices. + * + * Returned Value: + * On success, this function returns a reference to the LCD object for the + * specified device. NULL is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT +FAR struct lcd_dev_s *ssd1351_initialize(FAR struct ssd1351_lcd_s *lcd, + unsigned int devno) +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +FAR struct lcd_dev_s *ssd1351_initialize(FAR struct spi_dev_s *spi, + unsigned int devno) +#endif +{ + FAR struct ssd1351_dev_s *priv = &g_lcddev; + + /* Sanity check */ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT + DEBUGASSERT(lcd != NULL); +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) + DEBUGASSERT(spi != NULL); +#endif + DEBUGASSERT(devno == 0); + + /* Initialize the driver data structure */ + + priv->dev.getvideoinfo = ssd1351_getvideoinfo; + priv->dev.getplaneinfo = ssd1351_getplaneinfo; + priv->dev.getpower = ssd1351_getpower; + priv->dev.setpower = ssd1351_setpower; + priv->dev.getcontrast = ssd1351_getcontrast; + priv->dev.setcontrast = ssd1351_setcontrast; +#ifdef CONFIG_SSD1351_PARALLEL8BIT + priv->lcd = lcd; +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) + priv->spi = spi; +#endif + priv->power = LCD_FULL_OFF; + + /* Configure the device */ + + ssd1351_hwinitialize(priv); + + return &priv->dev; +} + +#endif /* CONFIG_LCD_SSD1351 */ diff --git a/drivers/lcd/st7565.c b/drivers/lcd/st7565.c index 592c39d3aedfc3c1de91eeda960bae72961d049f..6b4a1c02883641e3f8f1a2638bea4f50b1439d48 100644 --- a/drivers/lcd/st7565.c +++ b/drivers/lcd/st7565.c @@ -990,14 +990,16 @@ FAR struct lcd_dev_s *st7565_initialize(FAR struct st7565_lcd_s *lcd, st7565_reset(priv, true); /* it seems too long but written in NHD‐C12864KGZ DISPLAY - * INITIALIZATION... */ + * INITIALIZATION... + */ up_mdelay(150); st7565_reset(priv, false); /* it seems too long but written in NHD‐C12864KGZ DISPLAY - * INITIALIZATION... */ + * INITIALIZATION... + */ up_mdelay(150); @@ -1009,7 +1011,7 @@ FAR struct lcd_dev_s *st7565_initialize(FAR struct st7565_lcd_s *lcd, st7565_cmddata(priv, true); - /* reset by command in case of st7565_reset not implemeted */ + /* Reset by command in case of st7565_reset not implemeted */ (void)st7565_send_one_data(priv, ST7565_EXIT_SOFTRST); @@ -1025,6 +1027,17 @@ FAR struct lcd_dev_s *st7565_initialize(FAR struct st7565_lcd_s *lcd, (void)st7565_send_one_data(priv, ST7565_POWERCTRL_INT); (void)st7565_send_one_data(priv, ST7565_SETSTARTLINE); +#elif CONFIG_ERC_12864_3 + + (void)st7565_send_one_data(priv, ST7565_ADCNORMAL); + (void)st7565_send_one_data(priv, ST7565_SETCOMREVERSE); + (void)st7565_send_one_data(priv, ST7565_BIAS_1_9); + (void)st7565_send_one_data(priv, ST7565_POWERCTRL_INT); + (void)st7565_send_one_data(priv, ST7565_REG_RES_5_5); + (void)st7565_send_one_data(priv, ST7565_SETEVMODE); + (void)st7565_send_one_data(priv, ST7565_SETEVREG(0x24)); + (void)st7565_send_one_data(priv, ST7565_SETSTARTLINE); + #else # error "No initialization sequence selected" #endif diff --git a/drivers/lcd/st7567.c b/drivers/lcd/st7567.c index f138e14794d9c286171c8e26dc2e4d995ef02f58..77ba1bbc1ddad5fd1970d8c2ff44593b9e296213 100644 --- a/drivers/lcd/st7567.c +++ b/drivers/lcd/st7567.c @@ -232,10 +232,10 @@ struct st7567_dev_s uint8_t contrast; uint8_t powered; - /* The ST7567 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. - */ + /* The ST7567 does not support reading from the display memory in SPI mode. + * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep + * a shadow copy of the framebuffer memory. + */ uint8_t fb[ST7567_FBSIZE]; }; @@ -246,13 +246,8 @@ struct st7567_dev_s /* SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void st7567_select(FAR struct spi_dev_s *spi); -static inline void st7567_deselect(FAR struct spi_dev_s *spi); -#else static void st7567_select(FAR struct spi_dev_s *spi); static void st7567_deselect(FAR struct spi_dev_s *spi); -#endif /* LCD Data Transfer Methods */ @@ -315,17 +310,17 @@ static const struct fb_videoinfo_s g_videoinfo = .fmt = ST7567_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ .xres = ST7567_XRES, /* Horizontal resolution in pixel columns */ .yres = ST7567_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ + .nplanes = 1, /* Number of color planes supported */ }; /* This is the standard, NuttX Plane information object */ static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = st7567_putrun, /* Put a run into LCD memory */ - .getrun = st7567_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = ST7567_BPP, /* Bits-per-pixel */ + .putrun = st7567_putrun, /* Put a run into LCD memory */ + .getrun = st7567_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = ST7567_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -371,14 +366,6 @@ static struct st7567_dev_s g_st7567dev = * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void st7567_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else static void st7567_select(FAR struct spi_dev_s *spi) { /* Select ST7567 chip (locking the SPI bus in case there are multiple @@ -394,11 +381,11 @@ static void st7567_select(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_ST7567_SPIMODE); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); #ifdef CONFIG_ST7567_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_ST7567_FREQUENCY); + (void)SPI_SETFREQUENCY(spi, CONFIG_ST7567_FREQUENCY); #endif } -#endif /************************************************************************************** * Function: st7567_deselect @@ -416,14 +403,6 @@ static void st7567_select(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void st7567_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else static void st7567_deselect(FAR struct spi_dev_s *spi) { /* De-select ST7567 chip and relinquish the SPI bus. */ @@ -431,7 +410,6 @@ static void st7567_deselect(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); } -#endif /************************************************************************************** * Name: st7567_putrun diff --git a/drivers/lcd/ug-2864ambag01.c b/drivers/lcd/ug-2864ambag01.c index 51706026a9971d7a931685740c962b1651083d48..ab53fbc0247fb9bb12e0cb5522346728d81a0d30 100644 --- a/drivers/lcd/ug-2864ambag01.c +++ b/drivers/lcd/ug-2864ambag01.c @@ -175,7 +175,7 @@ # define SH1101A_MRATIO(d) ((d) & 0x3f) #define SH1101A_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */ # define SH1101A_DCDC_OFF (0x8a) - # define SH1101A_DCDC_ON (0x8b) +# define SH1101A_DCDC_ON (0x8b) #define SH1101A_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */ # define SH1101A_DISPOFF SH1101A_DISPOFFON(0) /* Display off */ # define SH1101A_DISPON SH1101A_DISPOFFON(1) /* Display on */ @@ -287,10 +287,10 @@ struct ug2864ambag01_dev_s bool on; /* true: display is on */ - /* The SH1101A does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB. - */ + /* The SH1101A does not support reading from the display memory in SPI mode. + * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep + * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB. + */ uint8_t fb[UG2864AMBAG01_FBSIZE]; }; @@ -301,15 +301,8 @@ struct ug2864ambag01_dev_s /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi); -# define ug2864ambag01_lock(spi) -# define ug2864ambag01_unlock(spi) -#else -# define ug2864ambag01_configspi(spi) static void ug2864ambag01_lock(FAR struct spi_dev_s *spi); static void ug2864ambag01_unlock(FAR struct spi_dev_s *spi); -#endif /* LCD Data Transfer Methods */ @@ -375,10 +368,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = ug2864ambag01_putrun, /* Put a run into LCD memory */ - .getrun = ug2864ambag01_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = UG2864AMBAG01_BPP, /* Bits-per-pixel */ + .putrun = ug2864ambag01_putrun, /* Put a run into LCD memory */ + .getrun = ug2864ambag01_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = UG2864AMBAG01_BPP, /* Bits-per-pixel */ }; /* This is the OLED driver instance (only a single device is supported for now) */ @@ -408,38 +401,6 @@ static struct ug2864ambag01_dev_s g_oleddev = * Private Functions **************************************************************************************/ -/************************************************************************************** - * Name: ug2864ambag01_configspi - * - * Description: - * Configure the SPI for use with the UG-2864AMBAG01 - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi) -{ - lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_UG2864AMBAG01_SPIMODE, CONFIG_UG2864AMBAG01_FREQUENCY); - - /* Configure SPI for the UG-2864AMBAG01. But only if we own the SPI bus. Otherwise, - * don't bother because it might change. - */ - - SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY); -} -#endif - /************************************************************************************** * Name: ug2864ambag01_lock * @@ -456,7 +417,6 @@ static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void ug2864ambag01_lock(FAR struct spi_dev_s *spi) { /* Lock the SPI bus if there are multiple devices competing for the SPI bus. */ @@ -469,9 +429,9 @@ static inline void ug2864ambag01_lock(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY); } -#endif /************************************************************************************** * Name: ug2864ambag01_unlock @@ -489,14 +449,12 @@ static inline void ug2864ambag01_lock(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void ug2864ambag01_unlock(FAR struct spi_dev_s *spi) { /* De-select UG-2864AMBAG01 chip and relinquish the SPI bus. */ SPI_LOCK(spi, false); } -#endif /************************************************************************************** * Name: ug2864ambag01_putrun @@ -1078,10 +1036,6 @@ FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsign priv->spi = spi; - /* Configure the SPI */ - - ug2864ambag01_configspi(spi); - /* Lock and select device */ ug2864ambag01_lock(priv->spi); @@ -1099,7 +1053,7 @@ FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsign SPI_SEND(spi, SH1101A_STARTLINE(0)); /* Set display start line */ SPI_SEND(spi, SH1101A_PAGEADDR(0)); /* Set page address */ SPI_SEND(spi, SH1101A_CONTRAST_MODE); /* Contrast control */ - SPI_SEND(spi ,UG2864AMBAG01_CONTRAST); /* Default contrast */ + SPI_SEND(spi, UG2864AMBAG01_CONTRAST); /* Default contrast */ SPI_SEND(spi, SH1101A_REMAPPLEFT); /* Set segment remap left */ SPI_SEND(spi, SH1101A_EDISPOFF); /* Normal display */ SPI_SEND(spi, SH1101A_NORMAL); /* Normal (un-reversed) display mode */ @@ -1109,7 +1063,7 @@ FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsign SPI_SEND(spi, SH1101A_DISPOFFS_MODE); /* Set display offset */ SPI_SEND(spi, SH1101A_DISPOFFS(0)); SPI_SEND(spi, SH1101A_CLKDIV_SET); /* Set clock divider */ - SPI_SEND(spi, SH1101A_CLKDIV(0,0)); + SPI_SEND(spi, SH1101A_CLKDIV(0, 0)); SPI_SEND(spi, SH1101A_CMNPAD_CONFIG); /* Set common pads */ SPI_SEND(spi, SH1101A_CMNPAD(0x10)); SPI_SEND(spi, SH1101A_VCOM_SET); diff --git a/drivers/lcd/ug-9664hswag01.c b/drivers/lcd/ug-9664hswag01.c index c649e26ca173183f4341f50acc99e79d51e5c2b7..e9053a7218e6e7827999811e37f1813d71e0d405 100644 --- a/drivers/lcd/ug-9664hswag01.c +++ b/drivers/lcd/ug-9664hswag01.c @@ -247,10 +247,10 @@ struct ug_dev_s uint8_t contrast; uint8_t powered; - /* The SSD1305 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. - */ + /* The SSD1305 does not support reading from the display memory in SPI mode. + * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep + * a shadow copy of the framebuffer memory. + */ uint8_t fb[UG_FBSIZE]; }; @@ -261,13 +261,8 @@ struct ug_dev_s /* SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_select(FAR struct spi_dev_s *spi); -static inline void ug_deselect(FAR struct spi_dev_s *spi); -#else static void ug_select(FAR struct spi_dev_s *spi); static void ug_deselect(FAR struct spi_dev_s *spi); -#endif /* LCD Data Transfer Methods */ @@ -337,10 +332,10 @@ static const struct fb_videoinfo_s g_videoinfo = static const struct lcd_planeinfo_s g_planeinfo = { - .putrun = ug_putrun, /* Put a run into LCD memory */ - .getrun = ug_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = UG_BPP, /* Bits-per-pixel */ + .putrun = ug_putrun, /* Put a run into LCD memory */ + .getrun = ug_getrun, /* Get a run from LCD memory */ + .buffer = (FAR uint8_t *)g_runbuffer, /* Run scratch buffer */ + .bpp = UG_BPP, /* Bits-per-pixel */ }; /* This is the standard, NuttX LCD driver object */ @@ -415,14 +410,6 @@ static inline FAR const char *ug_powerstring(uint8_t power) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else static void ug_select(FAR struct spi_dev_s *spi) { /* Select UG-9664HSWAG01 chip (locking the SPI bus in case there are multiple @@ -438,11 +425,11 @@ static void ug_select(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_UG9664HSWAG01_SPIMODE); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); #ifdef CONFIG_UG9664HSWAG01_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_UG9664HSWAG01_FREQUENCY); + (void)SPI_SETFREQUENCY(spi, CONFIG_UG9664HSWAG01_FREQUENCY); #endif } -#endif /************************************************************************************** * Function: ug_deselect @@ -460,14 +447,6 @@ static void ug_select(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else static void ug_deselect(FAR struct spi_dev_s *spi) { /* De-select UG-9664HSWAG01 chip and relinquish the SPI bus. */ @@ -475,7 +454,6 @@ static void ug_deselect(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_DISPLAY, false); SPI_LOCK(spi, false); } -#endif /************************************************************************************** * Name: ug_putrun @@ -1109,7 +1087,7 @@ FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devn (void)SPI_SEND(spi, 0x80); /* Data 1: Set 1 of 256 contrast steps */ (void)SPI_SEND(spi, SSD1305_MAPCOL131); /* Set segment re-map */ (void)SPI_SEND(spi, SSD1305_DISPNORMAL); /* Set normal display */ -/*(void)SPI_SEND(spi, SSD1305_DISPINVERTED); Set inverse display */ +//(void)SPI_SEND(spi, SSD1305_DISPINVERTED); /* Set inverse display */ (void)SPI_SEND(spi, SSD1305_SETMUX); /* Set multiplex ratio */ (void)SPI_SEND(spi, 0x3f); /* Data 1: MUX ratio -1: 15-63 */ (void)SPI_SEND(spi, SSD1305_SETOFFSET); /* Set display offset */ diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..5a673606fc7d6d236cd2f8135be362a97f28015f --- /dev/null +++ b/drivers/leds/Kconfig @@ -0,0 +1,59 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menu "LED Support" + +config USERLED + bool "LED driver" + default n + depends on ARCH_HAVE_LEDS + ---help--- + Enable standard user LED upper half driver. + +if USERLED + +config USERLED_LOWER + bool "Generic Lower Half LED Driver" + default n + ---help--- + If the board supports the standard LED interfaces as + defined in include/nuttx/board.h header file, then this + standard LED lower half driver might be usable. + + In order for this generic driver to be usable: + + 1. The board implementation must provide the LED + interfaces as defined in include/nuttx/board.h + 2. The board.h header file must provide the definition + BOARD_NLEDS, and + 3. The board.h header file must not include any other + header files that are not accessibble in this context + (such as those in arch//src/) UNLESS those + inclusions are conditioned on __KERNEL__. button_lower.c + will undefine __KERNEL__ before included board.h. + + If your board does not meet these requirements, then the + userled_lower.c file can still be copied to your your + board src/ directory and modified for your specific board + requirements. + +endif # USERLED + +config RGBLED + bool "RGB LED Driver Support" + default n + ---help--- + This selection enables building of the "upper-half" RGB LED driver. + See include/nuttx/rgbled.h for further PWM driver information. + +config PCA9635PW + bool "PCA9635PW I2C LED Driver" + default n + select I2C + ---help--- + Enable support for the NXP PCA9635PW LED driver which can be + utilized to drive up to 16 LED's. + +endmenu # LED Support diff --git a/drivers/leds/Make.defs b/drivers/leds/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..794ba4202c30671953d46377f3f6cb1e90ac1974 --- /dev/null +++ b/drivers/leds/Make.defs @@ -0,0 +1,68 @@ +############################################################################ +# drivers/leds/Make.defs +# Various LED-related drivers +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Include LED drivers + +LEDDEPATH = +LEDVPATH = + +# Include user LED driver + +ifeq ($(CONFIG_USERLED),y) + CSRCS += userled_upper.c +ifeq ($(CONFIG_USERLED_LOWER),y) + CSRCS += userled_lower.c +endif + LEDDEPATH = --dep-path leds + LEDVPATH = :leds +endif + +ifeq ($(CONFIG_RGBLED),y) + CSRCS += rgbled.c + LEDDEPATH = --dep-path leds + LEDVPATH = :leds +endif + +ifeq ($(CONFIG_PCA9635PW),y) + CSRCS += pca9635pw.c + LEDDEPATH = --dep-path leds + LEDVPATH = :leds +endif + +# Include LED build support (if any LED drivers were selected) + +DEPPATH += $(LEDDEPATH) +VPATH += $(LEDVPATH) diff --git a/drivers/leds/pca9635pw.c b/drivers/leds/pca9635pw.c new file mode 100644 index 0000000000000000000000000000000000000000..452891555a3a3927759cf40a33f188849ad55174 --- /dev/null +++ b/drivers/leds/pca9635pw.c @@ -0,0 +1,387 @@ +/**************************************************************************** + * drivers/leds/pca9635pw.c + * + * Copyright (C) 2015 DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_PCA9635PW) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct pca9635pw_dev_s +{ + FAR struct i2c_master_s *i2c; + uint8_t i2c_addr; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int pca9635pw_i2c_write_byte(FAR struct pca9635pw_dev_s *priv, + uint8_t const reg_addr, + uint8_t const reg_val); +static int pca9635pw_set_led_mode(FAR struct pca9635pw_dev_s *priv, + uint8_t const led_out_x_mode); + +static int pca9635pw_open(FAR struct file *filep); +static int pca9635pw_close(FAR struct file *filep); +static int pca9635pw_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_pca9635pw_fileops = +{ + pca9635pw_open, /* open */ + pca9635pw_close, /* close */ + 0, /* read */ + 0, /* write */ + 0, /* seek */ + pca9635pw_ioctl, /* ioctl */ + 0 /* poll */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pca9635pw_i2c_write_byte + * + * Description: + * Write a single byte to one of the PCA9635PW configuration registers. + * + ****************************************************************************/ + +static int pca9635pw_i2c_write_byte(FAR struct pca9635pw_dev_s *priv, + uint8_t const reg_addr, + uint8_t const reg_val) +{ + struct i2c_config_s config; + + dbg("pca9635pw_i2c_write_byte\n"); + + /* assemble the 2 byte message comprised of reg_addr and reg_val */ + + uint8_t const BUFFER_SIZE = 2; + uint8_t buffer[BUFFER_SIZE]; + + buffer[0] = reg_addr; + buffer[1] = reg_val; + + /* Setup up the I2C configuration */ + + config.frequency = I2C_BUS_FREQ_HZ; + config.address = priv->i2c_addr; + config.addrlen = 7; + + /* Write the register address followed by the data (no RESTART) */ + + dbg("i2c addr: 0x%02X reg addr: 0x%02X value: 0x%02X\n", priv->i2c_addr, + buffer[0], buffer[1]); + + + ret = i2c_write(priv->i2c, &config, buffer, BUFFER_SIZE); + if (ret != OK) + { + dbg("i2c_write returned error code %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: pca9635pw_set_led_mode + * + * Description: + * Set the led output mode (see PCA9635PW_LED_OUT_x register value definitions) + * + ****************************************************************************/ + +static int pca9635pw_set_led_mode(FAR struct pca9635pw_dev_s *priv, + uint8_t const led_out_x_mode) +{ + uint8_t current_ledout_reg = PCA9635PW_LED_OUT_0; + + for (; current_ledout_reg <= PCA9635PW_LED_OUT_3; current_ledout_reg++) + { + int const ret = pca9635pw_i2c_write_byte(priv, current_ledout_reg, + led_out_x_mode); + if (ret != OK) + { + return ret; + } + } + + return OK; +} + +/**************************************************************************** + * Name: pca9635pw_open + * + * Description: + * This function is called whenever a PCA9635PW device is opened. + * + ****************************************************************************/ + +static int pca9635pw_open(FAR struct file *filep) +{ + dbg("pca9635pw_open\n"); + + FAR struct inode *inode = filep->f_inode; + FAR struct pca9635pw_dev_s *priv = inode->i_private; + + int ret = -1; + + /* Wake up the PCA9635PW (sleep bit PCA9635PW_MODE_1_SLEEP is set to zero + * and enable register auto increment - this way we can write to multiple + * consecutive I2C registers without having to always write first the + * address and then the data byte. + */ + + uint8_t const PCA9635PW_MODE_1_INITIAL_VALUE = PCA9635PW_MODE_1_AI2; + + ret = pca9635pw_i2c_write_byte(priv, PCA9635PW_MODE_1, + PCA9635PW_MODE_1_INITIAL_VALUE); + if (ret != OK) + { + dbg("Could not set initial config for PCA9635PW_MODE_1\n"); + return ret; + } + + /* Configure the PCA9635PW output drivers for totem-pole structure since + * the output of the PCA9635PW are coupled with the Gates of MOSFET's + * which then drive the LED's. Since we have this kind of schematic + * structure we also need to invert the output. + */ + + uint8_t const PCA9635PW_MODE_2_INITIAL_VALUE = + PCA9635PW_MODE_2_INVRT | PCA9635PW_MODE_2_OUTDRV; + + ret = pca9635pw_i2c_write_byte(priv, PCA9635PW_MODE_2, + PCA9635PW_MODE_2_INITIAL_VALUE); + if (ret != OK) + { + dbg("Could not set initial config for PCA9635PW_MODE_2\n"); + return ret; + } + + /* A delay of 500 us is necessary since this is the maximum time which the + * oscillator of the PCA9635PW needs to be up and running once sleep mode was + * left. + */ + + usleep(500); + + /* Turn all led drivers to mode 2 in which the led brightness is controlled + * by the indiviual pwm registers. + */ + + ret = pca9635pw_set_led_mode(priv, PCA9635PW_LED_OUT_x_MODE_2); + if (ret != OK) + { + dbg("Could not set led driver outputs to MODE2 (LED's brightness are " + "controlled by pwm registers)\n"); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: pca9635pw_close + * + * Description: + * This function is called whenever a PCA9635PW device is closed. + * + ****************************************************************************/ + +static int pca9635pw_close(FAR struct file *filep) +{ + dbg("pca9635pw_close\n"); + + FAR struct inode *inode = filep->f_inode; + FAR struct pca9635pw_dev_s *priv = inode->i_private; + + int ret = -1; + + /* Turn all led drivers off */ + + ret = pca9635pw_set_led_mode(priv, PCA9635PW_LED_OUT_x_MODE_0); + if (ret != OK) + { + dbg("Could not set led driver outputs to MODE0 (LED's are off)\n"); + return ret; + } + + /* Send the PCA9635PW back to sleep mode */ + + uint8_t const PCA9635PW_MODE_1_FINAL_VALUE = PCA9635PW_MODE_1_SLEEP; + + ret =pca9635pw_i2c_write_byte(priv, PCA9635PW_MODE_1, + PCA9635PW_MODE_1_FINAL_VALUE); + if (ret != OK) + { + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: pca9635pw_close + * + * Description: + * This function is called whenever an ioctl call to a PCA9635PW is performed. + * + ****************************************************************************/ + +static int pca9635pw_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + dbg("pca9635pw_ioctl\n"); + + FAR struct inode *inode = filep->f_inode; + FAR struct pca9635pw_dev_s *priv = inode->i_private; + + int ret = OK; + + dbg("cmd: %d arg: %ld\n", cmd, arg); + + switch (cmd) + { + /* Set the brightness of an indivual LED. Arg: pca9635pw_led_brightness_s + * pointer. + */ + + case PWMIOC_SETLED_BRIGHTNESS: + { + /* Retrieve the information handed over as argument for this ioctl */ + + FAR const struct pca9635pw_setled_brightness_arg_s *ptr = + (FAR const struct pca9635pw_setled_brightness_arg_s *)((uintptr_t)arg); + + DEBUGASSERT(ptr != NULL); + + /* Set the brighntess of the led */ + + ret = pca9635pw_i2c_write_byte(priv, ptr->led, ptr->brightness); + } + break; + + /* The used ioctl command was invalid */ + + default: + { + dbg("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + } + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pca9635pw_register + * + * Description: + * Register the PCA9635PW device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/leddrv0". + * i2c - An instance of the I2C interface to use to communicate + * with the LM92. + * pca9635pw_i2c_addr + * - The I2C address of the PCA9635PW. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pca9635pw_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t const pca9635pw_i2c_addr) +{ + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + + /* Initialize the PCA9635PW device structure */ + + FAR struct pca9635pw_dev_s *priv = + (FAR struct pca9635pw_dev_s *)kmm_malloc(sizeof(struct pca9635pw_dev_s)); + + if (priv == NULL) + { + dbg("Failed to allocate instance of pca9635pw_dev_s\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->i2c_addr = pca9635pw_i2c_addr; + + /* Register the character driver */ + + int const ret = register_driver(devpath, &g_pca9635pw_fileops, 666, priv); + if (ret != OK) + { + dbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +#endif /* CONFIG_I2C && CONFIG_I2C_PCA9635PW */ diff --git a/drivers/leds/rgbled.c b/drivers/leds/rgbled.c new file mode 100644 index 0000000000000000000000000000000000000000..27e7a1a9ebeb1b80a43da3d4c642dd8e136d7ad2 --- /dev/null +++ b/drivers/leds/rgbled.c @@ -0,0 +1,417 @@ +/**************************************************************************** + * drivers/rgbled.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_RGBLED + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing PWM */ + +#ifdef CONFIG_DEBUG_RGBLED +# define pwmdbg dbg +# define pwmvdbg vdbg +# define pwmlldbg lldbg +# define pwmllvdbg llvdbg +#else +# define pwmdbg(x...) +# define pwmvdbg(x...) +# define pwmlldbg(x...) +# define pwmllvdbg(x...) +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* This structure describes the state of the upper half driver */ + +struct rgbled_upperhalf_s +{ + uint8_t crefs; /* The number of times the device has been opened */ + volatile bool started; /* True: pulsed output is being generated */ + sem_t exclsem; /* Supports mutual exclusion */ + struct pwm_info_s ledr; /* Pulsed output for LED R*/ + struct pwm_info_s ledg; /* Pulsed output for LED G*/ + struct pwm_info_s ledb; /* Pulsed output for LED B*/ + struct pwm_lowerhalf_s *devledr; + struct pwm_lowerhalf_s *devledg; + struct pwm_lowerhalf_s *devledb; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int rgbled_open(FAR struct file *filep); +static int rgbled_close(FAR struct file *filep); +static ssize_t rgbled_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_rgbledops = +{ + rgbled_open, /* open */ + rgbled_close, /* close */ + rgbled_read, /* read */ + rgbled_write, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rgbled_open + * + * Description: + * This function is called whenever the PWM device is opened. + * + ****************************************************************************/ + +static int rgbled_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct rgbled_upperhalf_s *upper = inode->i_private; + uint8_t tmp; + int ret; + + pwmvdbg("crefs: %d\n", upper->crefs); + + /* Get exclusive access to the device structures */ + + ret = sem_wait(&upper->exclsem); + if (ret < 0) + { + ret = -get_errno(); + goto errout; + } + + /* Increment the count of references to the device. If this the first + * time that the driver has been opened for this device, then initialize + * the device. + */ + + tmp = upper->crefs + 1; + if (tmp == 0) + { + /* More than 255 opens; uint8_t overflows to zero */ + + ret = -EMFILE; + goto errout_with_sem; + } + + /* Save the new open count on success */ + + upper->crefs = tmp; + ret = OK; + +errout_with_sem: + sem_post(&upper->exclsem); + +errout: + return ret; +} + +/**************************************************************************** + * Name: rgbled_close + * + * Description: + * This function is called when the PWM device is closed. + * + ****************************************************************************/ + +static int rgbled_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct rgbled_upperhalf_s *upper = inode->i_private; + int ret; + + pwmvdbg("crefs: %d\n", upper->crefs); + + /* Get exclusive access to the device structures */ + + ret = sem_wait(&upper->exclsem); + if (ret < 0) + { + ret = -get_errno(); + goto errout; + } + + /* Decrement the references to the driver. If the reference count will + * decrement to 0, then uninitialize the driver. + */ + + if (upper->crefs > 1) + { + upper->crefs--; + } + + sem_post(&upper->exclsem); + ret = OK; + +errout: + return ret; +} + +/**************************************************************************** + * Name: rgbled_read + * + * Description: + * A dummy read method. This is provided only to satisfy the VFS layer. + * + ****************************************************************************/ + +static ssize_t rgbled_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + /* Return zero -- usually meaning end-of-file */ + + return 0; +} + +/**************************************************************************** + * Name: rgbled_write + * + * Description: + * A dummy write method. This is provided only to satisfy the VFS layer. + * + ****************************************************************************/ + +static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + + FAR struct inode *inode = filep->f_inode; + FAR struct rgbled_upperhalf_s *upper = inode->i_private; + FAR struct pwm_lowerhalf_s *ledr = upper->devledr; + FAR struct pwm_lowerhalf_s *ledg = upper->devledg; + FAR struct pwm_lowerhalf_s *ledb = upper->devledb; + + unsigned int red; + unsigned int green; + unsigned int blue; + char color[3]; + + /* We need to receive a string #RRGGBB = 7 bytes */ + + if (buffer == NULL || buflen < 7) + { + /* Well... nothing to do */ + + return -EINVAL; + } + + /* Check if it is a color format */ + + if (buffer[0] != '#') + { + /* The color code needs to start with # */ + + return -EINVAL; + } + + /* Move buffer to next character */ + + buffer++; + + color[0] = buffer[0]; + color[1] = buffer[1]; + color[2] = '\0'; + + red = strtol(color, NULL, 16); + + color[0] = buffer[2]; + color[1] = buffer[3]; + color[2] = '\0'; + + green = strtol(color, NULL, 16); + + color[0] = buffer[4]; + color[1] = buffer[5]; + color[2] = '\0'; + + blue = strtol(color, NULL, 16); + + /* Sane check */ + + if (red > 255) + { + red = 255; + } + + if (green > 255) + { + green = 255; + } + + if (blue > 255) + { + blue = 255; + } + + /* Convert 8bit to 16bits */ + + red <<= 8; + green <<= 8; + blue <<= 8; + + /* Setup LED R */ + + upper->ledr.frequency = 100; + upper->ledr.duty = red; + + ledr->ops->start(ledr, &upper->ledr); + + /* Setup LED G */ + + upper->ledg.frequency = 100; + upper->ledg.duty = green; + + ledg->ops->start(ledg, &upper->ledg); + + /* Setup LED B */ + + upper->ledb.frequency = 100; + upper->ledb.duty = blue; + + ledb->ops->start(ledb, &upper->ledb); + + return buflen; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rgbled_register + * + * Description: + * This function binds three instances of a "lower half" PWM driver with + * the "upper half" RGB LED device and registers that device so that can + * be used by application code. + * + * + * Input parameters: + * path - The full path to the driver to be registers in the NuttX pseudo- + * filesystem. The recommended convention is to name all PWM drivers + * as "/dev/rgdbled0", "/dev/rgbled1", etc. where the driver path + * differs only in the "minor" number at the end of the device name. + * ledr, ledg, and ledb - A pointer to an instance of lower half PWM + * drivers for the red, green, and blue LEDs, respectively. These + * instances will be bound to the RGB LED driver and must persists as + * long as that driver persists. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int rgbled_register(FAR const char *path, FAR struct pwm_lowerhalf_s *ledr, + FAR struct pwm_lowerhalf_s *ledg, + FAR struct pwm_lowerhalf_s *ledb) +{ + FAR struct rgbled_upperhalf_s *upper; + + /* Allocate the upper-half data structure */ + + upper = (FAR struct rgbled_upperhalf_s *) + kmm_zalloc(sizeof(struct rgbled_upperhalf_s)); + + if (!upper) + { + pwmdbg("Allocation failed\n"); + return -ENOMEM; + } + + /* Initialize the PWM device structure (it was already zeroed by + * kmm_zalloc()) + */ + + sem_init(&upper->exclsem, 0, 1); + upper->devledr = ledr; + upper->devledg = ledg; + upper->devledb = ledb; + + /* Register the PWM device */ + + pwmvdbg("Registering %s\n", path); + return register_driver(path, &g_rgbledops, 0666, upper); +} + +#endif /* CONFIG_RGBLED */ diff --git a/drivers/leds/userled_lower.c b/drivers/leds/userled_lower.c new file mode 100644 index 0000000000000000000000000000000000000000..69e349f64d432baaac7b3ee2d7ddde6daeda3d89 --- /dev/null +++ b/drivers/leds/userled_lower.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * drivers/leds/userled_lower.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#undef __KERNEL__ +#include + +#if CONFIG_USERLED_LOWER + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static userled_set_t userled_supported(FAR const struct userled_lowerhalf_s *lower); +static void userled_led(FAR const struct userled_lowerhalf_s *lower, + int led, bool ledon); +static void userled_ledset(FAR const struct userled_lowerhalf_s *lower, + userled_set_t ledset); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the user LED lower half driver interface */ + +static const struct userled_lowerhalf_s g_userled_lower = +{ + .ll_supported = userled_supported, + .ll_led = userled_led, + .ll_ledset = userled_ledset, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: userled_supported + * + * Description: + * Return the set of LEDs supported by the board + * + ****************************************************************************/ + +static userled_set_t userled_supported(FAR const struct userled_lowerhalf_s *lower) +{ + ivdbg("BOARD_NLEDS: %02x\n", BOARD_NLEDS); + return (userled_set_t)((1 << BOARD_NLEDS) - 1); +} + +/**************************************************************************** + * Name: userled_led + * + * Description: + * Set the current state of one LED + * + ****************************************************************************/ + +static void userled_led(FAR const struct userled_lowerhalf_s *lower, + int led, bool ledon) +{ + board_userled(led, ledon); +} + +/**************************************************************************** + * Name: userled_led + * + * Description: + * Set the state of all LEDs + * + ****************************************************************************/ + +static void userled_ledset(FAR const struct userled_lowerhalf_s *lower, + userled_set_t ledset) +{ + board_userled_all(ledset); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: userled_lower_initialize + * + * Description: + * Initialize the generic LED lower half driver, bind it and register + * it with the upper half LED driver as devname. + * + ****************************************************************************/ + +int userled_lower_initialize(FAR const char *devname) +{ + board_userled_initialize(); + return userled_register(devname, &g_userled_lower); +} + +#endif /* CONFIG_USERLED_LOWER */ diff --git a/drivers/leds/userled_upper.c b/drivers/leds/userled_upper.c new file mode 100644 index 0000000000000000000000000000000000000000..0d2377b624f2d792bce6956f2fe679473d6dc4bd --- /dev/null +++ b/drivers/leds/userled_upper.c @@ -0,0 +1,600 @@ +/**************************************************************************** + * drivers/leds/userled_upper.c + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 file provides a driver for a LED input devices. + * + * The LEDs driver exports a standard character driver interface. By + * convention, the LED driver is registered as an input device at + * /dev/btnN where N uniquely identifies the driver instance. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_DISCRETE +#endif + +#ifdef CONFIG_DEBUG_DISCRETE +# define ddbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define dvdbg lldbg +# else +# define dvdbg(x...) +# endif +#else +# define ddbg(x...) +# define dvdbg(x...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the state of one LED driver */ + +struct userled_upperhalf_s +{ + /* Saved binding to the lower half LED driver */ + + FAR const struct userled_lowerhalf_s *lu_lower; + + userled_set_t lu_supported; /* The set of supported LEDs */ + userled_set_t lu_ledset; /* Current state of LEDs */ + sem_t lu_exclsem; /* Supports exclusive access to the device */ + + /* The following is a singly linked list of open references to the + * LED device. + */ + + FAR struct userled_open_s *lu_open; +}; + +/* This structure describes the state of one open LED driver instance */ + +struct userled_open_s +{ + /* Supports a singly linked list */ + + FAR struct userled_open_s *bo_flink; + + /* The following will be true if we are closing */ + + volatile bool bo_closing; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Semaphore helpers */ + +static inline int userled_takesem(sem_t *sem); +#define userled_givesem(s) sem_post(s); + +/* Character driver methods */ + +static int userled_open(FAR struct file *filep); +static int userled_close(FAR struct file *filep); +static ssize_t userled_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int userled_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations userled_fops = +{ + userled_open, /* open */ + userled_close, /* close */ + 0, /* read */ + userled_write, /* write */ + 0, /* seek */ + userled_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: userled_takesem + ****************************************************************************/ + +static inline int userled_takesem(sem_t *sem) +{ + /* Take a count from the semaphore, possibly waiting */ + + if (sem_wait(sem) < 0) + { + /* EINTR is the only error that we expect */ + + int errcode = get_errno(); + DEBUGASSERT(errcode == EINTR); + return -errcode; + } + + return OK; +} + +/**************************************************************************** + * Name: userled_open + ****************************************************************************/ + +static int userled_open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct userled_upperhalf_s *priv; + FAR struct userled_open_s *opriv; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct userled_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = userled_takesem(&priv->lu_exclsem); + if (ret < 0) + { + dvdbg("ERROR: userled_takesem failed: %d\n", ret); + return ret; + } + + /* Allocate a new open structure */ + + opriv = (FAR struct userled_open_s *)kmm_zalloc(sizeof(struct userled_open_s)); + if (!opriv) + { + dvdbg("ERROR: Failled to allocate open structure\n"); + ret = -ENOMEM; + goto errout_with_sem; + } + + /* Attach the open structure to the device */ + + opriv->bo_flink = priv->lu_open; + priv->lu_open = opriv; + + /* Attach the open structure to the file structure */ + + filep->f_priv = (FAR void *)opriv; + ret = OK; + +errout_with_sem: + userled_givesem(&priv->lu_exclsem); + return ret; +} + +/**************************************************************************** + * Name: userled_close + ****************************************************************************/ + +static int userled_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct userled_upperhalf_s *priv; + FAR struct userled_open_s *opriv; + FAR struct userled_open_s *curr; + FAR struct userled_open_s *prev; + irqstate_t flags; + bool closing; + int ret; + + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct userled_upperhalf_s *)inode->i_private; + + /* Handle an improbable race conditions with the following atomic test + * and set. + * + * This is actually a pretty feeble attempt to handle this. The + * improbable race condition occurs if two different threads try to + * close the LED driver at the same time. The rule: don't do + * that! It is feeble because we do not really enforce stale pointer + * detection anyway. + */ + + flags = enter_critical_section(); + closing = opriv->bo_closing; + opriv->bo_closing = true; + leave_critical_section(flags); + + if (closing) + { + /* Another thread is doing the close */ + + return OK; + } + + /* Get exclusive access to the driver structure */ + + ret = userled_takesem(&priv->lu_exclsem); + if (ret < 0) + { + dvdbg("ERROR: userled_takesem failed: %d\n", ret); + return ret; + } + + /* Find the open structure in the list of open structures for the device */ + + for (prev = NULL, curr = priv->lu_open; + curr && curr != opriv; + prev = curr, curr = curr->bo_flink); + + DEBUGASSERT(curr); + if (!curr) + { + dvdbg("ERROR: Failed to find open entry\n"); + ret = -ENOENT; + goto errout_with_exclsem; + } + + /* Remove the structure from the device */ + + if (prev) + { + prev->bo_flink = opriv->bo_flink; + } + else + { + priv->lu_open = opriv->bo_flink; + } + + /* And free the open structure */ + + kmm_free(opriv); + ret = OK; + +errout_with_exclsem: + userled_givesem(&priv->lu_exclsem); + return ret; +} + +/**************************************************************************** + * Name: userled_write + ****************************************************************************/ + +static ssize_t userled_write(FAR struct file *filep, FAR const char *buffer, + size_t len) +{ + FAR struct inode *inode; + FAR struct userled_upperhalf_s *priv; + FAR const struct userled_lowerhalf_s *lower; + userled_set_t ledset; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct userled_upperhalf_s *)inode->i_private; + + /* Make sure that the buffer is sufficiently large to hold at least one + * complete sample. + * + * REVISIT: Should also check buffer alignment. + */ + + if (len < sizeof(userled_set_t)) + { + dvdbg("ERROR: buffer too small: %lu\n", (unsigned long)len); + return -EINVAL; + } + + /* Get the LED set to write. + * REVISIT: if sizeof(userled_set_t) > 1, then we will have to address + * some buffer alignment issues. + */ + + DEBUGASSERT(buffer != NULL); + ledset = *(userled_set_t *)buffer; + + /* Get exclusive access to the driver structure */ + + ret = userled_takesem(&priv->lu_exclsem); + if (ret < 0) + { + dvdbg("ERROR: userled_takesem failed: %d\n", ret); + return ret; + } + + /* Read and return the current state of the LEDs */ + + lower = priv->lu_lower; + DEBUGASSERT(lower && lower->ll_ledset); + lower->ll_ledset(lower, ledset); + + userled_givesem(&priv->lu_exclsem); + return (ssize_t)sizeof(userled_set_t); +} + +/**************************************************************************** + * Name: userled_ioctl + ****************************************************************************/ + +static int userled_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct userled_upperhalf_s *priv; + FAR const struct userled_lowerhalf_s *lower; + int ret; + + DEBUGASSERT(filep != NULL && filep->f_priv != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct userled_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = userled_takesem(&priv->lu_exclsem); + if (ret < 0) + { + dvdbg("ERROR: userled_takesem failed: %d\n", ret); + return ret; + } + + /* Handle the ioctl command */ + + ret = -EINVAL; + switch (cmd) + { + /* Command: ULEDIOC_SUPPORTED + * Description: Report the set of LEDs supported by the hardware; + * Argument: A pointer to writeable userled_set_t value in which to + * return the set of supported LEDs. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + + case ULEDIOC_SUPPORTED: + { + FAR userled_set_t *supported = (FAR userled_set_t *)((uintptr_t)arg); + + /* Verify that a non-NULL pointer was provided */ + + if (supported) + { + *supported = priv->lu_supported; + ret = OK; + } + } + break; + + /* Command: ULEDIOC_SETLED + * Description: Set the state of one LED. + * Argument: A read-only pointer to an instance of struct userled_s + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + + case ULEDIOC_SETLED: + { + FAR struct userled_s *userled = (FAR struct userled_s *)((uintptr_t)arg); + int led; + bool ledon; + + /* Verify that a non-NULL pointer was provided */ + + if (userled) + { + led = userled->ul_led; + ledon = userled->ul_on; + + /* Check that a valid LED is being set */ + + if (led < 8 * sizeof(userled_set_t) && + (priv->lu_supported & (1 << led)) != 0) + { + /* Update the LED state */ + + if (ledon) + { + priv->lu_ledset |= (1 << led); + } + else + { + priv->lu_ledset &= ~(1 << led); + } + + /* Set the LED state */ + + lower = priv->lu_lower; + DEBUGASSERT(lower != NULL && lower->ll_led != NULL); + lower->ll_led(lower, led, ledon); + ret = OK; + } + } + } + break; + + /* Command: ULEDIOC_SETALL + * Description: Set the state of all LEDs. + * Argument: A value of type userled_set_t cast to unsigned long + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + + case ULEDIOC_SETALL: + { + userled_set_t ledset = (userled_set_t)((uintptr_t)arg); + + /* Verify that a valid LED set was provided */ + + if ((ledset & priv->lu_supported) == ledset) + { + /* Update the LED state */ + + priv->lu_ledset = ledset; + + /* Set the new LED state */ + + lower = priv->lu_lower; + DEBUGASSERT(lower != NULL && lower->ll_led != NULL); + lower->ll_ledset(lower, ledset); + ret = OK; + } + } + break; + + /* Command: ULEDIOC_GETALL + * Description: Get the state of one LED. + * Argument: A write-able pointer to a userled_set_t memory location in + * which to return the LED state. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + + case ULEDIOC_GETALL: + { + FAR userled_set_t *ledset = (FAR userled_set_t *)((uintptr_t)arg); + + /* Verify that a non-NULL pointer was provided */ + + if (ledset) + { + *ledset = priv->lu_ledset; + ret = OK; + } + } + break; + + default: + dvdbg("ERROR: Unrecognized command: %ld\n", cmd); + ret = -ENOTTY; + break; + } + + userled_givesem(&priv->lu_exclsem); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: userled_register + * + * Description: + * Bind the lower half LED driver to an instance of the upper half + * LED driver and register the composite character driver as the + * specified device. + * + * Input Parameters: + * devname - The name of the LED device to be registered. + * This should be a string of the form "/dev/ledN" where N is the the + * minor device number. + * lower - An instance of the platform-specific LED lower half driver. + * + * Returned Values: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int userled_register(FAR const char *devname, + FAR const struct userled_lowerhalf_s *lower) +{ + FAR struct userled_upperhalf_s *priv; + int ret; + + DEBUGASSERT(devname && lower); + + /* Allocate a new LED driver instance */ + + priv = (FAR struct userled_upperhalf_s *) + kmm_zalloc(sizeof(struct userled_upperhalf_s)); + + if (!priv) + { + dvdbg("ERROR: Failed to allocate device structure\n"); + return -ENOMEM; + } + + /* Initialize the new LED driver instance */ + + priv->lu_lower = lower; + sem_init(&priv->lu_exclsem, 0, 1); + + DEBUGASSERT(lower && lower->ll_supported); + priv->lu_supported = lower->ll_supported(lower); + + DEBUGASSERT(lower && lower->ll_ledset); + priv->lu_ledset = 0; + lower->ll_ledset(lower, priv->lu_ledset); + + /* And register the LED driver */ + + ret = register_driver(devname, &userled_fops, 0666, priv); + if (ret < 0) + { + dvdbg("ERROR: register_driver failed: %d\n", ret); + goto errout_with_priv; + } + + return OK; + +errout_with_priv: + sem_destroy(&priv->lu_exclsem); + kmm_free(priv); + return ret; +} diff --git a/drivers/loop/Kconfig b/drivers/loop/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..1a1dd2a189908cdadfeebefd4d162f4540ecc3f2 --- /dev/null +++ b/drivers/loop/Kconfig @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config DEV_LOOP + bool "Enable loop device" + default n + ---help--- + Supports the standard loop device that can be used to export a + file (or character device) as a block device. diff --git a/drivers/loop/Make.defs b/drivers/loop/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..a7c933667c294ad997b615d52054d805debf8db1 --- /dev/null +++ b/drivers/loop/Make.defs @@ -0,0 +1,54 @@ +############################################################################ +# drivers/loop/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Loop device can only be used with mountpoint support + +ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) + +# Include loop device support + +ifeq ($(CONFIG_DEV_LOOP),y) + CSRCS += loop.c +endif + +CSRCS += losetup.c + +# Add loop devicer build support + +DEPPATH += --dep-path loop +VPATH += :loop +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)loop} + +endif diff --git a/drivers/loop/loop.c b/drivers/loop/loop.c new file mode 100644 index 0000000000000000000000000000000000000000..19cd75d62cf194da9a66baae79d32b319a534105 --- /dev/null +++ b/drivers/loop/loop.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * drivers/loop/loop.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_DEV_LOOP + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t loop_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t loop_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int loop_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_loop_fops = +{ + 0, /* open */ + 0, /* close */ + loop_read, /* read */ + loop_write, /* write */ + 0, /* seek */ + loop_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: loop_read + ****************************************************************************/ + +static ssize_t loop_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + return 0; /* Return EOF */ +} + +/**************************************************************************** + * Name: loop_write + ****************************************************************************/ + +static ssize_t loop_write(FAR struct file *filep, FAR const char *buffer, size_t len) +{ + return len; /* Say that everything was written */ +} + +/**************************************************************************** + * Name: loop_ioctl + ****************************************************************************/ + +static int loop_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + int ret; + + switch (cmd) + { + /* Command: LOOPIOC_SETUP + * Description: Setup the loop device + * Argument: A pointer to a read-only instance of struct losetup_s. + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + + case LOOPIOC_SETUP: + { + FAR struct losetup_s *setup = (FAR struct losetup_s *)((uintptr_t)arg); + + if (setup == NULL) + { + ret = -EINVAL; + } + else + { + ret = losetup(setup->devname, setup->filename, setup->sectsize, + setup->offset, setup->readonly); + } + } + break; + + /* Command: LOOPIOC_TEARDOWN + * Description: Teardown a loop device previously setup vis LOOPIOC_SETUP + * Argument: A read-able pointer to the path of the device to be + * torn down + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + + case LOOPIOC_TEARDOWN: + { + FAR const char *devname = (FAR const char *)((uintptr_t)arg); + + if (devname == NULL) + { + ret = -EINVAL; + } + else + { + ret = loteardown(devname); + } + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: loop_register + * + * Description: + * Register /dev/null + * + ****************************************************************************/ + +void loop_register(void) +{ + (void)register_driver("/dev/loop", &g_loop_fops, 0666, NULL); +} + +#endif /* CONFIG_DEV_LOOP */ diff --git a/drivers/loop.c b/drivers/loop/losetup.c similarity index 99% rename from drivers/loop.c rename to drivers/loop/losetup.c index 9d51dd74656c0d2930767cabf7c741d66df40961..dadd44891cd1fff84249b8c320f41cb85ba0e1c7 100644 --- a/drivers/loop.c +++ b/drivers/loop/losetup.c @@ -1,7 +1,7 @@ /**************************************************************************** - * drivers/loop.c + * drivers/loop/losetup.c * - * Copyright (C) 2008-2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -58,6 +58,7 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/mmcsd/mmcsd_internal.h b/drivers/mmcsd/mmcsd.h similarity index 96% rename from drivers/mmcsd/mmcsd_internal.h rename to drivers/mmcsd/mmcsd.h index 36843685d84dd0ef63e7bd65bc201fe1cb0359fe..06d91348d02746063f2d8a65dbfc1e6eab473329 100644 --- a/drivers/mmcsd/mmcsd_internal.h +++ b/drivers/mmcsd/mmcsd.h @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/mmcsd/mmcsd_internal.h + * drivers/mmcsd/mmcsd.h * * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __DRIVERS_MMCSD_MMCSD_INTERNAL_H -#define __DRIVERS_MMCSD_MMCSD_INTERNAL_H +#ifndef __DRIVERS_MMCSD_MMCSD_H +#define __DRIVERS_MMCSD_MMCSD_H /**************************************************************************** * Included Files @@ -102,4 +102,4 @@ EXTERN void mmcsd_dmpcsd(FAR const uint8_t *csd, uint8_t cardtype); #if defined(__cplusplus) } #endif -#endif /* __DRIVERS_MMCSD_MMCSD_INTERNAL_H */ +#endif /* __DRIVERS_MMCSD_MMCSD_H */ diff --git a/drivers/mmcsd/mmcsd_debug.c b/drivers/mmcsd/mmcsd_debug.c index ea3788a29b66f88f1741eaec0b2a2c1d446e2975..e28b985a02553dccf1a335c5322daade4226d05a 100644 --- a/drivers/mmcsd/mmcsd_debug.c +++ b/drivers/mmcsd/mmcsd_debug.c @@ -47,7 +47,7 @@ #include #include "mmcsd_csd.h" -#include "mmcsd_internal.h" +#include "mmcsd.h" /**************************************************************************** * Pre-processor Definitions diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index 2ff3fd717d21d22f297c78f59753dd87026008e1..e3097d481267160efbdfd6c9bb12ff9a1afca536 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/mmcsd/mmcsd_sdio.c * - * Copyright (C) 2009-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -65,7 +65,7 @@ #include #include -#include "mmcsd_internal.h" +#include "mmcsd.h" #include "mmcsd_sdio.h" /**************************************************************************** @@ -498,9 +498,11 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2]) /* Setup up to receive data with interrupt mode */ SDIO_BLOCKSETUP(priv->dev, 8, 1); - SDIO_RECVSETUP(priv->dev, (FAR uint8_t*)scr, 8); + SDIO_RECVSETUP(priv->dev, (FAR uint8_t *)scr, 8); - (void)SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); + (void)SDIO_WAITENABLE(priv->dev, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | + SDIOWAIT_ERROR); /* Send CMD55 APP_CMD with argument as card's RCA */ @@ -525,7 +527,8 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2]) /* Wait for data to be transferred */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_SCR_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_SCR_DATADELAY); if (ret != OK) { fdbg("ERROR: mmcsd_eventwait for READ DATA failed: %d\n", ret); @@ -954,7 +957,7 @@ struct mmcsd_scr_s decoded; fvdbg("SCR:\n"); fvdbg(" SCR_STRUCTURE: %d SD_VERSION: %d\n", - decoded.scrversion,decoded.sdversion); + decoded.scrversion, decoded.sdversion); fvdbg(" DATA_STATE_AFTER_ERASE: %d SD_SECURITY: %d SD_BUS_WIDTHS: %x\n", decoded.erasestate, decoded.security, decoded.buswidth); fvdbg(" Manufacturing data: %08x\n", @@ -1117,10 +1120,10 @@ static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv, static int mmcsd_transferready(FAR struct mmcsd_state_s *priv) { - uint32_t starttime; - uint32_t elapsed; + systime_t starttime; + systime_t elapsed; uint32_t r1; - int ret; + int ret; /* First, check if the card has been removed. */ @@ -1151,7 +1154,7 @@ static int mmcsd_transferready(FAR struct mmcsd_state_s *priv) */ #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, MMCSD_BLOCK_WDATADELAY); if (ret != OK) { @@ -1353,7 +1356,8 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, /* Configure SDIO controller hardware for the read transfer */ SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1); - SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); + SDIO_WAITENABLE(priv->dev, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) @@ -1388,7 +1392,8 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, /* Then wait for the data transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_RDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + MMCSD_BLOCK_RDATADELAY); if (ret != OK) { fdbg("ERROR: CMD17 transfer failed: %d\n", ret); @@ -1485,7 +1490,8 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, /* Configure SDIO controller hardware for the read transfer */ SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks); - SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); + SDIO_WAITENABLE(priv->dev, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) @@ -1518,7 +1524,8 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_RDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, + nblocks * MMCSD_BLOCK_RDATADELAY); if (ret != OK) { fdbg("ERROR: CMD18 transfer failed: %d\n", ret); @@ -1698,7 +1705,8 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, /* Configure SDIO controller hardware for the write transfer */ SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1); - SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); + SDIO_WAITENABLE(priv->dev, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1723,7 +1731,8 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_WDATADELAY); + ret = mmcsd_eventwait(priv, + SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, MMCSD_BLOCK_WDATADELAY); if (ret != OK) { fdbg("ERROR: CMD24 transfer failed: %d\n", ret); @@ -1733,7 +1742,7 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, #if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) /* Arm the write complete detection with timeout */ - SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE|SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_WRCOMPLETE | SDIOWAIT_TIMEOUT); #endif /* On success, return the number of blocks written */ @@ -1859,7 +1868,8 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, /* Configure SDIO controller hardware for the write transfer */ SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks); - SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); + SDIO_WAITENABLE(priv->dev, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1896,7 +1906,7 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_WDATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_WDATADELAY); if (ret != OK) { fdbg("ERROR: CMD18 transfer failed: %d\n", ret); @@ -2704,9 +2714,9 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv) static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv) { uint32_t response; - uint32_t start; - uint32_t elapsed; uint32_t sdcapacity = MMCSD_ACMD41_STDCAPACITY; + systime_t start; + systime_t elapsed; int ret; /* Assume failure to identify the card */ @@ -2749,7 +2759,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv) * CMD8 Response: R7 */ - ret = mmcsd_sendcmdpoll(priv, SD_CMD8, MMCSD_CMD8CHECKPATTERN|MMCSD_CMD8VOLTAGE_27); + ret = mmcsd_sendcmdpoll(priv, SD_CMD8, + MMCSD_CMD8CHECKPATTERN | MMCSD_CMD8VOLTAGE_27); if (ret == OK) { /* CMD8 was sent successfully... Get the R7 response */ @@ -2815,7 +2826,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv) { /* Send ACMD41 */ - mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCSD_ACMD41_VOLTAGEWINDOW_33_32|sdcapacity); + mmcsd_sendcmdpoll(priv, SD_ACMD41, + MMCSD_ACMD41_VOLTAGEWINDOW_33_32 | sdcapacity); ret = SDIO_RECVR3(priv->dev, SD_ACMD41, &response); if (ret != OK) { @@ -3009,18 +3021,18 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv) switch (priv->type) { - case MMCSD_CARDTYPE_SDV1: /* Bit 1: SD version 1.x */ - case MMCSD_CARDTYPE_SDV2: /* SD version 2.x with byte addressing */ - case MMCSD_CARDTYPE_SDV2|MMCSD_CARDTYPE_BLOCK: /* SD version 2.x with block addressing */ + case MMCSD_CARDTYPE_SDV1: /* Bit 1: SD version 1.x */ + case MMCSD_CARDTYPE_SDV2: /* SD version 2.x with byte addressing */ + case MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK: /* SD version 2.x with block addressing */ ret = mmcsd_sdinitialize(priv); break; - case MMCSD_CARDTYPE_MMC: /* MMC card */ + case MMCSD_CARDTYPE_MMC: /* MMC card */ #ifdef CONFIG_MMCSD_MMCSUPPORT ret = mmcsd_mmcinitialize(priv); break; #endif - case MMCSD_CARDTYPE_UNKNOWN: /* Unknown card type */ + case MMCSD_CARDTYPE_UNKNOWN: /* Unknown card type */ default: fdbg("ERROR: Internal confusion: %d\n", priv->type); ret = -EPERM; diff --git a/drivers/mmcsd/mmcsd_spi.c b/drivers/mmcsd/mmcsd_spi.c index 16fc31089f67616dee80cc91641402574689e54c..9a44011f424566007a9ce7812acb4ae61f49c2d7 100644 --- a/drivers/mmcsd/mmcsd_spi.c +++ b/drivers/mmcsd/mmcsd_spi.c @@ -59,7 +59,7 @@ #include "mmcsd_spi.h" #include "mmcsd_csd.h" -#include "mmcsd_internal.h" +#include "mmcsd.h" /**************************************************************************** * Pre-processor Definitions @@ -158,9 +158,7 @@ struct mmcsd_slot_s uint32_t twrite; /* Card write time */ uint32_t ocr; /* Last 4 bytes of OCR (R3) */ uint32_t r7; /* Last 4 bytes of R7 */ -#ifndef CONFIG_SPI_OWNBUS uint32_t spispeed; /* Speed to use for SPI in data mode */ -#endif }; struct mmcsd_cmdinfo_s @@ -181,12 +179,6 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot); /* Card SPI interface *******************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void mmcsd_spiinit(FAR struct mmcsd_slot_s *slot); -#else -# define mmcsd_spiinit(slot) -#endif - static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot); static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot, const struct mmcsd_cmdinfo_s *cmd, uint32_t arg); @@ -274,7 +266,7 @@ static const uint32_t g_transpeedru[8] = 10000, /* 0: 10 Kbit/sec / 10 */ 100000, /* 1: 1 Mbit/sec / 10 */ 1000000, /* 2: 10 Mbit/sec / 10 */ - 10000000, /* 3: 100 Mbit/sec / 10*/ + 10000000, /* 3: 100 Mbit/sec / 10 */ 0, 0, 0, 0 /* 4-7: Reserved values */ }; @@ -316,7 +308,7 @@ static const uint16_t g_taactu[8] = 1, /* 3: 1 us 1,000 ns */ 10, /* 4: 10 us 10,000 ns */ 100, /* 5: 100 us 100,000 ns */ - 1000, /* 6: 1 ms 1,000,000 ns*/ + 1000, /* 6: 1 ms 1,000,000 ns */ 10000, /* 7: 10 ms 10,000,000 ns */ }; @@ -358,17 +350,16 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot) { /* Get exclusive access to the SPI bus (if necessary) */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(slot->spi, true); /* Set the frequency, bit width and mode, as some other driver could have * changed those since the last time that we had the SPI bus. */ - SPI_SETFREQUENCY(slot->spi, slot->spispeed); SPI_SETMODE(slot->spi, CONFIG_MMCSD_SPIMODE); SPI_SETBITS(slot->spi, 8); -#endif + (void)SPI_HWFEATURES(slot->spi, 0); + (void)SPI_SETFREQUENCY(slot->spi, slot->spispeed); /* Get exclusive access to the MMC/SD device (possibly unnecessary if * SPI_LOCK is also implemented as a semaphore). @@ -396,7 +387,6 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot) /* Relinquish the lock on the SPI bus */ -#ifndef CONFIG_SPI_OWNBUS /* The card may need up to 8 SCLK cycles to sample the CS status * and release the MISO line. */ @@ -406,27 +396,7 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot) /* Relinquish exclusive access to the SPI bus */ (void)SPI_LOCK(slot->spi, false); -#endif -} - -/**************************************************************************** - * Name: mmcsd_spiinit - * - * Description: - * Set SPI mode and data width. - * - * Assumptions: - * MMC/SD card already selected - * - ****************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void mmcsd_spiinit(FAR struct mmcsd_slot_s *slot) -{ - SPI_SETMODE(slot->spi, CONFIG_MMCSD_SPIMODE); - SPI_SETBITS(slot->spi, 8); } -#endif /**************************************************************************** * Name: mmcsd_waitready @@ -443,8 +413,8 @@ static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot) { FAR struct spi_dev_s *spi = slot->spi; uint8_t response; - uint32_t start; - uint32_t elapsed; + systime_t start; + systime_t elapsed; /* Wait until the card is no longer busy (up to 500MS) */ @@ -548,8 +518,8 @@ static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot, case MMCSD_CMDRESP_R1B: { uint32_t busy = 0; - uint32_t start; - uint32_t elapsed; + systime_t start; + systime_t elapsed; start = START_TIME; do @@ -677,7 +647,7 @@ static uint32_t mmcsd_taac(FAR struct mmcsd_slot_s *slot, uint8_t *csd) { int tundx; - /*The TAAC consists of a 3-bit time unit (TU) and a 4-bit time value (TV). + /* The TAAC consists of a 3-bit time unit (TU) and a 4-bit time value (TV). * TAAC is in units of time; NSAC is in units of SPI clocks. * The access time we need is then given by: * @@ -736,9 +706,7 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd) /* Set the actual SPI frequency as close as possible to the max frequency */ -#ifndef CONFIG_SPI_OWNBUS slot->spispeed = frequency; -#endif frequency = SPI_SETFREQUENCY(spi, frequency); /* Now determine the delay to access data */ @@ -963,9 +931,9 @@ static int mmcsd_recvblock(FAR struct mmcsd_slot_s *slot, uint8_t *buffer, int nbytes) { FAR struct spi_dev_s *spi = slot->spi; - uint32_t start; - uint32_t elapsed; - uint8_t token; + systime_t start; + systime_t elapsed; + uint8_t token; /* Wait up to the maximum to receive a valid data token. taccess is the * time from when the command is sent until the first byte of data is @@ -1532,7 +1500,7 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry) /* Then return the card geometry */ geometry->geo_available = - ((slot->state & (MMCSD_SLOTSTATUS_NOTREADY|MMCSD_SLOTSTATUS_NODISK)) == 0); + ((slot->state & (MMCSD_SLOTSTATUS_NOTREADY | MMCSD_SLOTSTATUS_NODISK)) == 0); geometry->geo_mediachanged = ((slot->state & MMCSD_SLOTSTATUS_MEDIACHGD) != 0); #if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY) @@ -1579,8 +1547,8 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) FAR struct spi_dev_s *spi = slot->spi; uint8_t csd[16]; uint32_t result = MMCSD_SPIR1_IDLESTATE; - uint32_t start; - uint32_t elapsed; + systime_t start; + systime_t elapsed; int i; int j; @@ -1605,10 +1573,8 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) /* Clock Freq. Identification Mode < 400kHz */ -#ifndef CONFIG_SPI_OWNBUS slot->spispeed = MMCSD_IDMODE_CLOCK; -#endif - SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK); + (void)SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK); /* Set the maximum access time out */ @@ -1713,7 +1679,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) if ((slot->ocr & MMCSD_OCR_CCS) != 0) { fdbg("Identified SD ver2 card/with block access\n"); - slot->type = MMCSD_CARDTYPE_SDV2|MMCSD_CARDTYPE_BLOCK; + slot->type = MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK; } else { @@ -1862,7 +1828,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) static void mmcsd_mediachanged(void *arg) { - struct mmcsd_slot_s *slot = (struct mmcsd_slot_s*)arg; + FAR struct mmcsd_slot_s *slot = (FAR struct mmcsd_slot_s *)arg; FAR struct spi_dev_s *spi; uint8_t oldstate; int ret; @@ -1892,7 +1858,7 @@ static void mmcsd_mediachanged(void *arg) /* Media is not present */ fdbg("No card present\n"); - slot->state |= (MMCSD_SLOTSTATUS_NODISK|MMCSD_SLOTSTATUS_NOTREADY); + slot->state |= (MMCSD_SLOTSTATUS_NODISK | MMCSD_SLOTSTATUS_NOTREADY); /* Was media removed? */ @@ -1906,7 +1872,7 @@ static void mmcsd_mediachanged(void *arg) * ready, then try re-initializing it */ - else if ((oldstate & (MMCSD_SLOTSTATUS_NODISK|MMCSD_SLOTSTATUS_NOTREADY)) != 0) + else if ((oldstate & (MMCSD_SLOTSTATUS_NODISK | MMCSD_SLOTSTATUS_NOTREADY)) != 0) { /* (Re-)initialize for the media in the slot */ @@ -1937,8 +1903,9 @@ static void mmcsd_mediachanged(void *arg) * slotno - The slot number to use. This is only meaningful for * architectures that support multiple MMC/SD slots. This value must be * in the range {0, ..., CONFIG_MMCSD_NSLOTS}. - * spi - And instance of an SPI interface obtained by called - * up_spiinitialize() with the appropriate port number (see spi.h) + * spi - And instance of an SPI interface obtained by called the + * approprite xyz_spibus_initialize() function for the MCU "xyz" with + * the appropriate port number. * ****************************************************************************/ @@ -1972,17 +1939,14 @@ int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi) /* Bind the SPI port to the slot */ - slot->spi = spi; -#ifndef CONFIG_SPI_OWNBUS + slot->spi = spi; slot->spispeed = MMCSD_IDMODE_CLOCK; -#endif /* Get exclusive access to the SPI bus and make sure that SPI is properly * configured for the MMC/SD card */ mmcsd_semtake(slot); - mmcsd_spiinit(slot); /* Initialize for the media in the slot (if any) */ @@ -2014,7 +1978,7 @@ int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi) * removal of cards. */ - (void)SPI_REGISTERCALLBACK(spi, mmcsd_mediachanged, (void*)slot); + (void)SPI_REGISTERCALLBACK(spi, mmcsd_mediachanged, (FAR void *)slot); return OK; } diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bfc7568612e80acfbaf3a7d2231b420c56c80967 --- /dev/null +++ b/drivers/modem/Kconfig @@ -0,0 +1,20 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config MODEM_U_BLOX + bool "Enable u-blox modem driver" + default n + ---help--- + Compile the u-blox serial modem driver. The driver consists of + the upper half in the OS and the lower half with implementation + in the chosen board. + +config MODEM_U_BLOX_DEBUG + bool "Debug u-blox modem driver" + default n + depends on MODEM_U_BLOX + ---help--- + Allow the u-blox modem driver print debug information. + diff --git a/drivers/modem/Make.defs b/drivers/modem/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..6916f46fa2af3ec049f5cb30e429e5ab6a9ddac0 --- /dev/null +++ b/drivers/modem/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# drivers/modem/Make.defs +# +# Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. +# Author: Vladimir Komendantskiy +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_MODEM),y) + +ifeq ($(CONFIG_MODEM_U_BLOX),y) +CSRCS += u-blox.c +endif + +# Include modem driver build support + +DEPPATH += --dep-path modem +VPATH += :modem +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)modem} + +endif diff --git a/drivers/modem/u-blox.c b/drivers/modem/u-blox.c new file mode 100644 index 0000000000000000000000000000000000000000..05e4453ba963f077f2116cd298656a568d07cbdc --- /dev/null +++ b/drivers/modem/u-blox.c @@ -0,0 +1,338 @@ +/**************************************************************************** + * drivers/modem/u-blox.c + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the modem driver */ + +#ifdef CONFIG_MODEM_U_BLOX_DEBUG +# define m_dbg dbg +# define m_vdbg vdbg +# define m_vlldbg lldbg +# define m_vllvdbg llvdbg +#else +# define m_dbg(x...) +# define m_vdbg(x...) +# define m_lldbg(x...) +# define m_llvdbg(x...) +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* The type of upper half driver state. */ + +struct ubxmdm_upper +{ + FAR char* path; /* Registration path */ + + /* The contained lower-half driver. */ + + FAR struct ubxmdm_lower* lower; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t ubxmdm_read (FAR struct file* filep, + FAR char* buffer, + size_t buflen); +static ssize_t ubxmdm_write(FAR struct file* filep, + FAR const char* buffer, + size_t buflen); +static int ubxmdm_ioctl(FAR struct file* filep, + int cmd, + unsigned long arg); + +#ifndef CONFIG_DISABLE_POLL +static int ubxmdm_poll (FAR struct file* filep, + FAR struct pollfd* fds, + bool setup); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations ubxmdm_fops = +{ + 0, /* open */ + 0, /* close */ + ubxmdm_read, /* read */ + ubxmdm_write, /* write */ + 0, /* seek */ + ubxmdm_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + ubxmdm_poll, /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static ssize_t ubxmdm_read(FAR struct file* filep, + FAR char* buffer, + size_t len) +{ + return 0; /* Return EOF */ +} + +static ssize_t ubxmdm_write(FAR struct file* filep, + FAR const char* buffer, + size_t len) +{ + return len; /* Say that everything was written */ +} + +static int ubxmdm_ioctl(FAR struct file* filep, + int cmd, + unsigned long arg) +{ + FAR struct inode* inode = filep->f_inode; + FAR struct ubxmdm_upper* upper = inode->i_private; + FAR struct ubxmdm_lower* lower = upper->lower; + int ret; + FAR struct ubxmdm_status* status; + + m_vdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(upper && lower); + + switch (cmd) + { + /* cmd: UBXMDM_IOC_START + * Description: + * arg: Ignored + */ + + case MODEM_IOC_POWERON: + if (lower->ops->poweron) + { + ret = lower->ops->poweron(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_STOP + * Description: + * arg: Ignored + */ + + case MODEM_IOC_POWEROFF: + if (lower->ops->poweroff) + { + ret = lower->ops->poweroff(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_RESET + * Description: + * arg: Ignored + */ + + case MODEM_IOC_RESET: + if (lower->ops->reset) + { + ret = lower->ops->reset(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_GETSTATUS + * Description: + * arg: Writeable pointer to struct ubxmdm_status. + */ + + case MODEM_IOC_GETSTATUS: + if (lower->ops->getstatus) + { + status = (FAR struct ubxmdm_status*) ((uintptr_t) arg); + if (status) + { + ret = lower->ops->getstatus(lower, status); + } + else + { + ret = -EINVAL; + } + } + else + { + ret = -ENOSYS; + } + + break; + + /* Unrecognized IOCTL commands are forwarded to the lower-half IOCTL + * handler, if defined. + */ + + default: + m_vdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg); + + if (lower->ops->ioctl) + { + ret = lower->ops->ioctl(lower, cmd, arg); + } + else + { + ret = -ENOSYS; + } + + break; + } + + return ret; +} + +#ifndef CONFIG_DISABLE_POLL +static int ubxmdm_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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR void* ubxmdm_register(FAR const char *path, + FAR struct ubxmdm_lower *lower) +{ + FAR struct ubxmdm_upper *upper; + int ret; + + DEBUGASSERT(path && lower); + + upper = (FAR struct ubxmdm_upper*) + kmm_zalloc(sizeof(struct ubxmdm_upper)); + if (!upper) + { + m_dbg("Upper half allocation failed\n"); + goto errout; + } + + upper->lower = lower; + upper->path = strdup(path); + if (!upper->path) + { + m_dbg("Path allocation failed\n"); + goto errout_with_upper; + } + + ret = register_driver(path, &ubxmdm_fops, 0666, upper); + if (ret < 0) + { + m_dbg("register_driver failed: %d\n", ret); + goto errout_with_path; + } + + return (FAR void*) upper; + +errout_with_path: + kmm_free(upper->path); + +errout_with_upper: + kmm_free(upper); + +errout: + return NULL; +} + +void ubxmdm_unregister(FAR void *handle) +{ + FAR struct ubxmdm_upper *upper; + FAR struct ubxmdm_lower *lower; + + upper = (FAR struct ubxmdm_upper*) handle; + lower = upper->lower; + DEBUGASSERT(upper && lower); + + m_vdbg("Unregistering: %s\n", upper->path); + + DEBUGASSERT(lower->ops->poweroff); + (void) lower->ops->poweroff(lower); + + (void) unregister_driver(upper->path); + + kmm_free(upper->path); + kmm_free(upper); +} diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index cf912b3ca53409adb2aa2661bc228b1a254d84da..5f04bccd606ed4dab6177d45151d856779c80fbe 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -114,6 +114,14 @@ config MTD_NRDBLOCKS endif # MTD_READAHEAD +config MTD_PROGMEM + bool "Enable on-chip program FLASH MTD device" + default n + ---help--- + Enable to support an MTD device that supports the on-chip FLASH + using the interfaces defined in include/nuttx/progmem. Those + interfaces must be exported by chip-specific logic. + config MTD_CONFIG bool "Enable Dev Config (MTD based) device" default n @@ -260,6 +268,28 @@ config RAMMTD_FLASHSIM endif +config FILEMTD + bool "File-based MTD driver" + default n + ---help--- + Build support for a File-based MTD driver. + +if FILEMTD + +config FILEMTD_BLOCKSIZE + int "File MTD block size" + default 512 + +config FILEMTD_ERASESIZE + int "File MTD erase block size" + default 4096 + +config FILEMTD_ERASESTATE + hex "Simulated erase state" + default 0xff + +endif + config MTD_AT24XX bool "I2C-based AT24xx eeprom" default n @@ -270,6 +300,15 @@ config MTD_AT24XX if MTD_AT24XX +config AT24XX_MULTI + bool "Multiple AT24XX devices" + default n + ---help--- + Build in additional support for multiple AT24XX devices, each with + dynamically allocated device structures wiath a separate I2C + addresses (but otherwise identical -- support for multiple, different + AT24xx, devices not yet supported). + config AT24XX_SIZE int "AT24xx size (Kbit)" default 64 @@ -283,6 +322,7 @@ config AT24XX_ADDR hex "AT24XX I2C address" default 0x50 range 0x50 0x57 + depends on !AT24XX_MULTI ---help--- The I2C address of the FLASH part. This is should be 0b01010aaa (where aaa is determined by board/pin configuration). @@ -309,6 +349,14 @@ config AT24XX_EXTSIZE Other, block-oriented access are not effected by this setting +config AT24XX_FREQUENCY + int "AT24xx I2C bus frequency" + default 100000 + ---help--- + Set the I2C frequency to use when accessing the AT24CXX EEPROM. This value + must represent a valid I2C speed (normally less than 400.000) or the driver + might fail. + endif config MTD_AT25 @@ -360,6 +408,10 @@ config M25P_SPIMODE int "M25P SPI mode" default 0 +config M25P_SPIFREQUENCY + int "M25P SPI Frequency" + default 20000000 + config M25P_MANUFACTURER hex "M25P manufacturers ID" default 0x20 @@ -387,6 +439,58 @@ config M25P_SUBSECTOR_ERASE endif +config MTD_S25FL1 + bool "QuadSPI-based S25FL1 FLASH" + default n + +if MTD_S25FL1 + +config S25FL1_QSPIMODE + int "S25FL1 QuadSPI Mode" + default 0 + +config S25FL1_QSPI_FREQUENCY + int "S25FL1 QuadSPI Frequency" + default 108000000 + ---help--- + Per data sheet: + – Normal Read (Serial): + – 50 MHz clock rate (-40°C to +85°C/105°C) + – 45 MHz clock rate (-40°C to +125°C) + – Fast Read (Serial): + – 108 MHz clock rate (-40°C to +85°C/105°C) + – 97 MHz clock rate (-40°C to +125°C) + – Dual Read: + – 108 MHz clock rate (-40°C to +85°C/105°C) + – 97 MHz clock rate (-40°C to +125°C) + – Quad Read: + – 108 MHz clock rate (-40°C to +85°C/105°C) + – 97 MHz clock rate for S25FL164K (-40°C to +125°C) + + - Clock frequency for all SPI commands except for Read Data + command (0x03) and Fast Read command (0x0b): 108 MHz + - Clock frequency for Read Data command (0x03): 50 MHz + - Clock frequency for all Fast Read commands SIO and MIO: 108 MHz + + In this implementation, only "Quad" reads are performed. + +config S25FL1_SECTOR512 + bool "Simulate 512 byte Erase Blocks" + default n + +config S25FL1_SCRAMBLE + bool "Scramble data" + default n + ---help--- + Requires drviver support for data scrambling/descrambling. + +config S25FL1_SCRAMBLE_KEY + hex "Scramble key" + default 0x0baddead + depends on S25FL1_SCRAMBLE + +endif + config MTD_SMART bool "Sector Mapped Allocation for Really Tiny (SMART) Flash support" default n @@ -401,6 +505,14 @@ config MTD_SMART if MTD_SMART +config SMART_DEV_LOOP + bool "Enable SMART loop device" + select FILEMTD + default n + ---help--- + Supports a smart loop device that can be used to export a + file (or character device) as a SMART block device. + config MTD_SMART_SECTOR_SIZE int "SMART Device sector size" default 1024 diff --git a/drivers/mtd/Make.defs b/drivers/mtd/Make.defs index ff1b899d99a926f39641adbf0c550e466499bb2c..fdd77d3610b3ca19d7c9302ee1fc6f75090024f0 100644 --- a/drivers/mtd/Make.defs +++ b/drivers/mtd/Make.defs @@ -3,7 +3,7 @@ # These driver supports various Memory Technology Devices (MTD) using the # NuttX MTD interface. # -# Copyright (C) 2009-2013 Gregory Nutt. All rights reserved. +# Copyright (C) 2009-2013, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -57,6 +57,10 @@ CSRCS += mtd_rwbuffer.c endif endif +ifeq ($(CONFIG_MTD_PROGMEM),y) +CSRCS += mtd_progmem.c +endif + ifeq ($(CONFIG_MTD_NAND),y) CSRCS += mtd_nand.c mtd_onfi.c mtd_nandscheme.c mtd_nandmodel.c mtd_modeltab.c ifeq ($(CONFIG_MTD_NAND_SWECC),y) @@ -68,6 +72,10 @@ ifeq ($(CONFIG_RAMMTD),y) CSRCS += rammtd.c endif +ifeq ($(CONFIG_FILEMTD),y) +CSRCS += filemtd.c +endif + ifeq ($(CONFIG_MTD_AT24XX),y) CSRCS += at24xx.c endif @@ -92,6 +100,10 @@ ifeq ($(CONFIG_MTD_AT25),y) CSRCS += at25.c endif +ifeq ($(CONFIG_MTD_S25FL1),y) +CSRCS += s25fl1.c +endif + ifeq ($(CONFIG_MTD_SMART),y) ifeq ($(CONFIG_FS_SMARTFS),y) CSRCS += smart.c diff --git a/drivers/mtd/at24xx.c b/drivers/mtd/at24xx.c index fbb56b7108849938384b6af92f9e15a0f92d01ee..76d2cf2659341ab54208212f18f5fe01f4350960 100644 --- a/drivers/mtd/at24xx.c +++ b/drivers/mtd/at24xx.c @@ -4,9 +4,9 @@ * * Copyright (C) 2011 Li Zhuoyi. All rights reserved. * Author: Li Zhuoyi - * History: 0.1 2011-08-20 initial version * - * 2011-11-1 Added support for larger MTD block sizes: Hal Glenn + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * Derived from drivers/mtd/m25px.c * @@ -59,7 +59,7 @@ #include #include -#include +#include #include #ifdef CONFIG_MTD_AT24XX @@ -74,17 +74,33 @@ # warning "Assuming AT24 size 64" # define CONFIG_AT24XX_SIZE 64 #endif -#ifndef CONFIG_AT24XX_ADDR -# warning "Assuming AT24 address of 0x50" +#if !defined(CONFIG_AT24XX_ADDR) && !defined(CONFIG_AT24XX_MULTI) +# warning "Assuming AT24 I2C address of 0x50" # define CONFIG_AT24XX_ADDR 0x50 #endif +#ifndef CONFIG_AT24XX_FREQUENCY +# warning "Assuming AT24 I2C frequency of 100KHz" +# define CONFIG_AT24XX_FREQUENCY 100000 +#endif /* Get the part configuration based on the size configuration */ -#if CONFIG_AT24XX_SIZE == 2 /* AT24C32: 2Kbits = 256; 16 * 16 = 256 */ +#if CONFIG_AT24XX_SIZE == 2 /* AT24C02: 2Kbits = 256; 16 * 16 = 256 */ # define AT24XX_NPAGES 16 # define AT24XX_PAGESIZE 16 # define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 4 /* AT24C04: 4Kbits = 512B; 32 * 16 = 512 */ +# define AT24XX_NPAGES 32 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 8 /* AT24C08: 8Kbits = 1KiB; 64 * 16 = 1024 */ +# define AT24XX_NPAGES 64 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 16 /* AT24C16: 16Kbits = 2KiB; 128 * 16 = 2048 */ +# define AT24XX_NPAGES 128 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 #elif CONFIG_AT24XX_SIZE == 32 /* AT24C32: 32Kbits = 4KiB; 128 * 32 = 4096 */ # define AT24XX_NPAGES 128 # define AT24XX_PAGESIZE 32 @@ -119,7 +135,7 @@ */ #ifndef CONFIG_AT24XX_MTD_BLOCKSIZE -# warning "Assuming driver block size is the same as the FLASH page size" +# warning "Assuming MTD driver block size is the same as the FLASH page size" # define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE #endif @@ -134,15 +150,15 @@ struct at24c_dev_s { - struct mtd_dev_s mtd; /* MTD interface */ - FAR struct i2c_dev_s *dev; /* Saved I2C interface instance */ - bool initd; /* True: The device has been initialize */ + struct mtd_dev_s mtd; /* MTD interface */ + FAR struct i2c_master_s *dev; /* Saved I2C interface instance */ + bool initd; /* True: The device has been initialize */ #ifdef CONFIG_AT24XX_EXTENDED - bool extended; /* True: use extended memory region */ + bool extended; /* True: use extended memory region */ #endif - uint8_t addr; /* I2C address */ - uint16_t pagesize; /* 32, 63 */ - uint16_t npages; /* 128, 256, 512, 1024 */ + uint8_t addr; /* I2C address */ + uint16_t pagesize; /* 32, 63 */ + uint16_t npages; /* 128, 256, 512, 1024 */ }; /************************************************************************************ @@ -164,41 +180,101 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); * Private Data ************************************************************************************/ -/* At present, only a signal AT24 part is supported. In this case, a statically - * allocated state structure may be used. +#ifndef CONFIG_AT24XX_MULTI +/* If only a signal AT24 part is supported then a statically allocated state + * structure may be used. */ static struct at24c_dev_s g_at24c; +#endif /************************************************************************************ * Private Functions ************************************************************************************/ +/**************************************************************************** + * Name: at24c_i2c_write + * + * Description: + * Write to the I2C device. + * + ****************************************************************************/ + +static int at24c_i2c_write(FAR struct at24c_dev_s *priv, uint16_t at24addr, + FAR const uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_AT24XX_FREQUENCY, + msg.addr = at24addr; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->dev, &msg, 1); +} + +/**************************************************************************** + * Name: at24c_i2c_read + * + * Description: + * Read from the I2C device. + * + ****************************************************************************/ + +static int at24c_i2c_read(FAR struct at24c_dev_s *priv, uint16_t at24addr, + FAR uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_AT24XX_FREQUENCY, + msg.addr = at24addr, + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->dev, &msg, 1); +} + +/************************************************************************************ + * Name: at24c_eraseall + ************************************************************************************/ + static int at24c_eraseall(FAR struct at24c_dev_s *priv) { - int startblock = 0; uint8_t buf[AT24XX_PAGESIZE + AT24XX_ADDRSIZE]; + int startblock = 0; memset(&buf[AT24XX_ADDRSIZE], 0xff, priv->pagesize); - I2C_SETADDRESS(priv->dev, priv->addr, 7); - I2C_SETFREQUENCY(priv->dev, 100000); for (startblock = 0; startblock < priv->npages; startblock++) { -#if AT24XX_ADDRSIZE == 2 uint16_t offset = startblock * priv->pagesize; - buf[1] = offset & 0xff; - buf[0] = (offset >> 8) & 0xff; + uint16_t at24addr; + +#if AT24XX_ADDRSIZE == 2 + buf[1] = offset & 0xff; + buf[0] = (offset >> 8) & 0xff; + at24addr = priv->addr; #else - buf[0] = startblock * priv->pagesize; + buf[0] = offset & 0xff; + at24addr = (priv->addr | ((offset >> 8) & 0x07)); #endif - while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) + while (at24c_i2c_write(priv, at24addr, buf, AT24XX_ADDRSIZE) < 0) { usleep(1000); } - I2C_WRITE(priv->dev, buf, AT24XX_PAGESIZE + AT24XX_ADDRSIZE); + at24c_i2c_write(priv, at24addr, buf, AT24XX_PAGESIZE + AT24XX_ADDRSIZE); } return OK; @@ -224,13 +300,11 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, uint8_t address) { uint8_t buf[AT24XX_ADDRSIZE]; + uint16_t at24addr; fvdbg("offset: %lu nbytes: %lu address: %02x\n", (unsigned long)offset, (unsigned long)nbytes, address); - I2C_SETADDRESS(priv->dev, address, 7); - I2C_SETFREQUENCY(priv->dev, 100000); - /* "Random Read: A Random Read requires a dummy byte write sequence to load in the * data word address. Once the device address word and data word address are clocked * in and acknowledged by the EEPROM, the microcontroller must generate another @@ -245,13 +319,15 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, */ #if AT24XX_ADDRSIZE == 2 - buf[1] = offset & 0xff; - buf[0] = (offset >> 8) & 0xff; + buf[1] = offset & 0xff; + buf[0] = (offset >> 8) & 0xff; + at24addr = address; #else - buf[0] = (uint8_t)offset; + buf[0] = offset & 0xff; + at24addr = (address | ((offset >> 8) & 0x07)); #endif - while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) + while (at24c_i2c_write(priv, at24addr, buf, AT24XX_ADDRSIZE) < 0) { fvdbg("wait\n"); usleep(1000); @@ -259,7 +335,7 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, /* Then transfer the following bytes */ - I2C_READ(priv->dev, buffer, nbytes); + at24c_i2c_read(priv, at24addr, buffer, nbytes); return nbytes; } @@ -311,6 +387,7 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, } offset += priv->pagesize; + buffer += priv->pagesize; } #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE @@ -351,20 +428,22 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t } fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - I2C_SETADDRESS(priv->dev, priv->addr, 7); - I2C_SETFREQUENCY(priv->dev, 100000); while (blocksleft-- > 0) { -#if AT24XX_ADDRSIZE uint16_t offset = startblock * priv->pagesize; - buf[1] = offset & 0xff; - buf[0] = (offset >> 8) & 0xff; + uint16_t at24addr; + +#if AT24XX_ADDRSIZE == 2 + buf[1] = offset & 0xff; + buf[0] = (offset >> 8) & 0xff; + at24addr = priv->addr; #else - buf[0] = startblock * priv->pagesize; + buf[0] = offset & 0xff; + at24addr = (priv->addr | ((offset >> 8) & 0x07)); #endif - while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) + while (at24c_i2c_write(priv, at24addr, buf, AT24XX_ADDRSIZE) < 0) { fvdbg("wait\n"); usleep(1000); @@ -372,7 +451,7 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t memcpy(&buf[AT24XX_ADDRSIZE], buffer, priv->pagesize); - I2C_WRITE(priv->dev, buf, priv->pagesize + AT24XX_ADDRSIZE); + at24c_i2c_write(priv, at24addr, buf, priv->pagesize + AT24XX_ADDRSIZE); startblock++; buffer += priv->pagesize; } @@ -516,17 +595,22 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) * Name: at24c_initialize * * Description: - * Create an initialize MTD device instance. MTD devices are not registered + * Create an initialized MTD device instance. MTD devices are not registered * in the file system, but are created as instances that can be bound to * other functions (such as a block or character driver front end). * ************************************************************************************/ -FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev) +#ifdef CONFIG_AT24XX_MULTI +FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev, uint8_t address) +#else +FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev) +#endif { FAR struct at24c_dev_s *priv; - fvdbg("dev: %p\n", dev); +#ifdef CONFIG_AT24XX_MULTI + fvdbg("dev: %p address: %02x\n", dev, address); /* Allocate a state structure (we allocate the structure instead of using * a fixed, static allocation so that we can handle multiple FLASH devices. @@ -535,12 +619,32 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev) * to be extended to handle multiple FLASH parts on the same I2C bus. */ + priv = (FAR struct at24c_dev_s *)kmm_zalloc(sizeof(struct at24c_dev_s)); + if (priv == NULL) + { + fdbg("ERROR: Failed to allocate device structure\n"); + return NULL; + } + +#else + fvdbg("dev: %p\n", dev); + + /* If only a signal AT24 part is supported then a statically allocated state + * structure is used. + */ + priv = &g_at24c; +#endif + if (!priv->initd) { /* Initialize the allocated structure */ +#ifdef CONFIG_AT24XX_MULTI + priv->addr = address; +#else priv->addr = CONFIG_AT24XX_ADDR; +#endif priv->pagesize = AT24XX_PAGESIZE; priv->npages = AT24XX_NPAGES; @@ -569,4 +673,30 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev) return (FAR struct mtd_dev_s *)priv; } +/************************************************************************************ + * Name: at24c_uninitialize + * + * Description: + * Release resources held by an allocated MTD device instance. Resources are only + * allocated for the case where multiple AT24xx devices are support. + * + ************************************************************************************/ + +#ifdef CONFIG_AT24XX_MULTI +void at24c_uninitialize(FAR struct mtd_dev_s *mtd) +{ + FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)mtd; + DEBUGASSERT(priv != NULL); + +#ifdef CONFIG_MTD_REGISTRATION + /* Unregister the MTD with the procfs system if enabled */ + + mtd_unregister(&priv->mtd); +#endif + + /* Free the MTD driver instance */ + + kmm_free(priv); +} +#endif /* CONFIG_AT24XX_MULTI */ #endif /* CONFIG_MTD_AT24XX */ diff --git a/drivers/mtd/at25.c b/drivers/mtd/at25.c index 87b08405a4e003c583fd695124325b28f86172a4..e085ca8b89bb25de7861e981d34942d31f6f202b 100644 --- a/drivers/mtd/at25.c +++ b/drivers/mtd/at25.c @@ -191,6 +191,7 @@ static void at25_lock(FAR struct spi_dev_s *dev) SPI_SETMODE(dev, CONFIG_AT25_SPIMODE); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, CONFIG_AT25_SPIFREQUENCY); } @@ -255,34 +256,6 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv) { uint8_t status; - /* Are we the only device on the bus? */ - -#ifdef CONFIG_SPI_OWNBUS - - /* Select this FLASH part */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, true); - - /* Send "Read Status Register (RDSR)" command */ - - (void)SPI_SEND(priv->dev, AT25_RDSR); - - /* Loop as long as the memory is busy with a write cycle */ - - do - { - /* Send a dummy byte to generate the clock needed to shift out the status */ - - status = SPI_SEND(priv->dev, AT25_DUMMY); - } - while ((status & AT25_SR_BUSY) != 0); - - /* Deselect the FLASH */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, false); - -#else - /* Loop as long as the memory is busy with a write cycle */ do @@ -316,7 +289,6 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv) } } while ((status & AT25_SR_BUSY) != 0); -#endif if (status & AT25_SR_EPE) { diff --git a/drivers/mtd/at45db.c b/drivers/mtd/at45db.c index c9095172a2b023cbd0cbfee435a9de941321f312..a76994d5e4c56e98a016aabca30c0a62386b8f14 100644 --- a/drivers/mtd/at45db.c +++ b/drivers/mtd/at45db.c @@ -251,12 +251,18 @@ static int at45db_ioctl(FAR struct mtd_dev_s *mtd, int cmd, unsigned long arg); /* Chip erase sequence */ #define CHIP_ERASE_SIZE 4 -static const uint8_t g_chiperase[CHIP_ERASE_SIZE] = {0xc7, 0x94, 0x80, 0x9a}; +static const uint8_t g_chiperase[CHIP_ERASE_SIZE] = +{ + 0xc7, 0x94, 0x80, 0x9a +}; /* Sequence to program the device to binary page sizes{256, 512, 1024} */ #define BINPGSIZE_SIZE 4 -static const uint8_t g_binpgsize[BINPGSIZE_SIZE] = {0x3d, 0x2a, 0x80, 0xa6}; +static const uint8_t g_binpgsize[BINPGSIZE_SIZE] = +{ + 0x3d, 0x2a, 0x80, 0xa6 +}; /************************************************************************************ * Private Functions @@ -270,7 +276,7 @@ static void at45db_lock(FAR struct at45db_dev_s *priv) { /* On SPI buses where there are multiple devices, it will be necessary to lock SPI * to have exclusive access to the buses for a sequence of transfers. The bus - & should be locked before the chip is selected. + * should be locked before the chip is selected. * * This is a blocking call and will not return until we have exclusive access to * the SPI bus. We will retain that exclusive access until the bus is unlocked. @@ -286,6 +292,7 @@ static void at45db_lock(FAR struct at45db_dev_s *priv) SPI_SETMODE(priv->spi, SPIDEV_MODE0); SPI_SETBITS(priv->spi, 8); + (void)SPI_HWFEATURES(priv->spi, 0); (void)SPI_SETFREQUENCY(priv->spi, CONFIG_AT45DB_FREQUENCY); } @@ -640,7 +647,7 @@ static ssize_t at45db_bread(FAR struct mtd_dev_s *mtd, off_t startblock, FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd; ssize_t nbytes; - /* On this device, we can handle the block read just like the byte-oriented read */ + /* On this device, we can handle the block read just like the byte-oriented read */ nbytes = at45db_read(mtd, startblock << priv->pageshift, nblocks << priv->pageshift, buffer); diff --git a/drivers/mtd/filemtd.c b/drivers/mtd/filemtd.c new file mode 100644 index 0000000000000000000000000000000000000000..18b2e19e1a9d0a2d85c2b1e3f2cb55695c56cbb8 --- /dev/null +++ b/drivers/mtd/filemtd.c @@ -0,0 +1,639 @@ +/**************************************************************************** + * drivers/mtd/filemtd.c + * + * Copyright (C) 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_FILEMTD_BLOCKSIZE +# define CONFIG_FILEMTD_BLOCKSIZE 512 +#endif + +#ifndef CONFIG_FILEMTD_ERASESIZE +# define CONFIG_FILEMTD_ERASESIZE 4096 +#endif + +#ifndef CONFIG_FILEMTD_ERASESTATE +# define CONFIG_FILEMTD_ERASESTATE 0xff +#endif + +#if CONFIG_FILEMTD_ERASESTATE != 0xff && CONFIG_FILEMTD_ERASESTATE != 0x00 +# error "Unsupported value for CONFIG_FILEMTD_ERASESTATE" +#endif + +#if CONFIG_FILEMTD_BLOCKSIZE > CONFIG_FILEMTD_ERASESIZE +# error "Must have CONFIG_FILEMTD_BLOCKSIZE <= CONFIG_FILEMTD_ERASESIZE" +#endif + +#undef FILEMTD_BLKPER +#define FILEMTD_BLKPER (CONFIG_FILEMTD_ERASESIZE/CONFIG_FILEMTD_BLOCKSIZE) + +#if FILEMTD_BLKPER*CONFIG_FILEMTD_BLOCKSIZE != CONFIG_FILEMTD_ERASESIZE +# error "CONFIG_FILEMTD_ERASESIZE must be an even multiple of CONFIG_FILEMTD_BLOCKSIZE" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type represents the state of the MTD device. The struct mtd_dev_s + * must appear at the beginning of the definition so that you can freely + * cast between pointers to struct mtd_dev_s and struct file_dev_s. + */ + +struct file_dev_s +{ + struct mtd_dev_s mtd; /* MTD device */ + int fd; /* File descriptor of underlying file */ + size_t nblocks; /* Number of erase blocks */ + size_t offset; /* Offset from start of file */ + size_t erasesize; /* Offset from start of file */ + size_t blocksize; /* Offset from start of file */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t filemtd_read(FAR struct file_dev_s *priv, + FAR unsigned char *buffer, size_t offsetbytes, + unsigned int nbytes); +static ssize_t filemtd_write(FAR struct file_dev_s *priv, size_t offset, + FAR const void *src, size_t len); + +/* MTD driver methods */ + +static int file_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t file_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t file_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t file_byteread(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buf); +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t file_bytewrite(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buf); +#endif +static int file_ioctl(FAR struct mtd_dev_s *dev, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: filemtd_write + ****************************************************************************/ + +static ssize_t filemtd_write(FAR struct file_dev_s *priv, size_t offset, + FAR const void *src, size_t len) +{ + FAR const uint8_t *pin = (FAR const uint8_t *)src; + FAR uint8_t *pout; + char buf[128]; + int buflen = 0; + uint8_t oldvalue; + uint8_t srcvalue; + uint8_t newvalue; + size_t seekpos; + + /* Set the starting location in the file */ + + seekpos = priv->offset + offset; + + while (len-- > 0) + { + if (buflen == 0) + { + /* Read more data from the file */ + + lseek(priv->fd, seekpos, SEEK_SET); + buflen = read(priv->fd, buf, sizeof(buf)); + pout = (FAR uint8_t *) buf; + } + + /* Get the source and destination values */ + + oldvalue = *pout; + srcvalue = *pin++; + + /* Get the new destination value, accounting for bits that cannot be + * changes because they are not in the erased state. + */ + +#if CONFIG_FILEMTD_ERASESTATE == 0xff + newvalue = oldvalue & srcvalue; /* We can only clear bits */ +#else /* CONFIG_FILEMTD_ERASESTATE == 0x00 */ + newvalue = oldvalue | srcvalue; /* We can only set bits */ +#endif + + /* Report any attempt to change the value of bits that are not in the + * erased state. + */ + +#ifdef CONFIG_DEBUG + if (newvalue != srcvalue) + { + dbg("ERROR: Bad write: source=%02x dest=%02x result=%02x\n", + srcvalue, oldvalue, newvalue); + } +#endif + + /* Write the modified value to simulated FLASH */ + + *pout++ = newvalue; + buflen--; + + /* If our buffer is full, then seek back to beginning of + * the file and write the buffer contents + */ + + if (buflen == 0) + { + lseek(priv->fd, seekpos, SEEK_SET); + write(priv->fd, buf, sizeof(buf)); + seekpos += sizeof(buf); + } + } + + /* Write remaining bytes */ + + if (buflen != 0) + { + lseek(priv->fd, seekpos, SEEK_SET); + write(priv->fd, buf, sizeof(buf)); + } + + return len; +} + +/**************************************************************************** + * Name: filemtd_read + ****************************************************************************/ + +static ssize_t filemtd_read(FAR struct file_dev_s *priv, + FAR unsigned char *buffer, size_t offsetbytes, + unsigned int nbytes) +{ + /* Set the starting location in the file */ + + lseek(priv->fd, priv->offset + offsetbytes, SEEK_SET); + + return read(priv->fd, buffer, nbytes); +} + +/**************************************************************************** + * Name: file_erase + ****************************************************************************/ + +static int file_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + size_t nbytes; + size_t offset; + char buffer[128]; + + DEBUGASSERT(dev); + + /* Don't let the erase exceed the original size of the file */ + + if (startblock >= priv->nblocks) + { + return 0; + } + + if (startblock + nblocks > priv->nblocks) + { + nblocks = priv->nblocks - startblock; + } + + /* Convert the erase block to a logical block and the number of blocks + * in logical block numbers + */ + + startblock *= FILEMTD_BLKPER; + nblocks *= FILEMTD_BLKPER; + + /* Get the offset corresponding to the first block and the size + * corresponding to the number of blocks. + */ + + offset = startblock * priv->blocksize; + nbytes = nblocks * priv->blocksize; + + /* Then erase the data in the file */ + + lseek(priv->fd, priv->offset + offset, SEEK_SET); + memset(buffer, CONFIG_FILEMTD_ERASESTATE, sizeof(buffer)); + while (nbytes) + { + write(priv->fd, buffer, sizeof(buffer)); + nbytes -= sizeof(buffer); + } + + return OK; +} + +/**************************************************************************** + * Name: file_bread + ****************************************************************************/ + +static ssize_t file_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + off_t offset; + off_t maxblock; + size_t nbytes; + + DEBUGASSERT(dev && buf); + + /* Don't let the read exceed the original size of the file */ + + maxblock = priv->nblocks * FILEMTD_BLKPER; + if (startblock >= maxblock) + { + return 0; + } + + if (startblock + nblocks > maxblock) + { + nblocks = maxblock - startblock; + } + + /* Get the offset corresponding to the first block and the size + * corresponding to the number of blocks. + */ + + offset = startblock * priv->blocksize; + nbytes = nblocks * priv->blocksize; + + /* Then read the data from the file */ + + filemtd_read(priv, buf, offset, nbytes); + return nblocks; +} + +/**************************************************************************** + * Name: file_bwrite + ****************************************************************************/ + +static ssize_t file_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + off_t offset; + off_t maxblock; + size_t nbytes; + + DEBUGASSERT(dev && buf); + + /* Don't let the write exceed the original size of the file */ + + maxblock = priv->nblocks * FILEMTD_BLKPER; + if (startblock >= maxblock) + { + return 0; + } + + if (startblock + nblocks > maxblock) + { + nblocks = maxblock - startblock; + } + + /* Get the offset corresponding to the first block and the size + * corresponding to the number of blocks. + */ + + offset = startblock * priv->blocksize; + nbytes = nblocks * priv->blocksize; + + /* Then write the data to the file */ + + filemtd_write(priv, offset, buf, nbytes); + return nblocks; +} + +/**************************************************************************** + * Name: file_byteread + ****************************************************************************/ + +static ssize_t file_byteread(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buf) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + + DEBUGASSERT(dev && buf); + + /* Don't let read read past end of buffer */ + + if (offset + nbytes > priv->nblocks * priv->erasesize) + { + return 0; + } + + filemtd_read(priv, buf, offset, nbytes); + return nbytes; +} + +/**************************************************************************** + * Name: file_bytewrite + ****************************************************************************/ + +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t file_bytewrite(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buf) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + off_t maxoffset; + + DEBUGASSERT(dev && buf); + + /* Don't let the write exceed the original size of the file */ + + maxoffset = priv->nblocks * priv->erasesize; + if (offset + nbytes > maxoffset) + { + return 0; + } + + /* Then write the data to the file */ + + filemtd_write(priv, offset, buf, nbytes); + return nbytes; +} +#endif + +/**************************************************************************** + * Name: file_ioctl + ****************************************************************************/ + +static int file_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = + (FAR struct mtd_geometry_s *)((uintptr_t)arg); + + if (geo) + { + /* Populate the geometry structure with information need to know + * the capacity and how to access the device. + */ + + geo->blocksize = priv->blocksize; + geo->erasesize = priv->erasesize; + geo->neraseblocks = priv->nblocks; + ret = OK; + } + } + break; + + case MTDIOC_XIPBASE: + ret = -ENOTTY; /* Bad command */ + break; + + case MTDIOC_BULKERASE: + { + /* Erase the entire device */ + + file_erase(dev, 0, priv->nblocks); + ret = OK; + } + break; + + default: + ret = -ENOTTY; /* Bad command */ + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: filemtd_initialize + * + * Description: + * Create and initialize a FILE MTD device instance. + * + * Input Parameters: + * path - Path name of the file backing the MTD device + * + ****************************************************************************/ + +FAR struct mtd_dev_s *filemtd_initialize(FAR const char *path, size_t offset, + int16_t sectsize, int32_t erasesize) +{ + FAR struct file_dev_s *priv; + struct stat sb; + size_t nblocks; + size_t filelen; + int mode, ret; + + /* Create an instance of the FILE MTD device state structure */ + + priv = (FAR struct file_dev_s *)kmm_zalloc(sizeof(struct file_dev_s)); + if (!priv) + { + fdbg("Failed to allocate the FILE MTD state structure\n"); + return NULL; + } + + /* Determine the file open mode */ + + mode = O_RDOK; +#ifdef CONFIG_FS_WRITABLE + mode |= O_WROK; +#endif + + /* Stat the file */ + + ret = stat(path, &sb); + if (ret < 0) + { + dbg("Failed to stat %s: %d\n", path, get_errno()); + return NULL; + } + + filelen = sb.st_size; + + /* Try to open the file */ + + priv->fd = open(path, mode); + if (priv->fd == -1) + { + fdbg("Failed to open the FILE MTD file %s\n", path); + kmm_free(priv); + return NULL; + } + + /* Set the block size based on the provided sectsize parameter */ + + if (sectsize <= 0) + { + priv->blocksize = CONFIG_FILEMTD_BLOCKSIZE; + } + else + { + priv->blocksize = sectsize; + } + + /* Set the erase size based on the provided erasesize parameter */ + + if (erasesize <= 0) + { + priv->erasesize = CONFIG_FILEMTD_ERASESIZE; + } + else + { + priv->erasesize = erasesize; + } + + /* Force the size to be an even number of the erase block size */ + + nblocks = (filelen - offset) / priv->erasesize; + if (nblocks < 3) + { + fdbg("Need to provide at least three full erase block\n"); + kmm_free(priv); + return NULL; + } + + /* Perform initialization as necessary. (unsupported methods were + * nullified by kmm_zalloc). + */ + + priv->mtd.erase = file_erase; + priv->mtd.bread = file_bread; + priv->mtd.bwrite = file_bwrite; + priv->mtd.read = file_byteread; +#ifdef CONFIG_MTD_BYTE_WRITE + priv->mtd.write = file_bytewrite; +#endif + priv->mtd.ioctl = file_ioctl; + priv->offset = offset; + priv->nblocks = nblocks; + + /* Register the MTD with the procfs system if enabled */ + +#ifdef CONFIG_MTD_REGISTRATION + mtd_register(&priv->mtd, "filemtd"); +#endif + + return &priv->mtd; +} + +/**************************************************************************** + * Name: filemtd_teardown + * + * Description: + * Teardown a previously created filemtd device. + * + * Input Parameters: + * path - Path name of the file backing the MTD device + * + ****************************************************************************/ + +void filemtd_teardown(FAR struct mtd_dev_s *dev) +{ + FAR struct file_dev_s *priv; + + /* Close the enclosed file */ + + priv = (FAR struct file_dev_s *) dev; + close(priv->fd); + + /* Register the MTD with the procfs system if enabled */ + +#ifdef CONFIG_MTD_REGISTRATION + mtd_unregister(&priv->mtd); +#endif + + /* Free the memory */ + + kmm_free(priv); +} + +/**************************************************************************** + * Name: filemtd_isfilemtd + * + * Description: + * Tests if the provided mtd is a filemtd device. + * + * Input Parameters: + * mtd - Pointer to the mtd. + * + ****************************************************************************/ + +bool filemtd_isfilemtd(FAR struct mtd_dev_s *dev) +{ + FAR struct file_dev_s *priv = (FAR struct file_dev_s *) dev; + + if (priv->mtd.erase == file_erase) + return 1; + + return 0; +} diff --git a/drivers/mtd/flash_eraseall.c b/drivers/mtd/flash_eraseall.c index e09f3cfacbe89ddd4d3c641d9831a6d0ef721795..185da7695c071f9706e6d67221b1543f4b580ee3 100644 --- a/drivers/mtd/flash_eraseall.c +++ b/drivers/mtd/flash_eraseall.c @@ -87,7 +87,7 @@ int flash_eraseall(FAR const char *driver) /* Open the block driver */ - ret = open_blockdriver(driver ,0, &inode); + ret = open_blockdriver(driver, 0, &inode); if (ret < 0) { fdbg("ERROR: Failed to open '%s': %d\n", driver, ret); diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index a0260a1f4d3e8fdfbd1133c718920afee1ac0e8e..6ed8529ac369a149d77c933a367d7e8e76fc8b69 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -329,7 +329,7 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, buffer += dev->geo.erasesize; } - /* Finally, handler any partial blocks after the last full erase block */ + /* Finally, handle any partial blocks after the last full erase block */ if (remaining > 0) { diff --git a/drivers/mtd/m25px.c b/drivers/mtd/m25px.c index 60eba9558a811ca2617bdd6f5ec40017af0443f6..f117c10d9124d8cfbd26c91c154c9af768fa7c73 100644 --- a/drivers/mtd/m25px.c +++ b/drivers/mtd/m25px.c @@ -69,6 +69,10 @@ # define CONFIG_M25P_SPIMODE SPIDEV_MODE0 #endif +#ifndef CONFIG_M25P_SPIFREQUENCY +# define CONFIG_M25P_SPIFREQUENCY 20000000 +#endif + /* Various manufacturers may have produced the parts. 0x20 is the manufacturer ID * for the STMicro MP25x serial FLASH. If, for example, you are using the a Macronix * International MX25 serial FLASH, the correct manufacturer ID would be 0xc2. @@ -137,6 +141,7 @@ #define M25P_M25P32_NSECTORS 64 #define M25P_M25P32_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */ #define M25P_M25P32_NPAGES 16384 +#define M25P_M25PX32_SUBSECT_SHIFT 12 /* Sub-Sector size 1 << 12 = 4,096 */ /* M25P64 capacity is 8,338,608 bytes: * (128 sectors) * (65,536 bytes per sector) @@ -284,7 +289,8 @@ static void m25p_lock(FAR struct spi_dev_s *dev) SPI_SETMODE(dev, CONFIG_M25P_SPIMODE); SPI_SETBITS(dev, 8); - (void)SPI_SETFREQUENCY(dev, 20000000); + (void)SPI_HWFEATURES(dev, 0); + (void)SPI_SETFREQUENCY(dev, CONFIG_M25P_SPIFREQUENCY); } /************************************************************************************ @@ -382,6 +388,9 @@ static inline int m25p_readid(struct m25p_dev_s *priv) priv->nsectors = M25P_M25P32_NSECTORS; priv->pageshift = M25P_M25P32_PAGE_SHIFT; priv->npages = M25P_M25P32_NPAGES; +#ifdef CONFIG_M25P_SUBSECTOR_ERASE + priv->subsectorshift = M25P_M25PX32_SUBSECT_SHIFT; +#endif return OK; } else if (capacity == M25P_M25P64_CAPACITY) @@ -417,34 +426,6 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv) { uint8_t status; - /* Are we the only device on the bus? */ - -#ifdef CONFIG_SPI_OWNBUS - - /* Select this FLASH part */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, true); - - /* Send "Read Status Register (RDSR)" command */ - - (void)SPI_SEND(priv->dev, M25P_RDSR); - - /* Loop as long as the memory is busy with a write cycle */ - - do - { - /* Send a dummy byte to generate the clock needed to shift out the status */ - - status = SPI_SEND(priv->dev, M25P_DUMMY); - } - while ((status & M25P_SR_WIP) != 0); - - /* Deselect the FLASH */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, false); - -#else - /* Loop as long as the memory is busy with a write cycle */ do @@ -478,7 +459,6 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv) } } while ((status & M25P_SR_WIP) != 0); -#endif fvdbg("Complete\n"); } diff --git a/drivers/mtd/mtd_config.c b/drivers/mtd/mtd_config.c index c9162eae6f5daa1b3403718d35e31ee9670c971d..d3cde695641eeb60099e4a85d8ee870c9cbb0097 100644 --- a/drivers/mtd/mtd_config.c +++ b/drivers/mtd/mtd_config.c @@ -115,11 +115,13 @@ struct mtdconfig_header_s static int mtdconfig_open(FAR struct file *filep); static int mtdconfig_close(FAR struct file *filep); -static ssize_t mtdconfig_read(FAR struct file *, FAR char *, size_t); -static ssize_t mtdconfig_ioctl(FAR struct file *, int, unsigned long); +static ssize_t mtdconfig_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int mtdconfig_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); #ifndef CONFIG_DISABLE_POLL static int mtdconfig_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup); + bool setup); #endif /**************************************************************************** @@ -645,8 +647,6 @@ static off_t mtdconfig_ramconsolidate(FAR struct mtdconfig_struct_s *dev) /* Now Write the item to the current dst_offset location */ - //printf("REL HDR: ID=%04X,%02X Len=%4d Off=%5d Src off=%4d\n", - // phdr->id, phdr->instance, phdr->len, dst_offset, src_offset); ret = mtdconfig_writebytes(dev, dst_offset, (uint8_t *) phdr, sizeof(hdr)); if (ret < 0) @@ -815,8 +815,6 @@ retry_relocate: /* Copy this entry to the destination */ - //printf("REL HDR: ID=%04X,%02X Len=%4d Off=%5d Src off=%4d\n", - // hdr.id, hdr.instance, hdr.len, dst_offset, src_offset); mtdconfig_writebytes(dev, dst_offset, (uint8_t *) &hdr, sizeof(hdr)); src_offset += sizeof(hdr); dst_offset += sizeof(hdr); @@ -850,7 +848,7 @@ retry_relocate: src_offset += sizeof(hdr) + hdr.len; if (src_offset + sizeof(hdr) >= (src_block + 1) * dev->erasesize || - src_offset == (src_block +1 ) * dev->erasesize) + src_offset == (src_block + 1) * dev->erasesize) { /* No room left at end of source block */ @@ -1181,8 +1179,7 @@ retry_find: hdr.instance = pdata->instance; hdr.len = pdata->len; hdr.flags = MTD_ERASED_FLAGS; - //printf("SAV HDR: ID=%04X,%02X Len=%4d Off=%5d\n", - // hdr.id, hdr.instance, hdr.len, offset); + mtdconfig_writebytes(dev, offset, (uint8_t *)&hdr, sizeof(hdr)); bytes = mtdconfig_writebytes(dev, offset + sizeof(hdr), pdata->configdata, pdata->len); @@ -1311,7 +1308,7 @@ static int mtdconfig_poll(FAR struct file *filep, FAR struct pollfd *fds, { if (setup) { - fds->revents |= (fds->events & (POLLIN|POLLOUT)); + fds->revents |= (fds->events & (POLLIN | POLLOUT)); if (fds->revents != 0) { sem_post(fds->sem); diff --git a/drivers/mtd/mtd_nand.c b/drivers/mtd/mtd_nand.c index 3c333dd47727c339e15dd1224f30c2b5d201c9d6..da4327b50b581f0d33c895a760eba80df863917e 100644 --- a/drivers/mtd/mtd_nand.c +++ b/drivers/mtd/mtd_nand.c @@ -250,8 +250,8 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block) * ****************************************************************************/ -//#ifdef CONFIG_MTD_NAND_BLOCKCHECK -#if defined(CONFIG_MTD_NAND_BLOCKCHECK) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) +#if defined(CONFIG_MTD_NAND_BLOCKCHECK) && defined(CONFIG_DEBUG_VERBOSE) && \ + defined(CONFIG_DEBUG_FS) static int nand_devscan(FAR struct nand_dev_s *nand) { FAR struct nand_raw_s *raw; @@ -329,7 +329,7 @@ static int nand_devscan(FAR struct nand_dev_s *nand) return OK; } -#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ +#endif /* CONFIG_MTD_NAND_BLOCKCHECK && CONFIG_DEBUG_VERBOSE && CONFIG_DEBUG_FS */ /**************************************************************************** * Name: nand_chipid @@ -540,7 +540,7 @@ static int nand_writepage(FAR struct nand_dev_s *nand, off_t block, * ECC calculations. */ - else + else #endif { return NAND_WRITEPAGE(nand->raw, block, page, data, NULL); diff --git a/drivers/mtd/mtd_nandscheme.c b/drivers/mtd/mtd_nandscheme.c index 600e58883665cf53d8e3619317ecb2f73e005fe7..367dcc18d6a4882b3eab8b7744b5e2bbd04661f2 100644 --- a/drivers/mtd/mtd_nandscheme.c +++ b/drivers/mtd/mtd_nandscheme.c @@ -327,12 +327,12 @@ void nandscheme_writeextra(FAR const struct nand_scheme_s *scheme, FAR uint8_t *spare, FAR const void *extra, unsigned int size, unsigned int offset) { - DEBUGASSERT((size + offset) < scheme->nxbytes); - - uint32_t i; - for (i = 0; i < size; i++) { + DEBUGASSERT((size + offset) < scheme->nxbytes); - spare[scheme->xbytepos[i+offset]] = ((uint8_t *) extra)[i]; + uint32_t i; + for (i = 0; i < size; i++) + { + spare[scheme->xbytepos[i+offset]] = ((uint8_t *) extra)[i]; } } diff --git a/drivers/mtd/mtd_onfi.c b/drivers/mtd/mtd_onfi.c index 5f9781b295bd237c94530f8d17dbd7a7e9286311..aa4c6a09c0a06ae99b4b448dad96c400ae57532d 100644 --- a/drivers/mtd/mtd_onfi.c +++ b/drivers/mtd/mtd_onfi.c @@ -88,7 +88,7 @@ #define EBICSA_EBI_DBPDC (1 << 9) #define EBICSA_NAND_D0_ON_D16 (1 << 24) - /* Misc. definitions */ +/* Misc. definitions */ #define MAX_READ_STATUS_COUNT 100000 /* Read status timeout */ #define ONFI_PARAM_TABLE_SIZE 116 /* Not all 256 bytes are useful */ @@ -113,17 +113,10 @@ *(volatile uint8_t *)((uintptr_t)a) = (uint8_t)d; \ } while (0) -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ + /**************************************************************************** * Name: onfi_readstatus * @@ -216,6 +209,7 @@ bool onfi_have_embeddedecc(FAR struct onfi_pgparam_s *onfi) /**************************************************************************** * Public Functions ****************************************************************************/ + /**************************************************************************** * Name: onfi_compatible * @@ -328,39 +322,39 @@ int onfi_read(uintptr_t cmdaddr, uintptr_t addraddr, uintptr_t dataaddr, /* JEDEC manufacturer ID */ - onfi->manufacturer = *(uint8_t *)(parmtab + 64); + onfi->manufacturer = *(FAR uint8_t *)(parmtab + 64); /* Bus width */ - onfi->buswidth = (*(uint8_t *)(parmtab + 6)) & 0x01; + onfi->buswidth = (*(FAR uint8_t *)(parmtab + 6)) & 0x01; /* Get number of data bytes per page (bytes 80-83 in the param table) */ - onfi->pagesize = *(uint32_t *)(void*)(parmtab + 80); + onfi->pagesize = *(FAR uint32_t *)(FAR void *)(parmtab + 80); /* Get number of spare bytes per page (bytes 84-85 in the param table) */ - onfi->sparesize = *(uint16_t *)(void*)(parmtab + 84); + onfi->sparesize = *(FAR uint16_t *)(FAR void *)(parmtab + 84); /* Number of pages per block. */ - onfi->pagesperblock = *(uint32_t *)(void*)(parmtab + 92); + onfi->pagesperblock = *(FAR uint32_t *)(FAR void *)(parmtab + 92); /* Number of blocks per logical unit (LUN). */ - onfi->blocksperlun = *(uint32_t *)(void*)(parmtab + 96); + onfi->blocksperlun = *(FAR uint32_t *)(FAR void *)(parmtab + 96); /* Number of logical units. */ - onfi->luns = *(uint8_t *)(parmtab + 100); + onfi->luns = *(FAR uint8_t *)(parmtab + 100); /* Number of bits of ECC correction */ - onfi->eccsize = *(uint8_t *)(parmtab + 112); + onfi->eccsize = *(FAR uint8_t *)(parmtab + 112); /* Device model */ - onfi->model= *(uint8_t *)(parmtab + 49); + onfi->model = *(FAR uint8_t *)(parmtab + 49); fvdbg("Returning:\n"); fvdbg(" manufacturer: 0x%02x\n", onfi->manufacturer); @@ -483,7 +477,7 @@ bool onfi_ebidetect(uintptr_t cmdaddr, uintptr_t addraddr, ids[2] = READ_NAND(dataaddr); ids[3] = READ_NAND(dataaddr); - for (i = 0; i< NAND_NMODELS ; i++) + for (i = 0; i < NAND_NMODELS ; i++) { if (g_nandmodels[i].devid == ids[1]) { diff --git a/drivers/mtd/mtd_partition.c b/drivers/mtd/mtd_partition.c index 4b7931e7801b359834ffc8f3edbc4d5c2edcfaf9..f6a148c753c80fb208a11e038ad9ec4f1079fd0d 100644 --- a/drivers/mtd/mtd_partition.c +++ b/drivers/mtd/mtd_partition.c @@ -739,7 +739,7 @@ static int part_procfs_stat(const char *relpath, struct stat *buf) { /* File/directory size, access block size */ - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; buf->st_size = 0; buf->st_blksize = 0; buf->st_blocks = 0; diff --git a/drivers/mtd/mtd_procfs.c b/drivers/mtd/mtd_procfs.c index fd27917e0c9dd91613c9f0656cb3de5eded3841c..bc3071c7e078e6af32c84d0e47430bb10ff906de 100644 --- a/drivers/mtd/mtd_procfs.c +++ b/drivers/mtd/mtd_procfs.c @@ -40,7 +40,6 @@ #include #include -//#include #include #include @@ -93,11 +92,11 @@ static int mtd_dup(FAR const struct file *oldp, static int mtd_stat(FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -304,7 +303,7 @@ static int mtd_stat(const char *relpath, struct stat *buf) { /* File/directory size, access block size */ - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; buf->st_size = 0; buf->st_blksize = 0; buf->st_blocks = 0; @@ -364,4 +363,45 @@ int mtd_register(FAR struct mtd_dev_s *mtd, FAR const char *name) return OK; } +/**************************************************************************** + * Name: mtd_unregister + * + * Description: + * Un-Registers an MTD device with the procfs file system. + * + * In an embedded system, this all is really unnecessary, but is provided + * in the procfs system simply for information purposes (if desired). + * + ****************************************************************************/ + +int mtd_unregister(FAR struct mtd_dev_s *mtd) +{ + FAR struct mtd_dev_s *plast; + + /* Remove the MTD from the list of registered devices */ + + if (g_pfirstmtd == mtd) + { + g_pfirstmtd = mtd->pnext; + } + else + { + /* Remove from middle of list */ + + plast = g_pfirstmtd; + while (plast->pnext != mtd) + { + /* Skip to next entry as long as there is one */ + + plast = plast->pnext; + } + + /* Now remove at this location */ + + plast->pnext = mtd->pnext; + } + + return OK; +} + #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */ diff --git a/drivers/mtd/mtd_progmem.c b/drivers/mtd/mtd_progmem.c new file mode 100644 index 0000000000000000000000000000000000000000..e3eca2ee5fbfa6b762d2999bada767d22375c8af --- /dev/null +++ b/drivers/mtd/mtd_progmem.c @@ -0,0 +1,406 @@ +/**************************************************************************** + * drivers/mtd/mtd_progmem.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type represents the state of the MTD device. The struct mtd_dev_s + * must appear at the beginning of the definition so that you can freely + * cast between pointers to struct mtd_dev_s and struct progmem_dev_s. + */ + +struct progmem_dev_s +{ + /* Publically visible representation of the interface */ + + struct mtd_dev_s mtd; + + /* Fields unique to the progmem MTD driver */ + + bool initialized; /* True: Already initialized */ + uint8_t blkshift; /* Log2 of the flash block size */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Internal helper functions */ + +static int32_t progmem_log2(size_t blocksize); + +/* MTD driver methods */ + +static int progmem_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t progmem_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t progmem_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t progmem_read(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buffer); +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t progmem_write(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buffer); +#endif +static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This structure holds the state of the MTD driver */ + +static struct progmem_dev_s g_progmem = +{ + { + progmem_erase, + progmem_bread, + progmem_bwrite, + progmem_read, +#ifdef CONFIG_MTD_BYTE_WRITE + progmem_write, +#endif + progmem_ioctl + } +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: progmem_erase + * + * Description: + * Erase several blocks, each of the size previously reported. + * + ****************************************************************************/ + +static int32_t progmem_log2(uint32_t blocksize) +{ + uint32_t log2 = 0; + + /* Search every bit in the blocksize from bit zero to bit 30 (omitting bit + * 31 which is the sign bit on return) + */ + + for (log2 = 0; log2 < 31; log2++, blocksize >>= 1) + { + /* Is bit zero set? */ + + if ((blocksize & 1) != 0) + { + /* Yes... the value should be exactly one. We do not support + * block sizes that are not exact powers of two. + */ + + return blocksize == 1 ? log2 : -ENOSYS; + } + } + + return blocksize == 0 ? -EINVAL : -E2BIG; +} + +/**************************************************************************** + * Name: progmem_erase + * + * Description: + * Erase several blocks, each of the size previously reported. + * + ****************************************************************************/ + +static int progmem_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks) +{ + ssize_t result; + + /* Erase the specified blocks and return status (OK or a negated errno) */ + + while (nblocks > 0) + { + result = up_progmem_erasepage(startblock); + if (result < 0) + { + return (int)result; + } + + /* Setup for the next pass through the loop */ + + startblock++; + nblocks--; + } + + return OK; +} + +/**************************************************************************** + * Name: progmem_bread + * + * Description: + * Read the specified number of blocks into the user provided buffer. + * + ****************************************************************************/ + +static ssize_t progmem_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buffer) +{ + FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev; + FAR const uint8_t *src; + + /* Read the specified blocks into the provided user buffer and return + * status (The positive, number of blocks actually read or a negated + * errno). + */ + + src = (FAR const uint8_t *)up_progmem_getaddress(startblock); + memcpy(buffer, src, nblocks << priv->blkshift); + return nblocks; +} + +/**************************************************************************** + * Name: progmem_bwrite + * + * Description: + * Write the specified number of blocks from the user provided buffer. + * + ****************************************************************************/ + +static ssize_t progmem_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buffer) +{ + FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev; + ssize_t result; + + /* Write the specified blocks from the provided user buffer and return status + * (The positive, number of blocks actually written or a negated errno) + */ + + result = up_progmem_write(up_progmem_getaddress(startblock), buffer, + nblocks << priv->blkshift); + return result < 0 ? result : nblocks; +} + +/**************************************************************************** + * Name: progmem_read + * + * Description: + * Read the specified number of bytes to the user provided buffer. + * + ****************************************************************************/ + +static ssize_t progmem_read(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buffer) +{ + FAR const uint8_t *src; + + /* Read the specified bytes into the provided user buffer and return + * status (The positive, number of bytes actually read or a negated + * errno) + */ + + src = (FAR const uint8_t *)up_progmem_getaddress(offset); + memcpy(buffer, src, nbytes); + return nbytes; +} + +/**************************************************************************** + * Name: progmem_write + * + * Description: + * Some FLASH parts have the ability to write an arbitrary number of + * bytes to an arbitrary offset on the device. + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_BYTE_WRITE +static ssize_t progmem_write(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buffer) +{ + FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev; + ssize_t result; + + /* Write the specified blocks from the provided user buffer and return status + * (The positive, number of blocks actually written or a negated errno) + */ + + result = up_progmem_write(up_progmem_getaddress(offset), buffer, nbytes; + return result < 0 ? result : nbytes; +} +#endif + +/**************************************************************************** + * Name: progmem_ioctl + ****************************************************************************/ + +static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg; + if (geo) + { + /* Populate the geometry structure with information needed to know + * the capacity and how to access the device. + * + * NOTE: that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but the client + * will expect the device logic to do whatever is necessary to make it + * appear so. + */ + + geo->blocksize = (1 << priv->blkshift); /* Size of one read/write block */ + geo->erasesize = (1 << priv->blkshift); /* Size of one erase block */ + geo->neraseblocks = up_progmem_npages(); /* Number of erase blocks */ + ret = OK; + } + } + break; + + case MTDIOC_XIPBASE: + { + FAR void **ppv = (FAR void**)arg; + + if (ppv) + { + /* Return (void*) base address of FLASH memory. */ + + *ppv = (FAR void *)up_progmem_getaddress(0); + ret = OK; + } + } + break; + + case MTDIOC_BULKERASE: + { + size_t nblocks = up_progmem_npages(); + + /* Erase the entire device */ + + ret = progmem_erase(dev, 0, nblocks); + } + break; + + default: + ret = -ENOTTY; /* Bad command */ + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: progmem_initialize + * + * Description: + * Create and initialize an MTD device instance that can be used to access + * on-chip program memory. + * + * MTD devices are not registered in the file system, but are created as + * instances that can be bound to other functions (such as a block or + * character driver front end). + * + ****************************************************************************/ + +FAR struct mtd_dev_s *progmem_initialize(void) +{ + FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)&g_progmem; + int32_t blkshift; + + /* Perform initialization if necessary */ + + if (!g_progmem.initialized) + { + /* Get the size of one block. Here we assume that the block size is + * uniform and that the size of block0 is the same as the size of any + * other block. + */ + + size_t blocksize = up_progmem_pagesize(0); + + /* Calculate Log2 of the flash block size */ + + blkshift = progmem_log2(blocksize); + if (blkshift < 0) + { + return NULL; + } + + /* Save the configuration data */ + + g_progmem.blkshift = blkshift; + g_progmem.initialized = true; + +#ifdef CONFIG_MTD_REGISTRATION + /* Register the MTD with the procfs system if enabled */ + + mtd_register(&priv->mtd, "progmem"); +#endif + } + + /* Return the implementation-specific state structure as the MTD device */ + + return (FAR struct mtd_dev_s *)priv; +} diff --git a/drivers/mtd/mtd_rwbuffer.c b/drivers/mtd/mtd_rwbuffer.c index 4b9e39ea4fd4476014ac2aa45472c74ba8e1cd87..0e05a7c92bca2dbf82981d8f274820a068702c7c 100644 --- a/drivers/mtd/mtd_rwbuffer.c +++ b/drivers/mtd/mtd_rwbuffer.c @@ -295,7 +295,7 @@ static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) /* Then invalidate in cached data */ - ret = rwb_invalidate(&priv->rwb,0, priv->rwb.nblocks); + ret = rwb_invalidate(&priv->rwb, 0, priv->rwb.nblocks); if (ret < 0) { fdbg("ERROR: rwb_invalidate failed: %d\n", ret); diff --git a/drivers/mtd/rammtd.c b/drivers/mtd/rammtd.c index 06497e13f8c96763fc6d92e4e3477757c9d24270..af63097723b7c69fb989d615adad77a05e870449 100644 --- a/drivers/mtd/rammtd.c +++ b/drivers/mtd/rammtd.c @@ -395,7 +395,7 @@ static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) { /* Return (void*) base address of device memory */ - *ppv = (FAR void*)priv->start; + *ppv = (FAR void *)priv->start; ret = OK; } } diff --git a/drivers/mtd/ramtron.c b/drivers/mtd/ramtron.c index 215c13f7b21cc0bf061af18c7a02a47e314fd419..89e0ade8597aa2f6185d60c9fb3d1842948ea6bb 100644 --- a/drivers/mtd/ramtron.c +++ b/drivers/mtd/ramtron.c @@ -176,6 +176,14 @@ static const struct ramtron_parts_s g_ramtron_parts[] = 2, /* addr_len */ RAMTRON_INIT_CLK_MAX /* speed */ }, + { + "FM25V01A", /* name */ + 0x21, /* id1 */ + 0x08, /* id2 */ + 16L*1024L, /* size */ + 2, /* addr_len */ + RAMTRON_INIT_CLK_MAX /* speed */ + }, { "FM25V02", /* name */ 0x22, /* id1 */ @@ -184,6 +192,14 @@ static const struct ramtron_parts_s g_ramtron_parts[] = 2, /* addr_len */ RAMTRON_INIT_CLK_MAX /* speed */ }, + { + "FM25V02A", /* name */ + 0x22, /* id1 */ + 0x08, /* id2 */ + 32L*1024L, /* size */ + 2, /* addr_len */ + RAMTRON_INIT_CLK_MAX /* speed */ + }, { "FM25VN02", /* name */ 0x22, /* id1 */ @@ -224,6 +240,22 @@ static const struct ramtron_parts_s g_ramtron_parts[] = 3, /* addr_len */ RAMTRON_INIT_CLK_MAX /* speed */ }, + { + "FM25V20A", /* name */ + 0x25, /* id1 */ + 0x08, /* id2 */ + 256L*1024L, /* size */ + 3, /* addr_len */ + RAMTRON_INIT_CLK_MAX /* speed */ + }, + { + "CY15B104Q", /* name */ + 0x26, /* id1 */ + 0x08, /* id2 */ + 512L*1024L, /* size */ + 3, /* addr_len */ + RAMTRON_INIT_CLK_MAX /* speed */ + }, { "MB85RS1MT", /* name */ 0x27, /* id1 */ @@ -311,6 +343,7 @@ static void ramtron_lock(FAR struct ramtron_dev_s *priv) SPI_SETMODE(dev, SPIDEV_MODE3); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, priv->speed); } diff --git a/drivers/mtd/s25fl1.c b/drivers/mtd/s25fl1.c new file mode 100644 index 0000000000000000000000000000000000000000..5a89c0d9e84abb74126c3ccf8a3dc06b98a3468b --- /dev/null +++ b/drivers/mtd/s25fl1.c @@ -0,0 +1,1562 @@ +/************************************************************************************ + * drivers/mtd/s25fl1.c + * Driver for QuadSPI-based S25FL116K, S25FL132K, and S25L164K + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* QuadSPI Mode. Per data sheet, either Mode 0 or Mode 3 may be used. */ + +#ifndef CONFIG_S25FL1_QSPIMODE +# define CONFIG_S25FL1_QSPIMODE QSPIDEV_MODE0 +#endif + +/* QuadSPI Frequency per data sheet:: + * + * – Normal Read (Serial): + * 50 MHz clock rate (-40°C to +85°C/105°C) + * 45 MHz clock rate (-40°C to +125°C) + * – Fast Read (Serial): + * 108 MHz clock rate (-40°C to +85°C/105°C) + * 97 MHz clock rate (-40°C to +125°C) + * – Dual Read: + * 108 MHz clock rate (-40°C to +85°C/105°C) + * 97 MHz clock rate (-40°C to +125°C) + * – Quad Read: + * 108 MHz clock rate (-40°C to +85°C/105°C) + * 97 MHz clock rate for S25FL164K (-40°C to +125°C) + * + * Table 5.8: + * - Clock frequency for all SPI commands except for Read Data + * command (0x03) and Fast Read command (0x0b): 108 MHz + * - Clock frequency for Read Data command (0x03): 50 MHz + * - Clock frequency for all Fast Read commands SIO and MIO: 108 MHz + * + * In this implementation, only "Quad" reads are performed. + */ + +#ifndef CONFIG_S25FL1_QSPI_FREQUENCY +# define CONFIG_S25FL1_QSPI_FREQUENCY 108000000 +#endif + +/* S25FL1 Commands ******************************************************************/ +/* Configuration, Status, Erase, Program Commands ***********************************/ +/* Command Value Description: */ +/* Data sequence */ +#define S25FL1_READ_STATUS1 0x05 /* Read status register 1: * + * 0x05 | SR1 */ +#define S25FL1_READ_STATUS2 0x35 /* Read status register 2: * + * 0x35 | SR2 */ +#define S25FL1_READ_STATUS3 0x33 /* Read status register 3: * + * 0x33 | SR3 */ +#define S25FL1_WRITE_ENABLE 0x06 /* Write enable: * + * 0x06 */ +#define S25FL1_VWRITE_ENABLE 0x50 /* Write enable for volatile status: * + * 0x50 */ +#define S25FL1_WRITE_DISABLE 0x04 /* Write disable command code: * + * 0x04 */ +#define S25FL1_WRITE_STATUS 0x01 /* Write status register: * + * 0x01 | SR1 | SR2 | SR3 */ +#define S25FL1_WRAP_ENABLE 0x77 /* Set Burst with Wrap: * + * 0x77 | xx | xx | xx | SR3 */ +#define S25FL1_UNPROTECT_SECTOR 0x39 /* Set Block / Pointer Protection: * + * 0x39 | ADDR(MS) | ADDR(MID) | xx */ +#define S25FL1_PAGE_PROGRAM 0x02 /* Page Program: * + * 0x02 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | data */ +#define S25FL1_SECTOR_ERASE 0x20 /* Sector Erase (4 kB) * + * 0x02 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) */ +#define S25FL1_BLOCK_ERASE 0xd8 /* Block Erase (64 kB): * + * 0x02 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) */ +#define S25FL1_CHIP_ERASE_1 0x60 /* Chip Erase 1: * + * 0x60 */ +#define S25FL1_CHIP_ERASE_2 0xc7 /* Chip Erase 2: * + * 0xc7 */ +#define S25FL1_ERASE_PROG_SUSPEND 0x75 /* Erase / Program Suspend: * + * 0x75 */ +#define S25FL1_ERASE_PROG_RESUME 0x7a /* Erase / Program Resume: * + * 0x7a */ + +/* Read Commands ********************************************************************/ +/* Command Value Description: */ +/* Data sequence */ +#define S25FL1_READ_DATA 0x03 /* Read Data: * + * 0x03 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | data... */ +#define S25FL1_FAST_READ 0x0b /* Fast Read: * + * 0x0b | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | dummy | data... */ +#define S25FL1_FAST_READ_DUAL 0x3b /* Fast Read Dual Output: * + * 0x3b | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | dummy | data... */ +#define S25FL1_FAST_READ_QUAD 0x6b /* Fast Read Dual Output: * + * 0x6b | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | dummy | data... */ +#define S25FL1_FAST_READ_DUALIO 0xbb /* Fast Read Dual I/O: * + * 0xbb | ADDR(MS) | ADDR(LS) | data... */ +#define S25FL1_FAST_READ_QUADIO 0xeb /* Fast Read Quad I/O: * + * 0xeb | ADDR | data... */ +#define S25FL1_CONT_READ_RESET 0xff /* Continuous Read Mode Reset: * + * 0xff | 0xff */ + +/* Reset Commands *******************************************************************/ +/* Command Value Description: */ +/* Data sequence */ +#define S25FL1_SOFT_RESET_ENABLE 0x66 /* Software Reset Enable: * + * 0x66 */ +#define S25FL1_SOFT_RESET 0x99 /* Software Reset: * + * 0x99 */ + /* Continuous Read Mode Reset: * + * 0xff | 0xff */ + +/* ID/Security Commands *************************&***********************************/ +/* Command Value Description: */ +/* Data sequence */ +#define S25FL1_DEEP_PWRDOWN 0xb9 /* Deep Power-down: * + * 0xb9 */ +#define S25FL1_RELEASE_PWRDOWN 0xab /* Release Power down / Device ID: * + * 0xab | dummy | dummy | dummy | * + * DeviceID */ +#define S25FL1_MANUFACTURER 0x90 /* Manufacturer / Device ID: * + * 0x90 | dummy | dummy | 0x00 | * + * Manufacturer | DeviceID */ +#define S25FL1_JEDEC_ID 0x9f /* JEDEC ID: * + * 0x9f | Manufacturer | MemoryType | * + * Capacity */ +#define S25FL1_READ_SFDP 0x5a /* Read SFDP Register / Read Unique ID * + * Number: * + * 0x5a | 0x00 | 0x00 | ADDR | dummy | * + * data... */ +#define S25FL1_READ_SECURITY 0x48 /* Read Security Registers: * + * 0x48 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | dummy | data... */ +#define S25FL1_ERASE_SECURITY 0x44 /* Erase Security Registers: * + * 0x48 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) */ +#define S25FL1_PROgRAM_SECURITY 0x42 /* Program Security Registers: * + * 0x42 | ADDR(MS) | ADDR(MID) | * + * ADDR(LS) | data... */ + +/* Flash Manufacturer JEDEC IDs */ + +#define S25FL1_JEDEC_ID_SPANSION 0x01 +#define S25FL1_JEDEC_ID_ATMEL 0x1f +#define S25FL1_JEDEC_ID_ST 0x20 +#define S25FL1_JEDEC_ID_SST 0xbf +#define S25FL1_JEDEC_ID_MACRONIX 0xc2 +#define S25FL1_JEDEC_ID_WINBOND 0xef + +/* S25FL1 JEDIC IDs */ + +#define S25FL1_JEDEC_DEVICE_TYPE 0x40 /* S25FL1 memory devuce type */ +#define S25FL116K_JEDEC_CAPACITY 0x15 /* S25FL116K memory capacity */ +#define S25FL132K_JEDEC_CAPACITY 0x16 /* S25FL132K memory capacity */ +#define S25FL164K_JEDEC_CAPACITY 0x17 /* S25FL164K memory capacity */ + +/* S25FL1 Registers ****************************************************************/ +/* Status register bit definitions */ + +#define STATUS1_BUSY_MASK (1 << 0) /* Bit 0: Device ready/busy status */ +# define STATUS1_READY (0 << 0) /* 0 = Not Busy */ +# define STATUS1_BUSY (1 << 0) /* 1 = Busy */ +#define STATUS1_WEL_MASK (1 << 1) /* Bit 1: Write enable latch status */ +# define STATUS1_WEL_DISABLED (0 << 1) /* 0 = Not Write Enabled */ +# define STATUS1_WEL_ENABLED (1 << 1) /* 1 = Write Enabled */ +#define STATUS1_BP_SHIFT (2) /* Bits 2-4: Block protect bits */ +#define STATUS1_BP_MASK (7 << STATUS1_BP_SHIFT) +# define STATUS1_BP_NONE (0 << STATUS1_BP_SHIFT) +# define STATUS1_BP_ALL (7 << STATUS1_BP_SHIFT) +#define STATUS1_TB_MASK (1 << 5) /* Bit 5: Top / Bottom Protect */ +# define STATUS1_TB_TOP (0 << 5) /* 0 = BP2-BP0 protect Top down */ +# define STATUS1_TB_BOTTOM (1 << 5) /* 1 = BP2-BP0 protect Bottom up */ +#define STATUS1_SEC_MASK (1 << 6) /* Bit 6: Sector / Block Protect */ +# define STATUS1_SEC_BLOCK (0 << 6) /* 0 = BP2-BP0 protect 64-kB blocks */ +# define STATUS1_SEC_SECTOR (1 << 6) /* 1 = BP2-BP0 protect 4-kB sectors */ +#define STATUS1_SRP0_MASK (1 << 7) /* Bit 7: Status register protect 0 */ +# define STATUS1_SRP0_UNLOCKED (0 << 7) /* 0 = WP# no effect / PS Lock Down */ +# define STATUS1_SRP0_LOCKED (1 << 7) /* 1 = WP# protect / OTP Lock Down */ + +#define STATUS2_SRP1_MASK (1 << 0) /* Bit 0: Status register protect 1 */ +# define STATUS2_SRP1_UNLOCKED (0 << 0) /* 0 = WP# no effect / PS Lock Down */ +# define STATUS2_SRP1_LOCKED (1 << 0) /* 1 = WP# protect / OTP Lock Down */ +#define STATUS2_QUAD_ENABLE_MASK (1 << 1) /* Bit 1: Quad Enable */ +# define STATUS2_QUAD_DISABLE (0 << 1) /* 0 = Quad Mode Not Enabled */ +# define STATUS2_QUAD_ENABLE (1 << 1) /* 1 = Quad Mode Enabled */ +#define STATUS2_LB_SHIFT (2) /* Bits 2-5: Security Register Lock */ +#define STATUS2_LB_MASK (15 << STATUS2_LB_SHIFT) +# define STATUS2_LB_NONE (0 << STATUS2_LB_SHIFT) +# define STATUS2_LB_ALL (15 << STATUS2_LB_SHIFT) +#define STATUS2_CMP_MASK (1 << 6) /* Bit 6: Complement Protect */ +# define STATUS2_CMP_NORMAL (0 << 6) /* 0 = Normal Protection Map */ +# define STATUS2_CMP_INVERTED (1 << 6) /* 1 = Inverted Protection Map */ +#define STATUS2_SUS_MASK (1 << 7) /* Bit 7: Suspend Status */ +# define STATUS2_SUS_NONE (0 << 7) /* 0 = Erase / Program not suspended */ +# define STATUS2_SUS_SUSPENDED (1 << 7) /* 1 = Erase / Program suspended */ + +#define STATUS3_LC_SHIFT (0) /* Bits 0-3: Latency control */ +#define STATUS3_LC_MASK (15 << STATUS3_LC_SHIFT) +#define STATUS3_W4_MASK (1 << 4) /* Bit 4: Burst Wrap Enable */ +# define STATUS3_W4_DISABLED (0 << 4) /* 0 = Wrap Enabled */ +# define STATUS3_W4_ENABLED (1 << 4) /* 1 = Wrap Disabled */ +#define STATUS3_W56_SHIFT (5) /* Bits 5-6: Burst Wrap Length */ +#define STATUS3_W56_MASK (3 << STATUS3_W56_SHIFT) +# define STATUS3_W56_8BYTE (0 << STATUS3_W56_SHIFT) +# define STATUS3_W56_16BYTE (1 << STATUS3_W56_SHIFT) +# define STATUS3_W56_32BYTE (2 << STATUS3_W56_SHIFT) +# define STATUS3_W56_63BYTE (3 << STATUS3_W56_SHIFT) + /* Bit 7: Reserved */ + +/* Chip Geometries ******************************************************************/ +/* All members of the family support uniform 4K-byte sectors */ + +#define S25FL116K_SECTOR_SIZE (4*1024) +#define S25FL116K_SECTOR_SHIFT (12) +#define S25FL116K_SECTOR_COUNT (512) +#define S25FL116K_PAGE_SIZE (256) +#define S25FL116K_PAGE_SHIFT (8) + +#define S25FL132K_SECTOR_SIZE (4*1024) +#define S25FL132K_SECTOR_SHIFT (12) +#define S25FL132K_SECTOR_COUNT (1024) +#define S25FL132K_PAGE_SIZE (256) +#define S25FL132K_PAGE_SHIFT (8) + +#define S25FL164K_SECTOR_SIZE (4*1024) +#define S25FL164K_SECTOR_SHIFT (12) +#define S25FL164K_SECTOR_COUNT (2048) +#define S25FL164K_PAGE_SIZE (256) +#define S25FL164K_PAGE_SHIFT (8) + +/* Cache flags **********************************************************************/ + +#define S25FL1_CACHE_VALID (1 << 0) /* 1=Cache has valid data */ +#define S25FL1_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */ +#define S25FL1_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */ + +#define IS_VALID(p) ((((p)->flags) & S25FL1_CACHE_VALID) != 0) +#define IS_DIRTY(p) ((((p)->flags) & S25FL1_CACHE_DIRTY) != 0) +#define IS_ERASED(p) ((((p)->flags) & S25FL1_CACHE_DIRTY) != 0) + +#define SET_VALID(p) do { (p)->flags |= S25FL1_CACHE_VALID; } while (0) +#define SET_DIRTY(p) do { (p)->flags |= S25FL1_CACHE_DIRTY; } while (0) +#define SET_ERASED(p) do { (p)->flags |= S25FL1_CACHE_DIRTY; } while (0) + +#define CLR_VALID(p) do { (p)->flags &= ~S25FL1_CACHE_VALID; } while (0) +#define CLR_DIRTY(p) do { (p)->flags &= ~S25FL1_CACHE_DIRTY; } while (0) +#define CLR_ERASED(p) do { (p)->flags &= ~S25FL1_CACHE_DIRTY; } while (0) + +/* 512 byte sector support **********************************************************/ + +#define S25FL1_SECTOR512_SHIFT 9 +#define S25FL1_SECTOR512_SIZE (1 << 9) +#define S25FL1_ERASED_STATE 0xff + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/* This type represents the state of the MTD device. The struct mtd_dev_s must + * appear at the beginning of the definition so that you can freely cast between + * pointers to struct mtd_dev_s and struct s25fl1_dev_s. + */ + +struct s25fl1_dev_s +{ + struct mtd_dev_s mtd; /* MTD interface */ + FAR struct qspi_dev_s *qspi; /* Saved QuadSPI interface instance */ + uint16_t nsectors; /* Number of erase sectors */ + uint8_t sectorshift; /* Log2 of sector size */ + uint8_t pageshift; /* Log2 of page size */ + FAR uint8_t *cmdbuf; /* Allocated command buffer */ + FAR uint8_t *readbuf; /* Allocated status read buffer */ + +#ifdef CONFIG_S25FL1_SECTOR512 + uint8_t flags; /* Buffered sector flags */ + uint16_t esectno; /* Erase sector number in the cache */ + FAR uint8_t *sector; /* Allocated sector data */ +#endif +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* Locking */ + +static void s25fl1_lock(FAR struct qspi_dev_s *qspi); +static inline void s25fl1_unlock(FAR struct qspi_dev_s *qspi); + +/* Low-level message helpers */ + +static int s25fl1_command(FAR struct qspi_dev_s *qspi, uint8_t cmd); +static int s25fl1_command_address(FAR struct qspi_dev_s *qspi, uint8_t cmd, + off_t addr, uint8_t addrlen); +static int s25fl1_command_read(FAR struct qspi_dev_s *qspi, uint8_t cmd, + FAR void *buffer, size_t buflen); +static int s25fl1_command_write(FAR struct qspi_dev_s *qspi, uint8_t cmd, + FAR const void *buffer, size_t buflen); +static uint8_t sf25fl1_read_status1(FAR struct s25fl1_dev_s *priv); +static uint8_t sf25fl1_read_status2(FAR struct s25fl1_dev_s *priv); +static uint8_t sf25fl1_read_status3(FAR struct s25fl1_dev_s *priv); +static void s25fl1_write_enable(FAR struct s25fl1_dev_s *priv); +static void s25fl1_write_disable(FAR struct s25fl1_dev_s *priv); + +static int s25fl1_readid(FAR struct s25fl1_dev_s *priv); +static int s25fl1_protect(FAR struct s25fl1_dev_s *priv, + off_t startblock, size_t nblocks); +static int s25fl1_unprotect(FAR struct s25fl1_dev_s *priv, + off_t startblock, size_t nblocks); +static bool s25fl1_isprotected(FAR struct s25fl1_dev_s *priv, + uint8_t status, off_t address); +static int s25fl1_erase_sector(FAR struct s25fl1_dev_s *priv, off_t offset); +static int s25fl1_erase_chip(FAR struct s25fl1_dev_s *priv); +static int s25fl1_read_byte(FAR struct s25fl1_dev_s *priv, FAR uint8_t *buffer, + off_t address, size_t nbytes); +static int s25fl1_write_page(FAR struct s25fl1_dev_s *priv, + FAR const uint8_t *buffer, off_t address, size_t nbytes); +#ifdef CONFIG_S25FL1_SECTOR512 +static int s25fl1_flush_cache(struct s25fl1_dev_s *priv); +static FAR uint8_t *s25fl1_read_cache(struct s25fl1_dev_s *priv, off_t sector); +static void s25fl1_erase_cache(struct s25fl1_dev_s *priv, off_t sector); +static int s25fl1_write_cache(FAR struct s25fl1_dev_s *priv, + FAR const uint8_t *buffer, off_t sector, size_t nsectors); +#endif + +/* MTD driver methods */ + +static int s25fl1_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t s25fl1_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t s25fl1_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t s25fl1_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR uint8_t *buffer); +static int s25fl1_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: s25fl1_lock + ************************************************************************************/ + +static void s25fl1_lock(FAR struct qspi_dev_s *qspi) +{ + /* On QuadSPI busses where there are multiple devices, it will be necessary to + * lock QuadSPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. + * + * This is a blocking call and will not return until we have exclusiv access to + * the QuadSPI buss. We will retain that exclusive access until the bus is unlocked. + */ + + (void)QSPI_LOCK(qspi, true); + + /* After locking the QuadSPI bus, the we also need call the setfrequency, setbits, and + * setmode methods to make sure that the QuadSPI is properly configured for the device. + * If the QuadSPI buss is being shared, then it may have been left in an incompatible + * state. + */ + + QSPI_SETMODE(qspi, CONFIG_S25FL1_QSPIMODE); + QSPI_SETBITS(qspi, 8); + (void)QSPI_SETFREQUENCY(qspi, CONFIG_S25FL1_QSPI_FREQUENCY); +} + +/************************************************************************************ + * Name: s25fl1_unlock + ************************************************************************************/ + +static inline void s25fl1_unlock(FAR struct qspi_dev_s *qspi) +{ + (void)QSPI_LOCK(qspi, false); +} + +/************************************************************************************ + * Name: s25fl1_command + ************************************************************************************/ + +static int s25fl1_command(FAR struct qspi_dev_s *qspi, uint8_t cmd) +{ + struct qspi_cmdinfo_s cmdinfo; + + fvdbg("CMD: %02x\n", cmd); + + cmdinfo.flags = 0; + cmdinfo.addrlen = 0; + cmdinfo.cmd = cmd; + cmdinfo.buflen = 0; + cmdinfo.addr = 0; + cmdinfo.buffer = NULL; + + return QSPI_COMMAND(qspi, &cmdinfo); +} + +/************************************************************************************ + * Name: s25fl1_command_address + ************************************************************************************/ + +static int s25fl1_command_address(FAR struct qspi_dev_s *qspi, uint8_t cmd, + off_t addr, uint8_t addrlen) +{ + struct qspi_cmdinfo_s cmdinfo; + + fvdbg("CMD: %02x Address: %04lx addrlen=%d\n", cmd, (unsigned long)addr, addrlen); + + cmdinfo.flags = QSPICMD_ADDRESS; + cmdinfo.addrlen = addrlen; + cmdinfo.cmd = cmd; + cmdinfo.buflen = 0; + cmdinfo.addr = addr; + cmdinfo.buffer = NULL; + + return QSPI_COMMAND(qspi, &cmdinfo); +} + +/************************************************************************************ + * Name: s25fl1_command_read + ************************************************************************************/ + +static int s25fl1_command_read(FAR struct qspi_dev_s *qspi, uint8_t cmd, + FAR void *buffer, size_t buflen) +{ + struct qspi_cmdinfo_s cmdinfo; + + fvdbg("CMD: %02x buflen: %lu\n", cmd, (unsigned long)buflen); + + cmdinfo.flags = QSPICMD_READDATA; + cmdinfo.addrlen = 0; + cmdinfo.cmd = cmd; + cmdinfo.buflen = buflen; + cmdinfo.addr = 0; + cmdinfo.buffer = buffer; + + return QSPI_COMMAND(qspi, &cmdinfo); +} + +/************************************************************************************ + * Name: s25fl1_command_write + ************************************************************************************/ + +static int s25fl1_command_write(FAR struct qspi_dev_s *qspi, uint8_t cmd, + FAR const void *buffer, size_t buflen) +{ + struct qspi_cmdinfo_s cmdinfo; + + fvdbg("CMD: %02x buflen: %lu\n", cmd, (unsigned long)buflen); + + cmdinfo.flags = QSPICMD_WRITEDATA; + cmdinfo.addrlen = 0; + cmdinfo.cmd = cmd; + cmdinfo.buflen = buflen; + cmdinfo.addr = 0; + cmdinfo.buffer = (FAR void *)buffer; + + return QSPI_COMMAND(qspi, &cmdinfo); +} + +/************************************************************************************ + * Name: sf25fl1_read_status1 + ************************************************************************************/ + +static uint8_t sf25fl1_read_status1(FAR struct s25fl1_dev_s *priv) +{ + DEBUGVERIFY(s25fl1_command_read(priv->qspi, S25FL1_READ_STATUS1, + (FAR void *)&priv->readbuf[0], 1)); + return priv->readbuf[0]; +} + +/************************************************************************************ + * Name: sf25fl1_read_status2 + ************************************************************************************/ + +static uint8_t sf25fl1_read_status2(FAR struct s25fl1_dev_s *priv) +{ + DEBUGVERIFY(s25fl1_command_read(priv->qspi, S25FL1_READ_STATUS2, + (FAR void *)&priv->readbuf[0], 1)); + return priv->readbuf[0]; +} + +/************************************************************************************ + * Name: sf25fl1_read_status3 + ************************************************************************************/ + +static uint8_t sf25fl1_read_status3(FAR struct s25fl1_dev_s *priv) +{ + DEBUGVERIFY(s25fl1_command_read(priv->qspi, S25FL1_READ_STATUS3, + (FAR void *)&priv->readbuf[0], 1)); + return priv->readbuf[0]; +} + +/************************************************************************************ + * Name: s25fl1_write_enable + ************************************************************************************/ + +static void s25fl1_write_enable(FAR struct s25fl1_dev_s *priv) +{ + uint8_t status; + + do + { + s25fl1_command(priv->qspi, S25FL1_WRITE_ENABLE); + status = sf25fl1_read_status1(priv); + } + while ((status & STATUS1_WEL_MASK) != STATUS1_WEL_ENABLED); +} + +/************************************************************************************ + * Name: s25fl1_write_disable + ************************************************************************************/ + +static void s25fl1_write_disable(FAR struct s25fl1_dev_s *priv) +{ + uint8_t status; + + do + { + s25fl1_command(priv->qspi, S25FL1_WRITE_DISABLE); + status = sf25fl1_read_status1(priv); + } + while ((status & STATUS1_WEL_MASK) != STATUS1_WEL_DISABLED); +} + +/************************************************************************************ + * Name: s25fl1_write_status + ************************************************************************************/ + +static void s25fl1_write_status(FAR struct s25fl1_dev_s *priv) +{ + s25fl1_write_enable(priv); + s25fl1_command_write(priv->qspi, S25FL1_WRITE_STATUS, + (FAR const void *)priv->cmdbuf, 3); + s25fl1_write_disable(priv); +} + +/************************************************************************************ + * Name: s25fl1_readid + ************************************************************************************/ + +static inline int s25fl1_readid(struct s25fl1_dev_s *priv) +{ + /* Lock the QuadSPI bus and configure the bus. */ + + s25fl1_lock(priv->qspi); + + /* Read the JEDEC ID */ + + s25fl1_command_read(priv->qspi, S25FL1_JEDEC_ID, priv->cmdbuf, 3); + + /* Unlock the bus */ + + s25fl1_unlock(priv->qspi); + + fvdbg("Manufacturer: %02x Device Type %02x, Capacity: %02x", + priv->cmdbuf[0], priv->cmdbuf[1], priv->cmdbuf[2]); + + /* Check for a recognized memory device type */ + + if (priv->cmdbuf[1] != S25FL1_JEDEC_DEVICE_TYPE) + { + fdbg("ERROR: Unrecognized device type: %02x\n", priv->cmdbuf[1]); + return -ENODEV; + } + + /* Check for a supported capacity */ + + switch (priv->cmdbuf[2]) + { + case S25FL116K_JEDEC_CAPACITY: + priv->sectorshift = S25FL116K_SECTOR_SHIFT; + priv->pageshift = S25FL116K_PAGE_SHIFT; + priv->nsectors = S25FL116K_SECTOR_COUNT; + break; + + case S25FL132K_JEDEC_CAPACITY: + priv->sectorshift = S25FL132K_SECTOR_SHIFT; + priv->pageshift = S25FL116K_PAGE_SHIFT; + priv->nsectors = S25FL132K_SECTOR_COUNT; + break; + + case S25FL164K_JEDEC_CAPACITY: + priv->sectorshift = S25FL164K_SECTOR_SHIFT; + priv->pageshift = S25FL116K_PAGE_SHIFT; + priv->nsectors = S25FL164K_SECTOR_COUNT; + break; + + /* Support for this part is not implemented yet */ + + default: + fdbg("ERROR: Unsupported memory capacity: %02x\n", priv->cmdbuf[2]); + return -ENODEV; + } + + return OK; +} + +/************************************************************************************ + * Name: s25fl1_protect + ************************************************************************************/ + +static int s25fl1_protect(FAR struct s25fl1_dev_s *priv, + off_t startblock, size_t nblocks) +{ + /* Get the status register value to check the current protection */ + + priv->cmdbuf[0] = sf25fl1_read_status1(priv); + priv->cmdbuf[1] = sf25fl1_read_status2(priv); + priv->cmdbuf[2] = sf25fl1_read_status3(priv); + + if ((priv->cmdbuf[0] & STATUS1_BP_MASK) == STATUS1_BP_NONE) + { + /* Protection already disabled */ + + return 0; + } + + /* Check if sector protection registers are locked */ + + if ((priv->cmdbuf[0] & STATUS1_SRP0_MASK) == STATUS1_SRP0_LOCKED) + { + /* Yes.. unprotect section protection registers */ + + priv->cmdbuf[0] &= ~STATUS1_SRP0_MASK; + s25fl1_write_status(priv); + } + + /* Set the protection mask to zero. + * REVISIT: This logic should really just set the BP bits as + * necessary to protect the range of sectors. + */ + + priv->cmdbuf[0] |= STATUS1_BP_MASK; + s25fl1_write_status(priv); + + /* Check the new status */ + + priv->cmdbuf[0] = sf25fl1_read_status1(priv); + if ((priv->cmdbuf[0] & STATUS1_BP_MASK) != STATUS1_BP_MASK) + { + return -EACCES; + } + + return OK; +} + +/************************************************************************************ + * Name: s25fl1_unprotect + ************************************************************************************/ + +static int s25fl1_unprotect(FAR struct s25fl1_dev_s *priv, + off_t startblock, size_t nblocks) +{ + /* Get the status register value to check the current protection */ + + priv->cmdbuf[0] = sf25fl1_read_status1(priv); + priv->cmdbuf[1] = sf25fl1_read_status2(priv); + priv->cmdbuf[2] = sf25fl1_read_status3(priv); + + if ((priv->cmdbuf[0] & STATUS1_BP_MASK) == STATUS1_BP_NONE && + (priv->cmdbuf[1] & STATUS2_CMP_MASK) == 0) + { + /* Protection already disabled */ + + return 0; + } + + /* Check if sector protection registers are locked */ + + if ((priv->cmdbuf[0] & STATUS1_SRP0_MASK) == STATUS1_SRP0_LOCKED) + { + /* Yes.. unprotect section protection registers */ + + priv->cmdbuf[0] &= ~STATUS1_SRP0_MASK; + s25fl1_write_status(priv); + } + + /* Set the protection mask to zero (and not complemented). + * REVISIT: This logic should really just re-write the BP bits as + * necessary to unprotect the range of sectors. + */ + + priv->cmdbuf[0] &= ~STATUS1_BP_MASK; + priv->cmdbuf[1] &= ~STATUS2_CMP_MASK; + s25fl1_write_status(priv); + + /* Check the new status */ + + priv->cmdbuf[0] = sf25fl1_read_status1(priv); + if ((priv->cmdbuf[0] & (STATUS1_SRP0_MASK | STATUS1_BP_MASK)) != 0) + { + return -EACCES; + } + + return OK; +} + +/************************************************************************************ + * Name: s25fl1_isprotected + ************************************************************************************/ + +static bool s25fl1_isprotected(FAR struct s25fl1_dev_s *priv, uint8_t status, + off_t address) +{ + off_t protstart; + off_t protend; + off_t protsize; + unsigned int bp; + + /* What is protected? 64 Kb blocks? Or 4Kb sectors? */ + + if ((status & STATUS1_SEC_MASK) == STATUS1_SEC_BLOCK) + { + /* 64 Kb block */ + + protsize = 0x00010000; + } + else + { + /* 4 Kb sector */ + + protsize = 0x00001000; + } + + /* The BP field is the essentially a multiplier on this protection size */ + + bp = (status & STATUS1_BP_MASK) >> STATUS1_BP_SHIFT; + switch (bp) + { + case 0: + return false; + + case 1: + break; + + case 6: + case 7: + return true; + + default: + protsize <<= (protsize << (bp - 1)); + break; + } + + /* The final protection range then depends on if the protection region is + * configured top-down or bottom up (assuming CMP=0). + */ + + if ((status & STATUS1_TB_MASK) != 0) + { + protstart = 0x00000000; + protend = protstart + protsize; + } + else + { + protend = 0x00200000; + protstart = protend - protsize; + } + + return (address >= protstart && address < protend); +} + +/************************************************************************************ + * Name: s25fl1_erase_sector + ************************************************************************************/ + +static int s25fl1_erase_sector(struct s25fl1_dev_s *priv, off_t sector) +{ + off_t address; + uint8_t status; + + fvdbg("sector: %08lx\n", (unsigned long)sector); + + /* Check that the flash is ready and unprotected */ + + status = sf25fl1_read_status1(priv); + if ((status & STATUS1_BUSY_MASK) != STATUS1_READY) + { + fdbg("ERROR: Flash busy: %02x", status); + return -EBUSY; + } + + /* Get the address associated with the sector */ + + address = (off_t)sector << priv->sectorshift; + + if ((status & STATUS1_BP_MASK) != 0 && + s25fl1_isprotected(priv, status, address)) + { + fdbg("ERROR: Flash protected: %02x", status); + return -EACCES; + } + + /* Send the sector erase command */ + + s25fl1_write_enable(priv); + s25fl1_command_address(priv->qspi, S25FL1_SECTOR_ERASE, address, 3); + + /* Wait for erasure to finish */ + + while ((sf25fl1_read_status1(priv) & STATUS1_BUSY_MASK) != 0); + return OK; +} + +/************************************************************************************ + * Name: s25fl1_erase_chip + ************************************************************************************/ + +static int s25fl1_erase_chip(struct s25fl1_dev_s *priv) +{ + uint8_t status; + + /* Check if the FLASH is protected */ + + status = sf25fl1_read_status1(priv); + if ((status & STATUS1_BP_MASK) != 0) + { + fdbg("ERROR: FLASH is Protected: %02x", status); + return -EACCES; + } + + /* Erase the whole chip */ + + s25fl1_write_enable(priv); + s25fl1_command(priv->qspi, S25FL1_CHIP_ERASE_2); + + /* Wait for the erasure to complete */ + + status = sf25fl1_read_status1(priv); + while ((status & STATUS1_BUSY_MASK) != 0) + { + usleep(200*1000); + status = sf25fl1_read_status1(priv); + } + + return OK; +} + +/************************************************************************************ + * Name: s25fl1_read_byte + ************************************************************************************/ + +static int s25fl1_read_byte(FAR struct s25fl1_dev_s *priv, FAR uint8_t *buffer, + off_t address, size_t buflen) +{ + struct qspi_meminfo_s meminfo; + + fvdbg("address: %08lx nbytes: %d\n", (long)address, (int)buflen); + +#ifdef CONFIG_S25FL1_SCRAMBLE + meminfo.flags = QSPIMEM_READ | QSPIMEM_QUADIO | QSPIMEM_SCRAMBLE; +#else + meminfo.flags = QSPIMEM_READ | QSPIMEM_QUADIO; +#endif + meminfo.addrlen = 3; + meminfo.dummies = 6; + meminfo.buflen = buflen; + meminfo.cmd = S25FL1_FAST_READ_QUADIO; + meminfo.addr = address; +#ifdef CONFIG_S25FL1_SCRAMBLE + meminfo.key = CONFIG_S25FL1_SCRAMBLE_KEY; +#endif + meminfo.buffer = buffer; + + return QSPI_MEMORY(priv->qspi, &meminfo); +} + +/************************************************************************************ + * Name: s25fl1_write_page + ************************************************************************************/ + +static int s25fl1_write_page(struct s25fl1_dev_s *priv, FAR const uint8_t *buffer, + off_t address, size_t buflen) +{ + struct qspi_meminfo_s meminfo; + unsigned int pagesize; + unsigned int npages; + int ret; + int i; + + fvdbg("address: %08lx buflen: %u\n", (unsigned long)address, (unsigned)buflen); + + npages = (buflen >> priv->pageshift); + pagesize = (1 << priv->pageshift); + + /* Set up non-varying parts of transfer description */ + +#ifdef CONFIG_S25FL1_SCRAMBLE + meminfo.flags = QSPIMEM_WRITE | QSPIMEM_SCRAMBLE; +#else + meminfo.flags = QSPIMEM_WRITE; +#endif + meminfo.cmd = S25FL1_PAGE_PROGRAM; + meminfo.addrlen = 3; + meminfo.buflen = pagesize; +#ifdef CONFIG_S25FL1_SCRAMBLE + meminfo.key = CONFIG_S25FL1_SCRAMBLE_KEY; +#endif + meminfo.dummies = 0; + + /* Then write each page */ + + for (i = 0; i < npages; i++) + { + /* Set up varying parts of the transfer description */ + + meminfo.addr = address; + meminfo.buffer = (void *)buffer; + + /* Write one page */ + + s25fl1_write_enable(priv); + ret = QSPI_MEMORY(priv->qspi, &meminfo); + s25fl1_write_disable(priv); + + if (ret < 0) + { + fdbg("ERROR: QSPI_MEMORY failed writing address=%06x\n", + address); + return ret; + } + + /* Update for the next time through the loop */ + + buffer += pagesize; + address += pagesize; + buflen -= pagesize; + } + + /* The transfer should always be an even number of sectors and hence also + * pages. There should be no remainder. + */ + + DEBUGASSERT(buflen == 0); + return OK; +} + +/************************************************************************************ + * Name: s25fl1_flush_cache + ************************************************************************************/ + +#ifdef CONFIG_S25FL1_SECTOR512 +static int s25fl1_flush_cache(struct s25fl1_dev_s *priv) +{ + int ret = OK; + + /* If the cached is dirty (meaning that it no longer matches the old FLASH contents) + * or was erased (with the cache containing the correct FLASH contents), then write + * the cached erase block to FLASH. + */ + + if (IS_DIRTY(priv) || IS_ERASED(priv)) + { + off_t address; + + /* Convert the erase sector numuber into a FLASH address */ + + address = (off_t)priv->esectno << priv->sectorshift; + + /* Write entire erase block to FLASH */ + + ret = s25fl1_write_page(priv, priv->sector, address, 1 << priv->sectorshift); + if (ret < 0) + { + fdbg("ERROR: s25fl1_write_page failed: %d\n", ret); + } + + /* The case is no long dirty and the FLASH is no longer erased */ + + CLR_DIRTY(priv); + CLR_ERASED(priv); + } + + return ret; +} +#endif + +/************************************************************************************ + * Name: s25fl1_read_cache + ************************************************************************************/ + +#ifdef CONFIG_S25FL1_SECTOR512 +static FAR uint8_t *s25fl1_read_cache(struct s25fl1_dev_s *priv, off_t sector) +{ + off_t esectno; + int shift; + int index; + int ret; + + /* Convert from the 512 byte sector to the erase sector size of the device. For + * exmample, if the actual erase sector size if 4Kb (1 << 12), then we first + * shift to the right by 3 to get the sector number in 4096 increments. + */ + + shift = priv->sectorshift - S25FL1_SECTOR512_SHIFT; + esectno = sector >> shift; + fvdbg("sector: %ld esectno: %d shift=%d\n", sector, esectno, shift); + + /* Check if the requested erase block is already in the cache */ + + if (!IS_VALID(priv) || esectno != priv->esectno) + { + /* No.. Flush any dirty erase block currently in the cache */ + + ret = s25fl1_flush_cache(priv); + if (ret < 0) + { + fdbg("ERROR: s25fl1_flush_cache failed: %d\n", ret); + return NULL; + } + + /* Read the erase block into the cache */ + + ret = s25fl1_read_byte(priv, priv->sector, + (esectno << priv->sectorshift), + (1 << priv->sectorshift)); + if (ret < 0) + { + fdbg("ERROR: s25fl1_read_byte failed: %d\n", ret); + return NULL; + } + + /* Mark the sector as cached */ + + priv->esectno = esectno; + + SET_VALID(priv); /* The data in the cache is valid */ + CLR_DIRTY(priv); /* It should match the FLASH contents */ + CLR_ERASED(priv); /* The underlying FLASH has not been erased */ + } + + /* Get the index to the 512 sector in the erase block that holds the argument */ + + index = sector & ((1 << shift) - 1); + + /* Return the address in the cache that holds this sector */ + + return &priv->sector[index << S25FL1_SECTOR512_SHIFT]; +} +#endif + +/************************************************************************************ + * Name: s25fl1_erase_cache + ************************************************************************************/ + +#ifdef CONFIG_S25FL1_SECTOR512 +static void s25fl1_erase_cache(struct s25fl1_dev_s *priv, off_t sector) +{ + FAR uint8_t *dest; + + /* First, make sure that the erase block containing the 512 byte sector is in + * the cache. + */ + + dest = s25fl1_read_cache(priv, sector); + + /* Erase the block containing this sector if it is not already erased. + * The erased indicated will be cleared when the data from the erase sector + * is read into the cache and set here when we erase the block. + */ + + if (!IS_ERASED(priv)) + { + off_t esectno = sector >> (priv->sectorshift - S25FL1_SECTOR512_SHIFT); + fvdbg("sector: %ld esectno: %d\n", sector, esectno); + + DEBUGVERIFY(s25fl1_erase_sector(priv, esectno)); + SET_ERASED(priv); + } + + /* Put the cached sector data into the erase state and mart the cache as dirty + * (but don't update the FLASH yet. The caller will do that at a more optimal + * time). + */ + + memset(dest, S25FL1_ERASED_STATE, S25FL1_SECTOR512_SIZE); + SET_DIRTY(priv); +} +#endif + +/************************************************************************************ + * Name: s25fl1_write_cache + ************************************************************************************/ + +#ifdef CONFIG_S25FL1_SECTOR512 +static int s25fl1_write_cache(FAR struct s25fl1_dev_s *priv, + FAR const uint8_t *buffer, off_t sector, + size_t nsectors) +{ + FAR uint8_t *dest; + int ret; + + for (; nsectors > 0; nsectors--) + { + /* First, make sure that the erase block containing 512 byte sector is in + * memory. + */ + + dest = s25fl1_read_cache(priv, sector); + + /* Erase the block containing this sector if it is not already erased. + * The erased indicated will be cleared when the data from the erase sector + * is read into the cache and set here when we erase the sector. + */ + + if (!IS_ERASED(priv)) + { + off_t esectno = sector >> (priv->sectorshift - S25FL1_SECTOR512_SHIFT); + fvdbg("sector: %ld esectno: %d\n", sector, esectno); + + ret = s25fl1_erase_sector(priv, esectno); + if (ret < 0) + { + fdbg("ERROR: s25fl1_erase_sector failed: %d\n", ret); + return ret; + } + + SET_ERASED(priv); + } + + /* Copy the new sector data into cached erase block */ + + memcpy(dest, buffer, S25FL1_SECTOR512_SIZE); + SET_DIRTY(priv); + + /* Set up for the next 512 byte sector */ + + buffer += S25FL1_SECTOR512_SIZE; + sector++; + } + + /* Flush the last erase block left in the cache */ + + return s25fl1_flush_cache(priv); +} +#endif + +/************************************************************************************ + * Name: s25fl1_erase + ************************************************************************************/ + +static int s25fl1_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) +{ + FAR struct s25fl1_dev_s *priv = (FAR struct s25fl1_dev_s *)dev; + size_t blocksleft = nblocks; +#ifdef CONFIG_S25FL1_SECTOR512 + int ret; +#endif + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* Lock access to the SPI bus until we complete the erase */ + + s25fl1_lock(priv->qspi); + + while (blocksleft-- > 0) + { + /* Erase each sector */ + +#ifdef CONFIG_S25FL1_SECTOR512 + s25fl1_erase_cache(priv, startblock); +#else + s25fl1_erase_sector(priv, startblock); +#endif + startblock++; + } + +#ifdef CONFIG_S25FL1_SECTOR512 + /* Flush the last erase block left in the cache */ + + ret = s25fl1_flush_cache(priv); + if (ret < 0) + { + nblocks = ret; + } +#endif + + s25fl1_unlock(priv->qspi); + return (int)nblocks; +} + +/************************************************************************************ + * Name: s25fl1_bread + ************************************************************************************/ + +static ssize_t s25fl1_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buffer) +{ +#ifndef CONFIG_S25FL1_SECTOR512 + FAR struct s25fl1_dev_s *priv = (FAR struct s25fl1_dev_s *)dev; +#endif + ssize_t nbytes; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* On this device, we can handle the block read just like the byte-oriented read */ + +#ifdef CONFIG_S25FL1_SECTOR512 + nbytes = s25fl1_read(dev, startblock << S25FL1_SECTOR512_SHIFT, + nblocks << S25FL1_SECTOR512_SHIFT, buffer); + if (nbytes > 0) + { + nbytes >>= S25FL1_SECTOR512_SHIFT; + } +#else + nbytes = s25fl1_read(dev, startblock << priv->sectorshift, + nblocks << priv->sectorshift, buffer); + if (nbytes > 0) + { + nbytes >>= priv->sectorshift; + } +#endif + + return nbytes; +} + +/************************************************************************************ + * Name: s25fl1_bwrite + ************************************************************************************/ + +static ssize_t s25fl1_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buffer) +{ + FAR struct s25fl1_dev_s *priv = (FAR struct s25fl1_dev_s *)dev; + int ret = (int)nblocks; + + fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* Lock the QuadSPI bus and write all of the pages to FLASH */ + + s25fl1_lock(priv->qspi); + +#if defined(CONFIG_S25FL1_SECTOR512) + ret = s25fl1_write_cache(priv, buffer, startblock, nblocks); + if (ret < 0) + { + fdbg("ERROR: s25fl1_write_cache failed: %d\n", ret); + } + +#else + ret = s25fl1_write_page(priv, buffer, startblock << priv->sectorshift, + nblocks << priv->sectorshift); + if (ret < 0) + { + fdbg("ERROR: s25fl1_write_page failed: %d\n", ret); + } +#endif + + s25fl1_unlock(priv->qspi); + + return ret < 0 ? ret : nblocks; +} + +/************************************************************************************ + * Name: s25fl1_read + ************************************************************************************/ + +static ssize_t s25fl1_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR uint8_t *buffer) +{ + FAR struct s25fl1_dev_s *priv = (FAR struct s25fl1_dev_s *)dev; + int ret; + + fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + + /* Lock the QuadSPI bus and select this FLASH part */ + + s25fl1_lock(priv->qspi); + ret = s25fl1_read_byte(priv, buffer, offset, nbytes); + s25fl1_unlock(priv->qspi); + + if (ret < 0) + { + fdbg("ERROR: s25fl1_read_byte returned: %d\n", ret); + return (ssize_t)ret; + } + + fvdbg("return nbytes: %d\n", (int)nbytes); + return (ssize_t)nbytes; +} + +/************************************************************************************ + * Name: s25fl1_ioctl + ************************************************************************************/ + +static int s25fl1_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct s25fl1_dev_s *priv = (FAR struct s25fl1_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + fvdbg("cmd: %d \n", cmd); + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = + (FAR struct mtd_geometry_s *)((uintptr_t)arg); + + if (geo) + { + /* Populate the geometry structure with information need to know + * the capacity and how to access the device. + * + * NOTE: that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but the client + * will expect the device logic to do whatever is necessary to make it + * appear so. + */ + +#ifdef CONFIG_S25FL1_SECTOR512 + geo->blocksize = (1 << S25FL1_SECTOR512_SHIFT); + geo->erasesize = (1 << S25FL1_SECTOR512_SHIFT); + geo->neraseblocks = priv->nsectors << (priv->sectorshift - S25FL1_SECTOR512_SHIFT); +#else + geo->blocksize = (1 << priv->sectorshift); + geo->erasesize = (1 << priv->sectorshift); + geo->neraseblocks = priv->nsectors; +#endif + ret = OK; + + fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + break; + + case MTDIOC_BULKERASE: + { + /* Erase the entire device */ + + s25fl1_lock(priv->qspi); + ret = s25fl1_erase_chip(priv); + s25fl1_unlock(priv->qspi); + } + break; + + case MTDIOC_PROTECT: + { + FAR const struct mtd_protect_s *prot = + (FAR const struct mtd_protect_s *)((uintptr_t)arg); + + DEBUGASSERT(prot); + ret = s25fl1_protect(priv, prot->startblock, prot->nblocks); + } + break; + + case MTDIOC_UNPROTECT: + { + FAR const struct mtd_protect_s *prot = + (FAR const struct mtd_protect_s *)((uintptr_t)arg); + + DEBUGASSERT(prot); + ret = s25fl1_unprotect(priv, prot->startblock, prot->nblocks); + } + break; + + default: + ret = -ENOTTY; /* Bad/unsupported command */ + break; + } + + fvdbg("return %d\n", ret); + return ret; +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: s25fl1_initialize + * + * Description: + * Create an initialize MTD device instance for the QuadSPI-based ST24FL1 + * FLASH part. + * + * MTD devices are not registered in the file system, but are created as instances + * that can be bound to other functions (such as a block or character driver front + * end). + * + ************************************************************************************/ + +FAR struct mtd_dev_s *s25fl1_initialize(FAR struct qspi_dev_s *qspi, bool unprotect) +{ + FAR struct s25fl1_dev_s *priv; + int ret; + + fvdbg("qspi: %p\n", qspi); + DEBUGASSERT(qspi != NULL); + + /* Allocate a state structure (we allocate the structure instead of using + * a fixed, static allocation so that we can handle multiple FLASH devices. + * The current implementation would handle only one FLASH part per QuadSPI + * device (only because of the QSPIDEV_FLASH definition) and so would have + * to be extended to handle multiple FLASH parts on the same QuadSPI bus. + */ + + priv = (FAR struct s25fl1_dev_s *)kmm_zalloc(sizeof(struct s25fl1_dev_s)); + if (priv) + { + /* Initialize the allocated structure (unsupported methods were + * nullified by kmm_zalloc). + */ + + priv->mtd.erase = s25fl1_erase; + priv->mtd.bread = s25fl1_bread; + priv->mtd.bwrite = s25fl1_bwrite; + priv->mtd.read = s25fl1_read; + priv->mtd.ioctl = s25fl1_ioctl; + priv->qspi = qspi; + + /* Allocate a 4-byte buffer to support DMA command data */ + + priv->cmdbuf = (FAR uint8_t *)QSPI_ALLOC(qspi, 4); + if (priv->cmdbuf == NULL) + { + fdbg("ERROR Failed to allocate command buffer\n"); + goto errout_with_priv; + } + + /* Allocate a one-byte buffer to support DMA status read data */ + + priv->readbuf = (FAR uint8_t *)QSPI_ALLOC(qspi, 1); + if (priv->readbuf == NULL) + { + fdbg("ERROR Failed to allocate read buffer\n"); + goto errout_with_cmdbuf; + } + + /* Identify the FLASH chip and get its capacity */ + + ret = s25fl1_readid(priv); + if (ret != OK) + { + /* Unrecognized! Discard all of that work we just did and return NULL */ + + fdbg("ERROR Unrecognized QSPI device\n"); + goto errout_with_readbuf; + } + + /* Enable quad mode */ + + priv->cmdbuf[0] = sf25fl1_read_status1(priv); + priv->cmdbuf[1] = sf25fl1_read_status2(priv); + priv->cmdbuf[2] = sf25fl1_read_status3(priv); + + while ((priv->cmdbuf[1] & STATUS2_QUAD_ENABLE_MASK) == 0) + { + priv->cmdbuf[1] |= STATUS2_QUAD_ENABLE; + s25fl1_write_status(priv); + priv->cmdbuf[1] = sf25fl1_read_status2(priv); + usleep(50*1000); + } + + /* Unprotect FLASH sectors if so requested. */ + + if (unprotect) + { + ret = s25fl1_unprotect(priv, 0, priv->nsectors - 1); + if (ret < 0) + { + fdbg("ERROR: Sector unprotect failed\n"); + } + } + +#ifdef CONFIG_S25FL1_SECTOR512 /* Simulate a 512 byte sector */ + /* Allocate a buffer for the erase block cache */ + + priv->sector = (FAR uint8_t *)QSPI_ALLOC(qspi, 1 << priv->sectorshift); + if (priv->sector == NULL) + { + /* Allocation failed! Discard all of that work we just did and return NULL */ + + fdbg("ERROR: Sector allocation failed\n"); + goto errout_with_readbuf; + } +#endif + } + +#ifdef CONFIG_MTD_REGISTRATION + /* Register the MTD with the procfs system if enabled */ + + mtd_register(&priv->mtd, "s25fl1"); +#endif + + /* Return the implementation-specific state structure as the MTD device */ + + fvdbg("Return %p\n", priv); + return (FAR struct mtd_dev_s *)priv; + +errout_with_readbuf: + QSPI_FREE(qspi, priv->readbuf); + +errout_with_cmdbuf: + QSPI_FREE(qspi, priv->cmdbuf); + +errout_with_priv: + kmm_free(priv); + return NULL; +} diff --git a/drivers/mtd/sector512.c b/drivers/mtd/sector512.c index 3b61e8210abcaa9806651469b516c2c4fcbcce3b..3705efb76903230c1f7604f07773d0bed2425f29 100644 --- a/drivers/mtd/sector512.c +++ b/drivers/mtd/sector512.c @@ -107,7 +107,7 @@ struct s512_dev_s size_t sectperblock; /* Number of read/write sectors per erase block */ uint16_t stdperblock; /* Number of 512 byte sectors in one erase block */ uint8_t flags; /* Buffered sector flags */ - uint32_t eblockno; /* Erase sector number in the cache*/ + uint32_t eblockno; /* Erase sector number in the cache */ FAR uint8_t *eblock; /* Allocated erase block */ }; @@ -269,9 +269,9 @@ static int s512_erase(FAR struct mtd_dev_s *dev, off_t sector512, size_t nsector } /* Erase the block containing this sector if it is not already erased. - * The erased indicator will be cleared when the data from the erase sector - * is read into the cache and set here when we erase the block. - */ + * The erased indicator will be cleared when the data from the erase sector + * is read into the cache and set here when we erase the block. + */ if (!IS_ERASED(priv)) { @@ -538,7 +538,7 @@ static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) if (ret >= 0) { priv->flags = 0; /* Buffered sector flags */ - priv->eblockno = 0; /* Erase sector number in the cache*/ + priv->eblockno = 0; /* Erase sector number in the cache */ priv->eblock = NULL; /* Allocated erase block */ } } @@ -588,7 +588,7 @@ FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd) /* We expect that the block size will be >512 and an even multiple of 512 */ if (ret < 0 || geo.erasesize <= SECTOR_512 || - (geo.erasesize & ~MASK_512) != geo.erasesize ) + (geo.erasesize & ~MASK_512) != geo.erasesize) { fdbg("ERROR: MTDIOC_GEOMETRY ioctl returned %d, eraseize=%d\n", ret, geo.erasesize); diff --git a/drivers/mtd/skeleton.c b/drivers/mtd/skeleton.c index 3740a879e061576f8440dceec68bdfc2aa446ef4..dc40675620a2d2fcd71470cfbadb0d394015129e 100644 --- a/drivers/mtd/skeleton.c +++ b/drivers/mtd/skeleton.c @@ -72,18 +72,20 @@ struct skel_dev_s /* MTD driver methods */ -static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); -static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR uint8_t *buf); -static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR const uint8_t *buf); -static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR uint8_t *buffer); +static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks); +static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf); +static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf); +static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buffer); #ifdef CONFIG_MTD_BYTE_WRITE -static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR const uint8_t *buffer); +static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buffer); #endif -static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); +static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, + unsigned long arg); /**************************************************************************** * Private Data @@ -92,15 +94,17 @@ static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static struct skel_dev_s g_skeldev = { - { skel_erase, - skel_rbead, + { + skel_erase, + skel_bread, skel_bwrite, skel_read, #ifdef CONFIG_MTD_BYTE_WRITE - skel_write, + skel_write, /* Should be NULL if the byte write method is not supported */ #endif skel_ioctl }, + /* Initialization of any other implementation specific data goes here */ }; @@ -121,9 +125,9 @@ static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, { FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev; - /* The interface definition assumes that all erase blocks are the same size. - * If that is not true for this particular device, then transform the - * start block and nblocks as necessary. + /* The interface definition assumes that all erase blocks are the same + * size. If that is not true for this particular device, then transform + * the start block and nblocks as necessary. */ /* Erase the specified blocks and return status (OK or a negated errno) */ @@ -139,18 +143,19 @@ static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, * ****************************************************************************/ -static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR uint8_t *buf) +static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buf) { FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev; - /* The interface definition assumes that all read/write blocks are the same size. - * If that is not true for this particular device, then transform the - * start block and nblocks as necessary. + /* The interface definition assumes that all read/write blocks are the + * same size. If that is not true for this particular device, then + * transform the start block and nblocks as necessary. */ - /* Read the specified blocks into the provided user buffer and return status - * (The positive, number of blocks actually read or a negated errno). + /* Read the specified blocks into the provided user buffer and return + * status (The positive, number of blocks actually read or a negated + * errno). */ return 0; @@ -164,18 +169,19 @@ static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nb * ****************************************************************************/ -static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR const uint8_t *buf) +static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buf) { FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev; - /* The interface definition assumes that all read/write blocks are the same size. - * If that is not true for this particular device, then transform the - * start block and nblocks as necessary. + /* The interface definition assumes that all read/write blocks are the + * same size. If that is not true for this particular device, then + * transform the start block and nblocks as necessary. */ - /* Write the specified blocks from the provided user buffer and return status - * (The positive, number of blocks actually written or a negated errno) + /* Write the specified blocks from the provided user buffer and return + * status (The positive, number of blocks actually written or a negated + * errno) */ return 0; @@ -189,26 +195,27 @@ static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n * ****************************************************************************/ -static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR uint8_t *buffer) +static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR uint8_t *buffer) { FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev; /* Some devices may support byte oriented read (optional). Byte-oriented - * writing is inherently block oriented on most MTD devices and is not supported. - * It is recommended that low-level drivers not support read() if it requires - * buffering -- let the higher level logic handle that. If the read method is - * not implemented, just set the method pointer to NULL in the struct mtd_dev_s - * instance. + * writing is inherently block oriented on most MTD devices and is not + * supported. It is recommended that low-level drivers not support read() + * if it requires buffering -- let the higher level logic handle that. If + * the read method is not implemented, just set the method pointer to NULL + * in the struct mtd_dev_s instance. */ - /* The interface definition assumes that all read/write blocks are the same size. - * If that is not true for this particular device, then transform the - * start block and nblocks as necessary. + /* The interface definition assumes that all read/write blocks are the + * same size. If that is not true for this particular device, then + * transform the start block and nblocks as necessary. */ - /* Read the specified blocks into the provided user buffer and return status - * (The positive, number of blocks actually read or a negated errno) + /* Read the specified bytes into the provided user buffer and return + * status (The positive, number of bytes actually read or a negated + * errno) */ return 0; @@ -219,13 +226,14 @@ static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, * * Description: * Some FLASH parts have the ability to write an arbitrary number of - * bytes to an arbitrary offset on the device. + * bytes to an arbitrary offset on the device. This method should be + * implement only for devices that support such access. * ****************************************************************************/ #ifdef CONFIG_MTD_BYTE_WRITE -static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR const uint8_t *buffer) +static ssize_t skel_write(FAR struct mtd_dev_s *dev, off_t offset, + size_t nbytes, FAR const uint8_t *buffer) { return -ENOSYS; } @@ -314,8 +322,19 @@ static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) FAR struct mtd_dev_s *skel_initialize(void) { + /* Allocate an instance of the private data structure -- OR, if there can + * only be a single instance of the driver, then use a shared, global + * device structure. + */ + /* Perform initialization as necessary */ +#ifdef CONFIG_MTD_REGISTRATION + /* Register the MTD with the procfs system if enabled */ + + mtd_register(&priv->mtd, "skeleton"); +#endif + /* Return the implementation-specific state structure as the MTD device */ return (FAR struct mtd_dev_s *)&g_skeldev; diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c index b8ac874fc9efa334b09ec7e5c42a2ffa70a6bf8d..cb188c1854656932a3064bbad758f0978a413e9c 100644 --- a/drivers/mtd/smart.c +++ b/drivers/mtd/smart.c @@ -3,7 +3,7 @@ * * Sector Mapped Allocation for Really Tiny (SMART) Flash block driver. * - * Copyright (C) 2013-2014 Ken Pettit. All rights reserved. + * Copyright (C) 2013-2015 Ken Pettit. All rights reserved. * Author: Ken Pettit * * Redistribution and use in source and binary forms, with or without @@ -43,6 +43,8 @@ #include #include +#include +#include #include #include #include @@ -277,8 +279,8 @@ struct smart_struct_s #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS struct smart_multiroot_device_s { - FAR struct smart_struct_s* dev; - uint8_t rootdirnum; + FAR struct smart_struct_s *dev; + uint8_t rootdirnum; }; #endif @@ -372,6 +374,8 @@ static int smart_findfreephyssector(FAR struct smart_struct_s *dev, uint8_t canr #ifdef CONFIG_FS_WRITABLE static int smart_writesector(FAR struct smart_struct_s *dev, unsigned long arg); +static inline int smart_allocsector(FAR struct smart_struct_s *dev, + unsigned long requested); #endif static int smart_readsector(FAR struct smart_struct_s *dev, unsigned long arg); @@ -381,7 +385,15 @@ static int smart_relocate_static_data(FAR struct smart_struct_s *dev, uint16_t b #endif static int smart_relocate_sector(FAR struct smart_struct_s *dev, - uint16_t oldsector, uint16_t newsector); + uint16_t oldsector, uint16_t newsector); + +#ifdef CONFIG_SMART_DEV_LOOP +static ssize_t smart_loop_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t smart_loop_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int smart_loop_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +#endif /* CONFIG_SMART_DEV_LOOP */ /**************************************************************************** * Private Data @@ -401,6 +413,21 @@ static const struct block_operations g_bops = smart_ioctl /* ioctl */ }; +#ifdef CONFIG_SMART_DEV_LOOP +static const struct file_operations g_fops = +{ + 0, /* open */ + 0, /* close */ + smart_loop_read, /* read */ + smart_loop_write, /* write */ + 0, /* seek */ + smart_loop_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; +#endif /* CONFIG_SMART_DEV_LOOP */ + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -440,10 +467,10 @@ static int smart_close(FAR struct inode *inode) ****************************************************************************/ #ifdef CONFIG_MTD_SMART_ALLOC_DEBUG -FAR static void* smart_malloc(FAR struct smart_struct_s *dev, +FAR static void *smart_malloc(FAR struct smart_struct_s *dev, size_t bytes, const char *name) { - void* ret = kmm_malloc(bytes); + FAR void *ret = kmm_malloc(bytes); uint8_t x; /* Keep track of the total allocation */ @@ -479,7 +506,7 @@ FAR static void* smart_malloc(FAR struct smart_struct_s *dev, ****************************************************************************/ #ifdef CONFIG_MTD_SMART_ALLOC_DEBUG -static void smart_free(FAR struct smart_struct_s *dev, FAR void* ptr) +static void smart_free(FAR struct smart_struct_s *dev, FAR void *ptr) { uint8_t x; @@ -505,7 +532,7 @@ static void smart_free(FAR struct smart_struct_s *dev, FAR void* ptr) ****************************************************************************/ #ifdef CONFIG_MTD_SMART_PACK_COUNTS -static void smart_set_count(FAR struct smart_struct_s *dev, FAR uint8_t* pCount, +static void smart_set_count(FAR struct smart_struct_s *dev, FAR uint8_t *pCount, uint16_t block, uint8_t count) { if (dev->sectorsPerBlk > 16) @@ -533,11 +560,11 @@ static void smart_set_count(FAR struct smart_struct_s *dev, FAR uint8_t* pCount, { if (count == 16) { - pCount[(dev->geo.neraseblocks >> 1) + (block>>3)] |= 1 << (block & 0x07); + pCount[(dev->geo.neraseblocks >> 1) + (block >> 3)] |= 1 << (block & 0x07); } else { - pCount[(dev->geo.neraseblocks >> 1) + (block>>3)] &= ~(1 << (block & 0x07)); + pCount[(dev->geo.neraseblocks >> 1) + (block >> 3)] &= ~(1 << (block & 0x07)); } } } @@ -554,7 +581,7 @@ static void smart_set_count(FAR struct smart_struct_s *dev, FAR uint8_t* pCount, #ifdef CONFIG_MTD_SMART_PACK_COUNTS static uint8_t smart_get_count(FAR struct smart_struct_s *dev, - FAR uint8_t* pCount, uint16_t block) + FAR uint8_t *pCount, uint16_t block) { uint8_t count; @@ -581,7 +608,7 @@ static uint8_t smart_get_count(FAR struct smart_struct_s *dev, if (dev->sectorsPerBlk == 16) { - if (pCount[(dev->geo.neraseblocks >> 1) + (block>>3)] & (1 << (block & 0x07))) + if (pCount[(dev->geo.neraseblocks >> 1) + (block >> 3)] & (1 << (block & 0x07))) { count |= 0x10; } @@ -600,7 +627,7 @@ static uint8_t smart_get_count(FAR struct smart_struct_s *dev, ****************************************************************************/ #ifdef CONFIG_MTD_SMART_PACK_COUNTS -static void smart_add_count(struct smart_struct_s *dev, uint8_t* pCount, +static void smart_add_count(struct smart_struct_s *dev, uint8_t *pCount, uint16_t block, int adder) { int16_t value; @@ -675,7 +702,7 @@ int smart_checkfree(FAR struct smart_struct_s *dev, int lineno) } /* Modifiy the freesector count to reflect the actual calculated freecount - to get us back in line. + * to get us back in line. */ dev->freesectors = freecount; @@ -761,13 +788,13 @@ static ssize_t smart_reload(struct smart_struct_s *dev, FAR uint8_t *buffer, static ssize_t smart_read(FAR struct inode *inode, unsigned char *buffer, size_t start_sector, unsigned int nsectors) { - struct smart_struct_s *dev; + FAR struct smart_struct_s *dev; fvdbg("SMART: sector: %d nsectors: %d\n", start_sector, nsectors); DEBUGASSERT(inode && inode->i_private); #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - dev = ((struct smart_multiroot_device_s*) inode->i_private)->dev; + dev = ((FAR struct smart_multiroot_device_s *)inode->i_private)->dev; #else dev = (struct smart_struct_s *)inode->i_private; #endif @@ -803,7 +830,7 @@ static ssize_t smart_write(FAR struct inode *inode, DEBUGASSERT(inode && inode->i_private); #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - dev = ((FAR struct smart_multiroot_device_s*) inode->i_private)->dev; + dev = ((FAR struct smart_multiroot_device_s *)inode->i_private)->dev; #else dev = (FAR struct smart_struct_s *)inode->i_private; #endif @@ -912,7 +939,7 @@ static int smart_geometry(FAR struct inode *inode, struct geometry *geometry) if (geometry) { #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - dev = ((FAR struct smart_multiroot_device_s*) inode->i_private)->dev; + dev = ((FAR struct smart_multiroot_device_s *)inode->i_private)->dev; #else dev = (FAR struct smart_struct_s *)inode->i_private; #endif @@ -924,14 +951,9 @@ static int smart_geometry(FAR struct inode *inode, struct geometry *geometry) geometry->geo_writeenabled = false; #endif - erasesize = dev->geo.erasesize; - if (erasesize == 0) - { - erasesize = 262144; - } - + erasesize = dev->geo.erasesize; geometry->geo_nsectors = dev->geo.neraseblocks * erasesize / - dev->sectorsize; + dev->sectorsize; geometry->geo_sectorsize = dev->sectorsize; fvdbg("available: true mediachanged: false writeenabled: %s\n", @@ -971,21 +993,12 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size) return OK; } - erasesize = dev->geo.erasesize; - dev->neraseblocks = dev->geo.neraseblocks; - - /* Most FLASH devices have erase size of 64K, but geo.erasesize is only - * 16 bits, so it will be zero - */ - - if (erasesize == 0) - { - erasesize = 262144; - } - - dev->erasesize = erasesize; - dev->sectorsize = size; + erasesize = dev->geo.erasesize; + dev->neraseblocks = dev->geo.neraseblocks; + dev->erasesize = erasesize; + dev->sectorsize = size; dev->mtdBlksPerSector = dev->sectorsize / dev->geo.blocksize; + if (erasesize / dev->sectorsize > 256) { /* We can't throw a dbg message here becasue it is too early. @@ -1006,6 +1019,10 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size) { dev->availSectPerBlk = 255; } + else if (dev->sectorsPerBlk == 0) + { + return -EINVAL; + } else { dev->availSectPerBlk = dev->sectorsPerBlk; @@ -1025,6 +1042,7 @@ static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size) smart_free(dev, dev->sMap); dev->sMap = NULL; } + #else if (dev->sBitMap != NULL) { @@ -1209,6 +1227,7 @@ errexit: { smart_free(dev, dev->sMap); } + #else if (dev->sBitMap) { @@ -1365,6 +1384,7 @@ static int smart_add_sector_to_cache(FAR struct smart_struct_s *dev, dev->sCache[index].birth = dev->cache_nextbirth++; dev->cache_lastlog = logical; dev->cache_lastphys = physical; + if (dev->debuglevel > 1) { dbg("Add Cache sector: Log=%d, Phys=%d at index %d from line %d\n", @@ -1451,7 +1471,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi /* Calculate the read address for this sector */ readaddress = block * dev->erasesize + - sector * CONFIG_MTD_SMART_SECTOR_SIZE; + sector * dev->sectorsize; /* Read the header for this sector */ @@ -1500,7 +1520,7 @@ static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logi /* This is the sector we are looking for! Add it to the cache */ physical = block * dev->sectorsPerBlk + sector; - smart_add_sector_to_cache(dev, logical, physical, __LINE__ ); + smart_add_sector_to_cache(dev, logical, physical, __LINE__); break; } } @@ -1543,7 +1563,7 @@ static void smart_update_cache(FAR struct smart_struct_s *dev, uint16_t dev->sCache[x].physical = physical; /* If we are freeing a sector, then remove the logical entry from - the cache. + * the cache. */ if (physical == 0xFFFF) @@ -1739,7 +1759,8 @@ static int smart_set_wear_level(FAR struct smart_struct_s *dev, uint16_t block, } /* Test if this was the min level. If it was, then - we need to rescan for min. */ + * we need to rescan for min. + */ if (oldlevel == dev->minwearlevel) { @@ -1826,6 +1847,10 @@ static int smart_scan(FAR struct smart_struct_s *dev) offset >>= 1; if (offset < 256 && sectorsize == 0xFFFF) { + /* No valid sectors found on device. Default the + * sector size to the CONFIG value + */ + sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE; } } @@ -1973,7 +1998,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) /* Read the sector data */ ret = MTD_READ(dev->mtd, readaddress, 32, - (FAR uint8_t*) dev->rwbuffer); + (FAR uint8_t *)dev->rwbuffer); if (ret != 32) { fdbg("Error reading physical sector %d.\n", sector); @@ -1986,12 +2011,13 @@ static int smart_scan(FAR struct smart_struct_s *dev) dev->rwbuffer[SMART_FMT_POS2] != SMART_FMT_SIG2 || dev->rwbuffer[SMART_FMT_POS3] != SMART_FMT_SIG3 || dev->rwbuffer[SMART_FMT_POS4] != SMART_FMT_SIG4) - { - /* Invalid signature on a sector claiming to be sector 0! - * What should we do? Release it?*/ + { + /* Invalid signature on a sector claiming to be sector 0! + * What should we do? Release it? + */ - continue; - } + continue; + } /* Mark the volume as formatted and set the sector size */ @@ -2023,8 +2049,8 @@ static int smart_scan(FAR struct smart_struct_s *dev) * the SMART device structure and the root directory number. */ - rootdirdev = (struct smart_multiroot_device_s*) smart_malloc(dev, - sizeof(*rootdirdev), "Root Dir"); + rootdirdev = (struct smart_multiroot_device_s *) + smart_malloc(dev, sizeof(*rootdirdev), "Root Dir"); if (rootdirdev == NULL) { fdbg("Memory alloc failed\n"); @@ -2058,7 +2084,6 @@ static int smart_scan(FAR struct smart_struct_s *dev) * to resolve who wins. */ - #if SMART_STATUS_VERSION == 1 if (header.status & SMART_STATUS_CRC) { @@ -2099,6 +2124,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) /* Get the logical sector number for this physical sector */ duplogsector = *((FAR uint16_t *) header.logicalsector); + #if CONFIG_SMARTFS_ERASEDSTATE == 0x00 if (duplogsector == 0) { @@ -2206,11 +2232,12 @@ static int smart_scan(FAR struct smart_struct_s *dev) dev->sMap[logicalsector] = sector; #else /* Mark the logical sector as used in the bitmap */ + dev->sBitMap[logicalsector >> 3] |= 1 << (logicalsector & 0x07); if (logicalsector < SMART_FIRST_ALLOC_SECTOR) { - smart_add_sector_to_cache(dev, logicalsector, sector, __LINE__ ); + smart_add_sector_to_cache(dev, logicalsector, sector, __LINE__); } #endif } @@ -2244,11 +2271,13 @@ static int smart_scan(FAR struct smart_struct_s *dev) goto err_out; } - /* Check for old format wear leveling */ + if (dev->rwbuffer[SMART_WEAR_LEVEL_FORMAT_SIG] == 0) { - /* Old format detected. We must relocate sector zero and fill it in with 0xFF */ + /* Old format detected. We must relocate sector zero and fill it + * in with 0xFF. + */ uint16_t newsector = smart_findfreephyssector(dev, FALSE); if (newsector == 0xFFFF) @@ -2280,7 +2309,6 @@ static int smart_scan(FAR struct smart_struct_s *dev) smart_add_count(dev, dev->freecount, newsector / dev->sectorsPerBlk, -1); smart_add_count(dev, dev->releasecount, sector / dev->sectorsPerBlk, 1); #endif - } } @@ -2298,6 +2326,17 @@ static int smart_scan(FAR struct smart_struct_s *dev) fdbg(" Erase count: %10d\n", dev->neraseblocks); fdbg(" Sect/block: %10d\n", dev->sectorsPerBlk); fdbg(" MTD Blk/Sect: %10d\n", dev->mtdBlksPerSector); + + /* Validate the geometry */ + + if (dev->mtdBlksPerSector == 0 || dev->sectorsPerBlk == 0 || + dev->sectorsPerBlk == 0 || dev->sectorsize == 0) + { + fdbg("Invalid Geometry!\n"); + ret = -EINVAL; + goto err_out; + } + #ifdef CONFIG_MTD_SMART_ALLOC_DEBUG fdbg(" Allocations:\n"); for (sector = 0; sector < SMART_MAX_ALLOCS; sector++) @@ -2411,7 +2450,8 @@ static void smart_erase_block_if_empty(FAR struct smart_struct_s *dev, freecount = dev->freecount[block]; #endif - if ((freecount + releasecount == dev->availSectPerBlk && freecount < 1) || forceerase) + if ((freecount + releasecount == dev->availSectPerBlk && freecount < 1) || + forceerase) { /* Erase the block */ @@ -2785,6 +2825,11 @@ static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev) * involves erasing the device and writing a valid sector * zero (logical) with proper format signature. * + * Input Parameters: + * + * arg: Upper 16 bits contains the sector size + * Lower 16 bits contains the number of root dir entries + * ****************************************************************************/ #ifdef CONFIG_FS_WRITABLE @@ -2795,24 +2840,29 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a int x; int ret; uint8_t sectsize, prerelease; + uint16_t sectorsize; fvdbg("Entry\n"); - smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE); + /* Get the sector size from the provided arg */ + + sectorsize = arg >> 16; + if (sectorsize == 0) + { + sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE; + } + + /* Set the sector size for the device */ + + smart_setsectorsize(dev, sectorsize); /* Check for invalid format */ - if (dev->erasesize == 0) + + if (dev->erasesize == 0 || dev->sectorsPerBlk == 0) { - if (dev->geo.erasesize == 0) - { - dev->erasesize = 262144; - } - else - { - dev->erasesize = dev->geo.erasesize; - } + dev->erasesize = dev->geo.erasesize; - dbg("ERROR: Invalid geometery ... Sectors per erase block must be 256 or less\n"); + dbg("ERROR: Invalid geometery ... Sectors per erase block must be 1-256\n"); dbg(" Erase block size = %d\n", dev->erasesize); dbg(" Sector size = %d\n", dev->sectorsize); dbg(" Sectors/erase block = %d\n", dev->erasesize / dev->sectorsize); @@ -2832,6 +2882,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a sectorheader = (FAR struct smart_sect_header_s *) dev->rwbuffer; memset(dev->rwbuffer, CONFIG_SMARTFS_ERASEDSTATE, dev->sectorsize); + #if SMART_STATUS_VERSION == 1 #ifdef CONFIG_MTD_SMART_ENABLE_CRC /* CRC enabled. Using an 8-bit sequence number */ @@ -2848,7 +2899,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* Set the sector size of this sector */ - sectsize = (CONFIG_MTD_SMART_SECTOR_SIZE >> 9) << 2; + sectsize = (sectorsize >> 9) << 2; /* Set the sector logical sector to zero and setup the header status */ @@ -2882,7 +2933,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* Record the number of root directory entries we have */ - dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) arg; + dev->rwbuffer[SMART_FMT_ROOTDIRS_POS] = (uint8_t) (arg & 0xFF); #ifdef CONFIG_SMART_CRC_8 sectorheader->crc8 = smart_calc_sector_crc(dev); @@ -2909,7 +2960,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a /* Now initialize our internal control variables */ - ret = smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE); + ret = smart_setsectorsize(dev, sectorsize); if (ret != OK) { return ret; @@ -2927,7 +2978,7 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a for (x = 0; x < dev->neraseblocks; x++) { /* Test for a geometry with 65536 sectors. We allow this, though - we never use the last two sectors in this mode. + * we never use the last two sectors in this mode. */ if (x == dev->neraseblocks && dev->totalsectors == 65534) @@ -2992,10 +3043,10 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a static int smart_relocate_sector(FAR struct smart_struct_s *dev, uint16_t oldsector, uint16_t newsector) { - int ret; size_t offset; FAR struct smart_sect_header_s *header; uint8_t newstatus; + int ret; header = (FAR struct smart_sect_header_s *) dev->rwbuffer; @@ -3159,7 +3210,8 @@ static int smart_relocate_block(FAR struct smart_struct_s *dev, uint16_t block) if (freecount >= dev->freesectors) { - fdbg("Program bug! Relocating the only block (%d) with free sectors!\n", block); + fdbg("Program bug! Relocating the only block (%d) with free sectors!\n", + block); ret = -EIO; goto errout; } @@ -3304,7 +3356,7 @@ static int smart_relocate_block(FAR struct smart_struct_s *dev, uint16_t block) if (x == dev->neraseblocks && dev->totalsectors == 65534) { /* We can't use the last two sectors on a 65536 sector device, - so "pre-release" them so they never get allocated. + * so "pre-release" them so they never get allocated. */ prerelease = 2; @@ -3331,7 +3383,8 @@ static int smart_relocate_block(FAR struct smart_struct_s *dev, uint16_t block) #ifdef CONFIG_SMART_LOCAL_CHECKFREE if (smart_checkfree(dev, __LINE__) != OK) { - fdbg(" ...while relocating block %d, free=%d, release=%d, oldrelease=%d\n", block, freecount, releasecount, oldrelease); + fdbg(" ...while relocating block %d, free=%d, release=%d, oldrelease=%d\n", + block, freecount, releasecount, oldrelease); } #endif @@ -3381,7 +3434,8 @@ static int smart_findfreephyssector(FAR struct smart_struct_s *dev, /* Determine which erase block we should allocate the new * sector from. This is based on the number of free sectors - * available in each erase block. */ + * available in each erase block. + */ #ifdef CONFIG_MTD_SMART_WEAR_LEVEL retry: @@ -3451,8 +3505,11 @@ retry: allocfreecount = count; } } + if (++block >= dev->neraseblocks) - block = 0; + { + block = 0; + } } /* Check if we found an allocblock. */ @@ -3485,6 +3542,7 @@ retry: block++; } + if (x > 0) { /* Disable relocate for retry */ @@ -3531,13 +3589,16 @@ retry: #ifdef CONFIG_MTD_SMART_ENABLE_CRC /* First check if there is a temporary alloc in place */ - FAR struct smart_allocsector_s* allocsect; + FAR struct smart_allocsector_s *allocsect; allocsect = dev->allocsector; while (allocsect) { if (allocsect->physical == x) - break; + { + break; + } + allocsect = allocsect->next; } @@ -3666,7 +3727,8 @@ static int smart_garbagecollect(FAR struct smart_struct_s *dev) collectblock = x; } #endif - } + } + //releasemax = smart_get_count(dev, dev->releasecount, collectblock); if (collectblock == 0xFFFF) @@ -3758,7 +3820,7 @@ static int smart_write_wearstatus(struct smart_struct_s *dev) } /* Test if we need to write either total block erase count or - uneven wearcount (or both) + * uneven wearcount (or both) */ if (write_buffer) @@ -3767,6 +3829,7 @@ static int smart_write_wearstatus(struct smart_struct_s *dev) req.offset = SMARTFS_FMT_WEAR_POS - 8; req.count = sizeof(buffer); req.buffer = buffer; + ret = smart_writesector(dev, (unsigned long) &req); if (ret != OK) { @@ -3781,9 +3844,9 @@ static int smart_write_wearstatus(struct smart_struct_s *dev) /* Calculate the number of bytes to write to this sector */ towrite = remaining; - if (towrite > dev->sectorsize - SMARTFS_FMT_WEAR_POS) + if (towrite > dev->sectorsize - (SMARTFS_FMT_WEAR_POS + sizeof(struct smart_sect_header_s))) { - towrite = dev->sectorsize - SMARTFS_FMT_WEAR_POS; + towrite = dev->sectorsize - (SMARTFS_FMT_WEAR_POS + sizeof(struct smart_sect_header_s)); } /* Setup the sector write request (we are our own client) */ @@ -3842,19 +3905,20 @@ errout: #ifdef CONFIG_MTD_SMART_WEAR_LEVEL static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev) { - uint16_t sector; - uint16_t remaining, toread; struct smart_read_write_s req; - int ret; - uint8_t buffer[8]; + uint16_t sector, physsector; + uint16_t remaining, toread; + uint8_t buffer[8]; + int ret; /* Prepare to read the total block erases and uneven wearcount values */ - sector = 0; + sector = 0; req.logsector = sector; - req.offset = SMARTFS_FMT_WEAR_POS - 8; - req.count = sizeof(buffer); - req.buffer = buffer; + req.offset = SMARTFS_FMT_WEAR_POS - 8; + req.count = sizeof(buffer); + req.buffer = buffer; + ret = smart_readsector(dev, (unsigned long) &req); if (ret != sizeof(buffer)) { @@ -3894,9 +3958,9 @@ static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev) /* Calculate number of bytes to read from this sector */ toread = remaining; - if (toread > dev->sectorsize - SMARTFS_FMT_WEAR_POS) + if (toread > dev->sectorsize - (SMARTFS_FMT_WEAR_POS + sizeof(struct smart_sect_header_s))) { - toread = dev->sectorsize - SMARTFS_FMT_WEAR_POS; + toread = dev->sectorsize - (SMARTFS_FMT_WEAR_POS + sizeof(struct smart_sect_header_s)); } /* Setup the sector read request (we are our own client) */ @@ -3907,6 +3971,29 @@ static inline int smart_read_wearstatus(FAR struct smart_struct_s *dev) req.buffer = &dev->wearstatus[(dev->geo.neraseblocks >> SMART_WEAR_BIT_DIVIDE) - remaining]; + /* Validate wear status sector has been allocated */ + +#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM + physsector = dev->sMap[req.logsector]; +#else + physsector = smart_cache_lookup(dev, req.logsector); +#endif + if ((sector != 0) && (physsector == 0xFFFF)) + { +#ifdef CONFIG_FS_WRITABLE + + /* This logical sector does not exist yet. We must allocate it */ + + ret = smart_allocsector(dev, sector); + if (ret != sector) + { + fdbg("Unable to allocate wear level status sector %d\n", sector); + ret = -EINVAL; + goto errout; + } +#endif + } + /* Read the sector */ ret = smart_readsector(dev, (unsigned long) &req); @@ -4009,7 +4096,7 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev, /* The block is not empty!! What to do? */ fdbg("Write block %d failed: %d.\n", physical * - dev->mtdBlksPerSector, ret); + dev->mtdBlksPerSector, ret); /* Unlock the mutex if we add one */ @@ -4223,9 +4310,9 @@ static int smart_writesector(FAR struct smart_struct_s *dev, #endif /* CONFIG_MTD_SMART_ENABLE_CRC */ /* If we are not using CRC and on a device that supports re-writing - bits from 1 to 0 without neededing a block erase, such as NOR - FLASH, then we can simply update the data in place and don't need - to relocate the sector. Test if we need to relocate or not. + * bits from 1 to 0 without neededing a block erase, such as NOR + * FLASH, then we can simply update the data in place and don't need + * to relocate the sector. Test if we need to relocate or not. */ if (needsrelocate) @@ -4393,7 +4480,8 @@ static int smart_writesector(FAR struct smart_struct_s *dev, ret = smart_bytewrite(dev, offset, 1, &byte); /* Update releasecount for released sector and freecount for the - * newly allocated physical sector. */ + * newly allocated physical sector. + */ block = oldphyssector / dev->sectorsPerBlk; #ifdef CONFIG_MTD_SMART_PACK_COUNTS @@ -4465,7 +4553,8 @@ static int smart_writesector(FAR struct smart_struct_s *dev, } #else /* Not relocated. Just write the portion of the sector that needs - * to be written. */ + * to be written. + */ offset = mtdblock * dev->geo.blocksize + sizeof(struct smart_sect_header_s) + req->offset; @@ -4506,7 +4595,8 @@ static int smart_readsector(FAR struct smart_struct_s *dev, fvdbg("Entry\n"); req = (FAR struct smart_read_write_s *) arg; DEBUGASSERT(req->offset < dev->sectorsize); - DEBUGASSERT(req->offset+req->count < dev->sectorsize); + DEBUGASSERT(req->offset+req->count+ sizeof(struct smart_sect_header_s) <= + dev->sectorsize); /* Ensure the logical sector has been allocated */ @@ -4532,20 +4622,20 @@ static int smart_readsector(FAR struct smart_struct_s *dev, #ifdef CONFIG_MTD_SMART_ENABLE_CRC - /* When CRC is enabled, we read the entire sector into RAM so we can - * validate the CRC. - */ + /* When CRC is enabled, we read the entire sector into RAM so we can + * validate the CRC. + */ - ret = MTD_BREAD(dev->mtd, physsector * dev->mtdBlksPerSector, - dev->mtdBlksPerSector, (FAR uint8_t *) dev->rwbuffer); - if (ret != dev->mtdBlksPerSector) - { - /* TODO: Mark the block bad */ + ret = MTD_BREAD(dev->mtd, physsector * dev->mtdBlksPerSector, + dev->mtdBlksPerSector, (FAR uint8_t *) dev->rwbuffer); + if (ret != dev->mtdBlksPerSector) + { + /* TODO: Mark the block bad */ - fdbg("Error reading phys sector %d\n", physsector); - ret = -EIO; - goto errout; - } + fdbg("Error reading phys sector %d\n", physsector); + ret = -EIO; + goto errout; + } #if SMART_STATUS_VERSION == 1 /* Test if this sector has CRC enabled or not */ @@ -4556,7 +4646,6 @@ static int smart_readsector(FAR struct smart_struct_s *dev, /* Format VERSION 1 supports either no CRC or 8-bit CRC. Looks like * CRC not enabled for this sector, so skip the CRC test. */ - } else #endif @@ -4610,7 +4699,7 @@ static int smart_readsector(FAR struct smart_struct_s *dev, /* Read the sector data into the buffer */ readaddr = (uint32_t) physsector * dev->mtdBlksPerSector * dev->geo.blocksize + - req->offset + sizeof(struct smart_sect_header_s);; + req->offset + sizeof(struct smart_sect_header_s); ret = MTD_READ(dev->mtd, readaddr, req->count, (FAR uint8_t *) req->buffer); @@ -4639,16 +4728,17 @@ errout: static inline int smart_allocsector(FAR struct smart_struct_s *dev, unsigned long requested) { - int x; uint16_t logsector = 0xFFFF; /* Logical sector number selected */ uint16_t physicalsector; /* The selected physical sector */ #ifndef CONFIG_MTD_SMART_ENABLE_CRC int ret; #endif + int x; /* Validate that we have enough sectors available to perform an * allocation. We have to ensure we keep enough reserved sectors - * on hand to do released sector garbage collection. */ + * on hand to do released sector garbage collection. + */ if (dev->freesectors <= (dev->sectorsPerBlk << 0) + 4) { @@ -4662,7 +4752,9 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, smart_garbagecollect(dev); if (dev->freesectors > dev->availSectPerBlk + 4) - break; + { + break; + } } if (dev->freesectors <= (dev->availSectPerBlk << 0) + 4) @@ -4681,9 +4773,10 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, } /* Check if a specific sector is being requested and allocate that - * sector if it isn't already in use */ + * sector if it isn't already in use. + */ - if ((requested > 2) && (requested < dev->totalsectors)) + if ((requested > 0) && (requested < dev->totalsectors)) { /* Validate the sector is not already allocated */ @@ -4697,6 +4790,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, FAR struct smart_allocsector_s *allocsect; /* Ensure this logical sector doesn't have a temporary alloc */ + allocsect = dev->allocsector; while (allocsect) { @@ -4776,7 +4870,8 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, * something happened and we didn't find any free * logical sectors. What do do? Report an error? * rescan and try again to "self heal" in case of a - * bug in our code? */ + * bug in our code? + */ fdbg("No free logical sector numbers! Free sectors = %d\n", dev->freesectors); @@ -4788,7 +4883,8 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, * ensure we keep enough reserved free sectors to perform garbage * collection as it involves moving sectors from blocks with * released sectors into blocks with free sectors, then - * erasing the vacated block. */ + * erasing the vacated block. + */ smart_garbagecollect(dev); @@ -4797,7 +4893,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, physicalsector = smart_findfreephyssector(dev, FALSE); fvdbg("Alloc: log=%d, phys=%d, erase block=%d, free=%d, released=%d\n", logsector, physicalsector, physicalsector / - dev->sectorsPerBlk, dev->freesectors, releasecount); + dev->sectorsPerBlk, dev->freesectors, dev->releasecount); #ifdef CONFIG_MTD_SMART_ENABLE_CRC @@ -4844,7 +4940,7 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev, dev->sMap[logsector] = physicalsector; #else dev->sBitMap[logsector >> 3] |= (1 << (logsector & 0x07)); - smart_add_sector_to_cache(dev, logsector, physicalsector, __LINE__ ); + smart_add_sector_to_cache(dev, logsector, physicalsector, __LINE__); #endif #ifdef CONFIG_MTD_SMART_PACK_COUNTS @@ -4991,7 +5087,7 @@ static int smart_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) DEBUGASSERT(inode && inode->i_private); #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - dev = ((FAR struct smart_multiroot_device_s*) inode->i_private)->dev; + dev = ((FAR struct smart_multiroot_device_s *)inode->i_private)->dev; #else dev = (FAR struct smart_struct_s *)inode->i_private; #endif @@ -5027,7 +5123,7 @@ static int smart_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS ret = smart_getformat(dev, (FAR struct smart_format_s *) arg, - ((FAR struct smart_multiroot_device_s*) inode->i_private)->rootdirnum); + ((FAR struct smart_multiroot_device_s *)inode->i_private)->rootdirnum); #else ret = smart_getformat(dev, (FAR struct smart_format_s *) arg); #endif @@ -5049,6 +5145,13 @@ static int smart_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) case BIOC_ALLOCSECT: + /* Ensure the FS is not trying to allocate a reserved sector */ + + if (arg < 3) + { + arg = (unsigned long) -1; + } + /* Allocate a logical sector for the upper layer file system */ ret = smart_allocsector(dev, arg); @@ -5292,8 +5395,8 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partn * the SMART device structure and the root directory number. */ - rootdirdev = (FAR struct smart_multiroot_device_s*) smart_malloc(dev, - sizeof(*rootdirdev), "Root Dir"); + rootdirdev = (FAR struct smart_multiroot_device_s *) + smart_malloc(dev, sizeof(*rootdirdev), "Root Dir"); if (rootdirdev == NULL) { fdbg("register_blockdriver failed: %d\n", -ret); @@ -5333,6 +5436,10 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partn smart_scan(dev); } +#ifdef CONFIG_SMART_DEV_LOOP + (void)register_driver("/dev/smart", &g_fops, 0666, NULL); +#endif + return OK; errout: @@ -5352,10 +5459,217 @@ errout: #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS if (rootdirdev) { - smart_free(dev,rootdirdev); + smart_free(dev, rootdirdev); } #endif kmm_free(dev); return ret; } + + /**************************************************************************** + * Name: smart_losetup + * + * Description: Dynamically setups up a SMART enabled loop device that + * is backed by a file. The resulting loop device is a + * MTD type block device vs. a generic block device. + * + ****************************************************************************/ + +#ifdef CONFIG_SMART_DEV_LOOP +static int smart_losetup(int minor, FAR const char *filename, + int sectsize, int erasesize, off_t offset, bool readonly) +{ + FAR struct mtd_dev_s *mtd; + struct stat sb; + int x, ret; + char devpath[20]; + + /* Try to create a filemtd device using the filename provided */ + + mtd = filemtd_initialize(filename, offset, sectsize, erasesize); + if (mtd == NULL) + { + return -ENOENT; + } + + /* Check if we need to dynamically assign a minor number */ + + if (minor == -1) + { + /* Start at zero and stat /dev/smartX until no entry found. + * Searching 0 to 256 should be sufficient. + */ + + for (x = 0; x < 256; x++) + { + snprintf(devpath, sizeof(devpath), "/dev/smart%d", x); + ret = stat(devpath, &sb); + if (ret != 0) + { + /* We can use this minor number */ + + minor = x; + break; + } + } + } + + /* Now create a smart MTD using the filemtd backing it */ + + ret = smart_initialize(minor, mtd, NULL); + + if (ret != OK) + { + filemtd_teardown(mtd); + } + + return ret; +} +#endif /* CONFIG_SMART_DEV_LOOP */ + +/**************************************************************************** + * Name: loteardown + * + * Description: + * Undo the setup performed by losetup + * + ****************************************************************************/ + +#ifdef CONFIG_SMART_DEV_LOOP +static int smart_loteardown(FAR const char *devname) +{ + FAR struct smart_struct_s *dev; + FAR struct inode *inode; + int ret; + + /* Sanity check */ + +#ifdef CONFIG_DEBUG + if (!devname) + { + return -EINVAL; + } +#endif + + /* Open the block driver associated with devname so that we can get the inode + * reference. + */ + + ret = open_blockdriver(devname, MS_RDONLY, &inode); + if (ret < 0) + { + dbg("Failed to open %s: %d\n", devname, -ret); + return ret; + } + + /* Inode private data is a reference to the loop device structure */ + + dev = (FAR struct smart_struct_s *)inode->i_private; + + /* Validate this is a filemtd backended device */ + + if (!filemtd_isfilemtd(dev->mtd)) + { + fdbg("Device is not a SMART loop: %s\n", devname); + return -EINVAL; + } + + close_blockdriver(inode); + + /* Now teardown the filemtd */ + + filemtd_teardown(dev->mtd); + unregister_blockdriver(devname); + + kmm_free(dev); + + return OK; +} +#endif /* CONFIG_SMART_DEV_LOOP */ + +/**************************************************************************** + * Name: smart_loop_read + ****************************************************************************/ + +#ifdef CONFIG_SMART_DEV_LOOP +static ssize_t smart_loop_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + return 0; /* Return EOF */ +} +#endif /* CONFIG_SMART_DEV_LOOP */ + +/**************************************************************************** + * Name: smart_loop_write + ****************************************************************************/ + +#ifdef CONFIG_SMART_DEV_LOOP +static ssize_t smart_loop_write(FAR struct file *filep, FAR const char *buffer, size_t len) +{ + return len; /* Say that everything was written */ +} +#endif /* CONFIG_SMART_DEV_LOOP */ + +/**************************************************************************** + * Name: smart_loop_ioctl + ****************************************************************************/ + +#ifdef CONFIG_SMART_DEV_LOOP +static int smart_loop_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + int ret; + + switch (cmd) + { + /* Command: LOOPIOC_SETUP + * Description: Setup the loop device + * Argument: A pointer to a read-only instance of struct losetup_s. + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + + case SMART_LOOPIOC_SETUP: + { + FAR struct smart_losetup_s *setup = (FAR struct smart_losetup_s *)((uintptr_t)arg); + + if (setup == NULL) + { + ret = -EINVAL; + } + else + { + ret = smart_losetup(setup->minor, setup->filename, setup->sectsize, + setup->erasesize, setup->offset, setup->readonly); + } + } + break; + + /* Command: LOOPIOC_TEARDOWN + * Description: Teardown a loop device previously setup vis LOOPIOC_SETUP + * Argument: A read-able pointer to the path of the device to be + * torn down + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + + case SMART_LOOPIOC_TEARDOWN: + { + FAR const char *devname = (FAR const char *)((uintptr_t)arg); + + if (devname == NULL) + { + ret = -EINVAL; + } + else + { + ret = smart_loteardown(devname); + } + } + break; + + default: + ret = -ENOTTY; + } + + return ret; +} +#endif /* CONFIG_SMART_DEV_LOOP */ + diff --git a/drivers/mtd/sst25.c b/drivers/mtd/sst25.c index c4c49c7ee7b3f7915ca870e5667c83581d806dd1..61a79a63b5e09c1345ad66a4db80f18cdec58699 100644 --- a/drivers/mtd/sst25.c +++ b/drivers/mtd/sst25.c @@ -139,8 +139,8 @@ #define SST25_DUMMY 0xa5 /* Chip Geometries ******************************************************************/ -/* SST25VF512 capacity is 512Kbit (64Kbit x 8) = 64Kb (8Kb x 8)*/ -/* SST25VF010 capacity is 1Mbit (128Kbit x 8) = 128Kb (16Kb x 8*/ +/* SST25VF512 capacity is 512Kbit (64Kbit x 8) = 64Kb (8Kb x 8) */ +/* SST25VF010 capacity is 1Mbit (128Kbit x 8) = 128Kb (16Kb x 8 */ /* SST25VF520 capacity is 2Mbit (256Kbit x 8) = 256Kb (32Kb x 8) */ /* SST25VF540 capacity is 4Mbit (512Kbit x 8) = 512Kb (64Kb x 8) */ /* SST25VF080 capacity is 8Mbit (1024Kbit x 8) = 1Mb (128Kb x 8) */ @@ -199,7 +199,7 @@ struct sst25_dev_s #if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY) uint8_t flags; /* Buffered sector flags */ - uint16_t esectno; /* Erase sector number in the cache*/ + uint16_t esectno; /* Erase sector number in the cache */ FAR uint8_t *sector; /* Allocated sector data */ #endif }; @@ -286,6 +286,7 @@ static void sst25_lock(FAR struct spi_dev_s *dev) SPI_SETMODE(dev, CONFIG_SST25_SPIMODE); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, CONFIG_SST25_SPIFREQUENCY); } @@ -395,34 +396,6 @@ static uint8_t sst25_waitwritecomplete(struct sst25_dev_s *priv) { uint8_t status; - /* Are we the only device on the bus? */ - -#ifdef CONFIG_SPI_OWNBUS - - /* Select this FLASH part */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, true); - - /* Send "Read Status Register (RDSR)" command */ - - (void)SPI_SEND(priv->dev, SST25_RDSR); - - /* Loop as long as the memory is busy with a write cycle */ - - do - { - /* Send a dummy byte to generate the clock needed to shift out the status */ - - status = SPI_SEND(priv->dev, SST25_DUMMY); - } - while ((status & SST25_SR_BUSY) != 0); - - /* Deselect the FLASH */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, false); - -#else - /* Loop as long as the memory is busy with a write cycle */ do @@ -458,7 +431,6 @@ static uint8_t sst25_waitwritecomplete(struct sst25_dev_s *priv) #endif } while ((status & SST25_SR_BUSY) != 0); -#endif return status; } @@ -583,7 +555,7 @@ static void sst25_byteread(FAR struct sst25_dev_s *priv, FAR uint8_t *buffer, /* Wait for any preceding write or erase operation to complete. */ status = sst25_waitwritecomplete(priv); - DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0); + DEBUGASSERT((status & (SST25_SR_WEL | SST25_SR_BP_MASK | SST25_SR_AAI)) == 0); UNUSED(status); /* Select this FLASH part */ @@ -643,7 +615,7 @@ static void sst25_bytewrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer, /* Wait for any preceding write or erase operation to complete. */ status = sst25_waitwritecomplete(priv); - DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0); + DEBUGASSERT((status & (SST25_SR_WEL | SST25_SR_BP_MASK | SST25_SR_AAI)) == 0); /* Enable write access to the FLASH */ @@ -723,7 +695,7 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer, /* Wait for any preceding write or erase operation to complete. */ status = sst25_waitwritecomplete(priv); - DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0); + DEBUGASSERT((status & (SST25_SR_WEL | SST25_SR_BP_MASK | SST25_SR_AAI)) == 0); UNUSED(status); /* Enable write access to the FLASH */ @@ -755,7 +727,8 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer, /* Wait for the preceding write to complete. */ status = sst25_waitwritecomplete(priv); - DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI)); + DEBUGASSERT((status & (SST25_SR_WEL | SST25_SR_BP_MASK | SST25_SR_AAI)) == + (SST25_SR_WEL | SST25_SR_AAI)); UNUSED(status); /* Decrement the word count and advance the write position */ @@ -793,7 +766,8 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer, /* Wait for the preceding write to complete. */ status = sst25_waitwritecomplete(priv); - DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI)); + DEBUGASSERT((status & (SST25_SR_WEL | SST25_SR_BP_MASK | SST25_SR_AAI)) == + (SST25_SR_WEL | SST25_SR_AAI)); UNUSED(status); /* Decrement the word count and advance the write position */ diff --git a/drivers/mtd/sst25xx.c b/drivers/mtd/sst25xx.c index 8598dd51d728743b661b883a3f8fc39ecfa57acf..ebbcfd33f2fab290ec517080a1476336380e601c 100644 --- a/drivers/mtd/sst25xx.c +++ b/drivers/mtd/sst25xx.c @@ -236,6 +236,7 @@ static void sst25xx_lock(FAR struct spi_dev_s *dev) SPI_SETMODE(dev, CONFIG_SST25XX_SPIMODE); SPI_SETBITS(dev, 8); + (void)SPI_HWFEATURES(dev, 0); (void)SPI_SETFREQUENCY(dev, CONFIG_SST25XX_SPIFREQUENCY); } @@ -314,36 +315,10 @@ static void sst25xx_waitwritecomplete(struct sst25xx_dev_s *priv) #if 0 if (!priv->lastwaswrite) - return; -#endif - - /* Are we the only device on the bus? */ - -#ifdef CONFIG_SPI_OWNBUS - - /* Select this FLASH part */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, true); - - /* Send "Read Status Register (RDSR)" command */ - - (void)SPI_SEND(priv->dev, SST25_RDSR); - - /* Loop as long as the memory is busy with a write cycle */ - - do { - /* Send a dummy byte to generate the clock needed to shift out the status */ - - status = SPI_SEND(priv->dev, SST25_DUMMY); + return; } - while ((status & SST25_SR_WIP) != 0); - - /* Deselect the FLASH */ - - SPI_SELECT(priv->dev, SPIDEV_FLASH, false); - -#else +#endif /* Loop as long as the memory is busy with a write cycle */ @@ -379,8 +354,6 @@ static void sst25xx_waitwritecomplete(struct sst25xx_dev_s *priv) } while ((status & SST25_SR_WIP) != 0); -#endif - priv->lastwaswrite = false; fvdbg("Complete\n"); diff --git a/drivers/mtd/sst39vf.c b/drivers/mtd/sst39vf.c index e2fe862c9eb327033eadc3c4eb1a276908ac6403..5386427587b372a731155e5e676f0e20bf361673 100644 --- a/drivers/mtd/sst39vf.c +++ b/drivers/mtd/sst39vf.c @@ -417,8 +417,8 @@ static int sst39vf_chiperase(FAR struct sst39vf_dev_s *priv) { #if 0 struct sst39vf_wrinfo_s wrinfo; - uint32_t start; - uint32_t elapsed; + systime_t start; + systime_t elapsed; #endif /* Send the sequence to erase the chip */ @@ -488,8 +488,8 @@ static int sst39vf_sectorerase(FAR struct sst39vf_dev_s *priv, { struct sst39vf_wrinfo_s wrinfo; #if 0 - uint32_t start; - uint32_t elapsed; + systime_t start; + systime_t elapsed; #endif /* Set up the sector address */ diff --git a/drivers/mtd/w25.c b/drivers/mtd/w25.c index f84643d037617e4eace4d12e86a8d87a10121da7..09a7c015d2581f0e40b7f2cb02a7ba1fe572b61c 100644 --- a/drivers/mtd/w25.c +++ b/drivers/mtd/w25.c @@ -273,6 +273,10 @@ static ssize_t w25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t w25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, FAR uint8_t *buffer); static int w25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); +#if defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) +static ssize_t w25_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR const uint8_t *buffer); +#endif /************************************************************************************ * Private Data @@ -306,6 +310,7 @@ static void w25_lock(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_W25_SPIMODE); SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); (void)SPI_SETFREQUENCY(spi, CONFIG_W25_SPIFREQUENCY); } @@ -467,34 +472,6 @@ static uint8_t w25_waitwritecomplete(struct w25_dev_s *priv) { uint8_t status; - /* Are we the only device on the bus? */ - -#ifdef CONFIG_SPI_OWNBUS - - /* Select this FLASH part */ - - SPI_SELECT(priv->spi, SPIDEV_FLASH, true); - - /* Send "Read Status Register (RDSR)" command */ - - (void)SPI_SEND(priv->spi, W25_RDSR); - - /* Loop as long as the memory is busy with a write cycle */ - - do - { - /* Send a dummy byte to generate the clock needed to shift out the status */ - - status = SPI_SEND(priv->spi, W25_DUMMY); - } - while ((status & W25_SR_BUSY) != 0); - - /* Deselect the FLASH */ - - SPI_SELECT(priv->spi, SPIDEV_FLASH, false); - -#else - /* Loop as long as the memory is busy with a write cycle */ do @@ -530,7 +507,6 @@ static uint8_t w25_waitwritecomplete(struct w25_dev_s *priv) #endif } while ((status & W25_SR_BUSY) != 0); -#endif return status; } @@ -657,7 +633,7 @@ static void w25_byteread(FAR struct w25_dev_s *priv, FAR uint8_t *buffer, /* Wait for any preceding write or erase operation to complete. */ status = w25_waitwritecomplete(priv); - DEBUGASSERT((status & (W25_SR_WEL|W25_SR_BP_MASK)) == 0); + DEBUGASSERT((status & (W25_SR_WEL | W25_SR_BP_MASK)) == 0); /* Make sure that writing is disabled */ @@ -715,7 +691,7 @@ static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, /* Wait for any preceding write or erase operation to complete. */ status = w25_waitwritecomplete(priv); - DEBUGASSERT((status & (W25_SR_WEL|W25_SR_BP_MASK)) == 0); + DEBUGASSERT((status & (W25_SR_WEL | W25_SR_BP_MASK)) == 0); /* Enable write access to the FLASH */ @@ -755,6 +731,53 @@ static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, } #endif +/************************************************************************************ + * Name: w25_bytewrite + ************************************************************************************/ + +#if defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) +static inline void w25_bytewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, + off_t offset, uint16_t count) +{ + fvdbg("offset: %08lx count:%d\n", (long)offset, count); + + /* Wait for any preceding write to complete. We could simplify things by + * perform this wait at the end of each write operation (rather than at + * the beginning of ALL operations), but have the wait first will slightly + * improve performance. + */ + + w25_waitwritecomplete(priv); + + /* Enable the write access to the FLASH */ + + w25_wren(priv); + + /* Select this FLASH part */ + + SPI_SELECT(priv->spi, SPIDEV_FLASH, true); + + /* Send "Page Program (PP)" command */ + + (void)SPI_SEND(priv->spi, W25_PP); + + /* Send the page offset high byte first. */ + + (void)SPI_SEND(priv->spi, (offset >> 16) & 0xff); + (void)SPI_SEND(priv->spi, (offset >> 8) & 0xff); + (void)SPI_SEND(priv->spi, offset & 0xff); + + /* Then write the specified number of bytes */ + + SPI_SNDBLOCK(priv->spi, buffer, count); + + /* Deselect the FLASH: Chip Select high */ + + SPI_SELECT(priv->spi, SPIDEV_FLASH, false); + fvdbg("Written\n"); +} +#endif /* defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) */ + /************************************************************************************ * Name: w25_cacheflush ************************************************************************************/ @@ -771,7 +794,7 @@ static void w25_cacheflush(struct w25_dev_s *priv) { /* Write entire erase block to FLASH */ - w25_pagewrite(priv, priv->sector, (off_t)priv->esectno << W25_SECTOR_SHIFT, + w25_pagewrite(priv, priv->sector, (off_t)priv->esectno << W25_PAGE_SHIFT, W25_SECTOR_SIZE); /* The case is no long dirty and the FLASH is no longer erased */ @@ -982,10 +1005,10 @@ static ssize_t w25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nbl nbytes >>= W25_SECTOR512_SHIFT; } #else - nbytes = w25_read(dev, startblock << W25_SECTOR_SHIFT, nblocks << W25_SECTOR_SHIFT, buffer); + nbytes = w25_read(dev, startblock << W25_PAGE_SHIFT, nblocks << W25_PAGE_SHIFT, buffer); if (nbytes > 0) { - nbytes >>= W25_SECTOR_SHIFT; + nbytes >>= W25_PAGE_SHIFT; } #endif @@ -1013,8 +1036,8 @@ static ssize_t w25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nb #if defined(CONFIG_W25_SECTOR512) w25_cachewrite(priv, buffer, startblock, nblocks); #else - w25_pagewrite(priv, buffer, startblock << W25_SECTOR_SHIFT, - nblocks << W25_SECTOR_SHIFT); + w25_pagewrite(priv, buffer, startblock << W25_PAGE_SHIFT, + nblocks << W25_PAGE_SHIFT); #endif w25_unlock(priv->spi); @@ -1043,6 +1066,76 @@ static ssize_t w25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, return nbytes; } +/************************************************************************************ + * Name: w25_write + ************************************************************************************/ + +#if defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) +static ssize_t w25_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, + FAR const uint8_t *buffer) +{ + FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev; + int startpage; + int endpage; + int count; + int index; + int bytestowrite; + + fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + + /* We must test if the offset + count crosses one or more pages + * and perform individual writes. The devices can only write in + * page increments. + */ + + startpage = offset / W25_PAGE_SIZE; + endpage = (offset + nbytes) / W25_PAGE_SIZE; + + if (startpage == endpage) + { + /* All bytes within one programmable page. Just do the write. */ + + w25_bytewrite(priv, buffer, offset, nbytes); + } + else + { + /* Write the 1st partial-page */ + + count = nbytes; + bytestowrite = W25_PAGE_SIZE - (offset & (W25_PAGE_SIZE-1)); + w25_bytewrite(priv, buffer, offset, bytestowrite); + + /* Update offset and count */ + + offset += bytestowrite; + count -= bytestowrite; + index = bytestowrite; + + /* Write full pages */ + + while (count >= W25_PAGE_SIZE) + { + w25_bytewrite(priv, &buffer[index], offset, W25_PAGE_SIZE); + + /* Update offset and count */ + + offset += W25_PAGE_SIZE; + count -= W25_PAGE_SIZE; + index += W25_PAGE_SIZE; + } + + /* Now write any partial page at the end */ + + if (count > 0) + { + w25_bytewrite(priv, &buffer[index], offset, count); + } + } + + return nbytes; +} +#endif /* defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) */ + /************************************************************************************ * Name: w25_ioctl ************************************************************************************/ @@ -1075,7 +1168,7 @@ static int w25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) geo->erasesize = (1 << W25_SECTOR512_SHIFT); geo->neraseblocks = priv->nsectors << (W25_SECTOR_SHIFT - W25_SECTOR512_SHIFT); #else - geo->blocksize = W25_SECTOR_SIZE; + geo->blocksize = W25_PAGE_SIZE; geo->erasesize = W25_SECTOR_SIZE; geo->neraseblocks = priv->nsectors; #endif @@ -1147,6 +1240,9 @@ FAR struct mtd_dev_s *w25_initialize(FAR struct spi_dev_s *spi) priv->mtd.bwrite = w25_bwrite; priv->mtd.read = w25_read; priv->mtd.ioctl = w25_ioctl; +#if defined(CONFIG_MTD_BYTE_WRITE) && !defined(CONFIG_W25_READONLY) + priv->mtd.write = w25_write; +#endif priv->spi = spi; /* Deselect the FLASH */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 32c87c7e0c751946a484485b651cbecdea1ab1cf..49ad8d710fd25b0191d1eb9bdbcac157148c6574 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -5,12 +5,64 @@ comment "General Ethernet MAC Driver Options" +config NETDEV_LOOPBACK + bool + default n if !NET_LOOPBACK + default y if NET_LOOPBACK + select NET_NOINTS + select ARCH_HAVE_NETDEV_STATISTICS + ---help--- + Add support for the local network loopback device, lo. Any additional + networking devices that are enabled must be compatible with + CONFIG_NET_NOINTS. + +config NETDEV_TELNET + bool "Telnet driver" + default n + depends on NET && NET_TCP + ---help--- + The Telnet driver generates a character driver instance to support a + Telnet session. This driver is used by the Telnet daemon. The + Telnet daeman will instantiate a new Telnet driver to support + standard I/O on the new Telnet session. + +if NETDEV_TELNET + +config TELNET_RXBUFFER_SIZE + int "Telnet RX buffer size" + default 256 + +config TELNET_TXBUFFER_SIZE + int "Telnet TX buffer size" + default 256 + +config TELNET_DUMPBUFFER + bool "Dump Telnet buffers" + default n + depends on DEBUG_NET + +endif # NETDEV_TELNET + config NETDEV_MULTINIC bool "Multiple network interface support" - default n + default n if !NETDEV_LOOPBACK + default y if NETDEV_LOOPBACK ---help--- Select this option if you board and/or MCU are capable of supporting - multiple Ethernet MAC drivers. + multiple link layer drivers. NOTE that the local loopback device + is considered to be a a link layer driver so if local loopback + support is used you probably need to select this option. + +config ARCH_HAVE_NETDEV_STATISTICS + bool + default n + +config NETDEV_STATISTICS + bool "Network device driver statistics" + depends on NET_STATISTICS && ARCH_HAVE_NETDEV_STATISTICS + ---help--- + Enable to collect statistics from the network drivers (if supported + by the network driver). config NETDEV_LATEINIT bool "Late driver initialization" @@ -55,6 +107,7 @@ comment "External Ethernet MAC Device Support" menuconfig NET_DM90x0 bool "Davicom dm9000/dm9010 support" default n + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: Davicom data sheets (DM9000-DS-F03-041906.pdf, DM9010-DS-F01-103006.pdf) and looking at lots of other DM90x0 @@ -119,23 +172,21 @@ config DM9X_NINTERFACES default 1 depends on EXPERIMENTAL -config DM9X_STATS - bool "DM90x0 statistics" - default n - -endif # NET_DM90x0 +endif # NET_DM90x0 config NET_CS89x0 bool "CS89x0 support" default n depends on EXPERIMENTAL + select ARCH_HAVE_NETDEV_STATISTICS ---help--- - Under construction -- do not use + Under construction -- do not use menuconfig ENC28J60 bool "Microchip ENC28J60 support" default n select SPI + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: ENC28J60 Data Sheet, Stand-Alone Ethernet Controller with SPI Interface, @@ -167,12 +218,6 @@ config ENC28J60_FREQUENCY ---help--- Define to use a different bus frequency -config ENC28J60_STATS - bool "Network statistics support" - default n - ---help--- - Collect network statistics - config ENC28J60_HALFDUPPLEX bool "Enable half dupplex" default n @@ -200,6 +245,7 @@ menuconfig ENCX24J600 default n select SPI select NET_RXAVAIL + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: ENC424J600/624J600 Data Sheet Stand-Alone 10/100 Ethernet Controller @@ -240,12 +286,6 @@ config ENCX24J600_NRXDESCR The ENC has a relative large packet buffer of 24kB which can be used to buffer multiple packets silmutaneously -config ENCX24J600_STATS - bool "Network statistics support" - default n - ---help--- - Collect network statistics - config ENCX24J600_DUMPPACKET bool "Dump Packets" default n @@ -285,6 +325,7 @@ endif # NET_E1000 menuconfig NET_SLIP bool "SLIP (serial line) support" default n + select ARCH_HAVE_NETDEV_STATISTICS ---help--- Reference: RFC 1055 @@ -302,23 +343,6 @@ config NET_SLIP_DEFPRIO ---help--- Provides the priority for SLIP RX and TX threads. -config NET_SLIP_MTU - int "Packet size (MTU)" - default 296 - ---help--- - Provides the size of the SLIP packet buffers. - - The Linux slip module hard-codes its MTU size to 296 (40 bytes for - the IP+TPC headers plus 256 bytes of data). So you might as well - set CONFIG_NET_SLIP_MTU to 296 as well. - - There may be an issue with this setting, however. I see that Linux - uses a MTU of 296 and window of 256, but actually only sends 168 - bytes of data: 40 + 128. I believe that is to allow for the 2x - worst cast packet expansion. Ideally we would like to advertise the - 256 MSS, but restrict transfers to 128 bytes (possibly by modifying - the tcp_mss() macro). - config NET_SLIP_NINTERFACES int "Number of SLIP interfaces" default 1 diff --git a/drivers/net/Make.defs b/drivers/net/Make.defs index 1af43565653479cc05fc6f9b294bf53ed1b10db9..fe68efb267aee7bf7a7f9efa1e2c2dc9f00c7f56 100644 --- a/drivers/net/Make.defs +++ b/drivers/net/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/net/Make.defs # -# Copyright (C) 2007, 2010-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2007, 2010-2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -39,6 +39,14 @@ ifeq ($(CONFIG_NET),y) # Include network interface drivers +ifeq ($(CONFIG_NETDEV_LOOPBACK),y) + CSRCS += loopback.c +endif + +ifeq ($(CONFIG_NETDEV_TELNET),y) + CSRCS += telnet.c +endif + ifeq ($(CONFIG_NET_DM90x0),y) CSRCS += dm90x0.c endif diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 1b278829121ac57db3c15c2268e6f19d58305152..dfaf2d63840af554d4ca9c32961b713814672679 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/cs89x0.c * - * Copyright (C) 2009-2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -76,7 +76,6 @@ /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define CS89x0_WDDELAY (1*CLK_TCK) -#define CS89x0_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -219,9 +218,9 @@ static uint16_t cs89x0_getppreg(struct cs89x0_driver_s *cs89x0, int addr) #endif } - /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit - * I/O ports that in the host system's I/O space. - */ + /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit + * I/O ports that in the host system's I/O space. + */ else #endif @@ -253,9 +252,9 @@ static void cs89x0_putppreg(struct cs89x0_driver_s *cs89x0, int addr, uint16_t v #endif } - /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit - * I/O ports that in the host system's I/O space. - */ + /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit + * I/O ports that in the host system's I/O space. + */ else #endif @@ -306,7 +305,8 @@ static int cs89x0_transmit(struct cs89x0_driver_s *cs89x0) /* Setup the TX timeout watchdog (perhaps restarting the timer) */ - (void)wd_start(cs89x0->cs_txtimeout, CS89x0_TXTIMEOUT, cs89x0_txtimeout, 1, (uint32_t)cs89x0); + (void)wd_start(cs89x0->cs_txtimeout, CS89x0_TXTIMEOUT, cs89x0_txtimeout, + 1, (wdparm_t)cs89x0); return OK; } @@ -397,9 +397,9 @@ static int cs89x0_txpoll(struct net_driver_s *dev) * ****************************************************************************/ -static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) +static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) { - uint16_t *dest; + FAR uint16_t *dest; uint16_t rxlength; int nbytes; @@ -408,31 +408,31 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) rxlength = cs89x0_getreg(PPR_RXLENGTH); if ((isq & RX_OK) == 0) { -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_errors++; +#ifdef CONFIG_NETDEV_STATISTICS + NETDEV_RXERRORS(&cd89x0->cs_dev); + +#if 0 if ((isq & RX_RUNT) != 0) { - cd89x0->cs_stats.rx_lengtherrors++; } if ((isq & RX_EXTRA_DATA) != 0) { - cd89x0->cs_stats.rx_lengtherrors++; } if (isq & RX_CRC_ERROR) != 0) { - if (!(isq & (RX_EXTRA_DATA|RX_RUNT))) + if (!(isq & (RX_EXTRA_DATA | RX_RUNT))) { - cd89x0->cs_stats.rx_crcerrors++; } } if ((isq & RX_DRIBBLE) != 0) { - cd89x0->cs_stats.rx_frameerrors++; } #endif +#endif + return; } @@ -440,10 +440,7 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) if (rxlength > ???) { -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_errors++; - cd89x0->cs_stats.rx_lengtherrors++; -#endif + NETDEV_RXERRORS(&cd89x0->cs_dev); return; } @@ -451,15 +448,13 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) * amount of data in cs89x0->cs_dev.d_len */ - dest = (uint16_t*)cs89x0->cs_dev.d_buf; + dest = (FAR uint16_t *)cs89x0->cs_dev.d_buf; for (nbytes = 0; nbytes < rxlength; nbytes += sizeof(uint16_t)) { *dest++ = cs89x0_getreg(PPR_RXFRAMELOCATION); } -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_packets++; -#endif + NETDEV_RXPACKETS(&cd89x0->cs_dev); #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ @@ -473,6 +468,7 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->cs_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -513,6 +509,7 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->cs_dev); /* Give the IPv6 packet to the network layer */ @@ -549,21 +546,23 @@ static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq) #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { - arp_arpin(&cs89x0->cs_dev); + NETDEV_RXARP(&priv->cs_dev); + arp_arpin(&cs89x0->cs_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ - if (cs89x0->cs_dev.d_len > 0) - { - cs89x0_transmit(cs89x0); - } + if (cs89x0->cs_dev.d_len > 0) + { + cs89x0_transmit(cs89x0); + } } else #endif { nllvdbg("Unrecognized packet type %02x\n", BUF->type); + NETDEV_RXDROPPED(&priv->cs_dev); } } @@ -589,28 +588,30 @@ static void cs89x0_txdone(struct cs89x0_driver_s *cs89x0, uint16_t isq) * hold the register address causing the interrupt. We got here because * those bits indicated */ -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.tx_packets++; +#ifdef CONFIG_NETDEV_STATISTICS + NETDEV_TXPACKETS(&cd89x0->cs_dev); if ((isq & ISQ_TXEVENT_TXOK) == 0) { - cd89x0->cs_stats.tx_errors++; + NETDEV_TXERRORS(&cd89x0->cs_dev); } + +#if 0 if ((isq & ISQ_TXEVENT_LOSSOFCRS) != 0) { - cd89x0->cs_stats.tx_carriererrors++; } + if ((isq & ISQ_TXEVENT_SQEERROR) != 0) { - cd89x0->cs_stats.tx_heartbeaterrors++; } + if (i(sq & ISQ_TXEVENT_OUTWINDOW) != 0) { - cd89x0->cs_stats.tx_windowerrors++; } + if (isq & TX_16_COL) { - cd89x0->cs_stats.tx_abortederrors++; } +#endif #endif /* If no further xmits are pending, then cancel the TX timeout */ @@ -719,15 +720,11 @@ static int cs89x0_interrupt(int irq, FAR void *context) break; case ISQ_RXMISSEVENT: -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_missederrors += (isq >>6); -#endif + NETDEV_RXERRORS(&cd89x0->cs_dev); break; case ISQ_TXCOLEVENT: -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.collisions += (isq >>6); -#endif + NETDEV_TXERRORS(&cd89x0->cs_dev); break; } } @@ -793,11 +790,12 @@ static void cs89x0_polltimer(int argc, uint32_t arg, ...) /* If so, update TCP timing states and poll uIP for new XMIT data */ - (void)devif_timer(&cs89x0->cs_dev, cs89x0_txpoll, CS89x0_POLLHSEC); + (void)devif_timer(&cs89x0->cs_dev, cs89x0_txpoll); /* Setup the watchdog poll timer again */ - (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, arg); + (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, + (wdparm_t)arg); } /**************************************************************************** @@ -823,14 +821,15 @@ static int cs89x0_ifup(struct net_driver_s *dev) ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Initialize the Ethernet interface */ #warning "Missing logic" /* Set and activate a timer process */ - (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, (uint32_t)cs89x0); + (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, + (wdparm_t)cs89x0); /* Enable the Ethernet interrupt */ @@ -862,7 +861,7 @@ static int cs89x0_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); up_disable_irq(CONFIG_CS89x0_IRQ); /* Cancel the TX poll timer and TX timeout timers */ @@ -873,7 +872,7 @@ static int cs89x0_ifdown(struct net_driver_s *dev) /* Reset the device */ cs89x0->cs_bifup = false; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -901,7 +900,7 @@ static int cs89x0_txavail(struct net_driver_s *dev) struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)dev->d_private; irqstate_t flags; - flags = irqsave(); + flags = enter_critical_section(); /* Ignore the notification if the interface is not yet up */ @@ -915,7 +914,7 @@ static int cs89x0_txavail(struct net_driver_s *dev) (void)devif_poll(&cs89x0->cs_dev, cs89x0_txpoll); } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -1033,20 +1032,20 @@ int cs89x0_initialize(FAR const cs89x0_driver_s *cs89x0, int devno) /* Initialize the driver structure */ - g_cs89x[devno] = cs89x0; /* Used to map IRQ back to instance */ - cs89x0->cs_dev.d_ifup = cs89x0_ifup; /* I/F down callback */ - cs89x0->cs_dev.d_ifdown = cs89x0_ifdown; /* I/F up (new IP address) callback */ - cs89x0->cs_dev.d_txavail = cs89x0_txavail; /* New TX data callback */ + g_cs89x[devno] = cs89x0; /* Used to map IRQ back to instance */ + cs89x0->cs_dev.d_ifup = cs89x0_ifup; /* I/F down callback */ + cs89x0->cs_dev.d_ifdown = cs89x0_ifdown; /* I/F up (new IP address) callback */ + cs89x0->cs_dev.d_txavail = cs89x0_txavail; /* New TX data callback */ #ifdef CONFIG_NET_IGMP - cs89x0->cs_dev.d_addmac = cs89x0_addmac; /* Add multicast MAC address */ - cs89x0->cs_dev.d_rmmac = cs89x0_rmmac; /* Remove multicast MAC address */ + cs89x0->cs_dev.d_addmac = cs89x0_addmac; /* Add multicast MAC address */ + cs89x0->cs_dev.d_rmmac = cs89x0_rmmac; /* Remove multicast MAC address */ #endif - cs89x0->cs_dev.d_private = (void*)cs89x0; /* Used to recover private state from dev */ + cs89x0->cs_dev.d_private = (FAR void *)cs89x0; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmisstions */ - cs89x0->cs_txpoll = wd_create(); /* Create periodic poll timer */ - cs89x0->cs_txtimeout = wd_create(); /* Create TX timeout timer */ + cs89x0->cs_txpoll = wd_create(); /* Create periodic poll timer */ + cs89x0->cs_txtimeout = wd_create(); /* Create TX timeout timer */ /* Read the MAC address from the hardware into cs89x0->cs_dev.d_mac.ether_addr_octet */ diff --git a/drivers/net/dm90x0.c b/drivers/net/dm90x0.c index 03e1e44f8d5584f2ee4b3d41f3c57f9f587f9183..caaf0c1872d9c50405d04a883ac3f6cec974f364 100644 --- a/drivers/net/dm90x0.c +++ b/drivers/net/dm90x0.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/dm9x.c * - * Copyright (C) 2007-2010, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: Davicom data sheets (DM9000-DS-F03-041906.pdf, @@ -194,8 +194,8 @@ #define DM9X_ISR_IOMODE16 (0 << 6) /* IO mode = 16 bit */ #define DM9X_ISR_IOMODE32 (1 << 6) /* IO mode = 32 bit */ -#define DM9X_IMRENABLE (DM9X_INT_PR|DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR) -#define DM9X_IMRRXDISABLE (DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR) +#define DM9X_IMRENABLE (DM9X_INT_PR | DM9X_INT_PT | DM9X_INT_LNKCHG | DM9X_IMR_PAR) +#define DM9X_IMRRXDISABLE (DM9X_INT_PT | DM9X_INT_LNKCHG | DM9X_IMR_PAR) #define DM9X_IMRDISABLE (DM9X_IMR_PAR) /* EEPROM/PHY control regiser bits */ @@ -224,7 +224,7 @@ #define DM9X_RXC_WTDIS (1 << 6) /* Disable watchdog timer */ #define DM9X_RXC_HASHALL (1 << 7) /* Filter all addresses in hash table */ -#define DM9X_RXCSETUP (DM9X_RXC_DISCRC|DM9X_RXC_DISLONG) +#define DM9X_RXCSETUP (DM9X_RXC_DISCRC | DM9X_RXC_DISLONG) /* EEPHY bit settings */ @@ -266,7 +266,6 @@ /* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define DM6X_WDDELAY (1*CLK_TCK) -#define DM6X_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -310,20 +309,6 @@ struct dm9x_driver_s void (*dm_write)(const uint8_t *ptr, int len); void (*dm_discard)(int len); -#if defined(CONFIG_DM9X_STATS) - uint32_t dm_ntxpackets; /* Count of packets sent */ - uint32_t dm_ntxbytes; /* Count of bytes sent */ - uint32_t dm_ntxerrors; /* Count of TX errors */ - uint32_t dm_nrxpackets; /* Count of packets received */ - uint32_t dm_nrxbytes; /* Count of bytes received */ - uint32_t dm_nrxfifoerrors; /* Count of RX FIFO overflow errors */ - uint32_t dm_nrxcrcerrors; /* Count of RX CRC errors */ - uint32_t dm_nrxlengtherrors; /* Count of RX length errors */ - uint32_t dm_nphyserrors; /* Count of physical layer errors */ - uint32_t dm_nresets; /* Counts number of resets */ - uint32_t dm_ntxtimeouts; /* Counts resets caused by TX timeouts */ -#endif - /* This holds the information visible to uIP/NuttX */ struct net_driver_s dm_dev; @@ -359,18 +344,6 @@ static void write32(const uint8_t *ptr, int len); static uint16_t dm9x_phyread(struct dm9x_driver_s *dm9x, int reg); static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value); -#if defined(CONFIG_DM9X_STATS) -static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x); -#else -# define dm9x_resetstatistics(dm9x) -#endif - -#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG) -static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x); -#else -# define dm9x_dumpstatistics(dm9x) -#endif - #if defined(CONFIG_DM9X_CHECKSUM) static bool dm9x_rxchecksumready(uint8_t); #else @@ -458,7 +431,7 @@ static void putreg(int reg, uint8_t value) * ****************************************************************************/ -static void read8(uint8_t *ptr, int len) +static void read8(FAR uint8_t *ptr, int len) { nvdbg("Read %d bytes (8-bit mode)\n", len); for (; len > 0; len--) @@ -467,9 +440,10 @@ static void read8(uint8_t *ptr, int len) } } -static void read16(uint8_t *ptr, int len) +static void read16(FAR uint8_t *ptr, int len) { - register uint16_t *ptr16 = (uint16_t*)ptr; + FAR uint16_t *ptr16 = (FAR uint16_t *)ptr; + nvdbg("Read %d bytes (16-bit mode)\n", len); for (; len > 0; len -= sizeof(uint16_t)) { @@ -477,9 +451,10 @@ static void read16(uint8_t *ptr, int len) } } -static void read32(uint8_t *ptr, int len) +static void read32(FAR uint8_t *ptr, int len) { - register uint32_t *ptr32 = (uint32_t*)ptr; + FAR uint32_t *ptr32 = (FAR uint32_t *)ptr; + nvdbg("Read %d bytes (32-bit mode)\n", len); for (; len > 0; len -= sizeof(uint32_t)) { @@ -548,9 +523,10 @@ static void discard32(int len) * ****************************************************************************/ -static void write8(const uint8_t *ptr, int len) +static void write8(FAR const uint8_t *ptr, int len) { nvdbg("Write %d bytes (8-bit mode)\n", len); + for (; len > 0; len--) { DM9X_DATA = (*ptr++ & 0xff); @@ -559,7 +535,8 @@ static void write8(const uint8_t *ptr, int len) static void write16(const uint8_t *ptr, int len) { - register uint16_t *ptr16 = (uint16_t*)ptr; + FAR uint16_t *ptr16 = (FAR uint16_t *)ptr; + nvdbg("Write %d bytes (16-bit mode)\n", len); for (; len > 0; len -= sizeof(uint16_t)) @@ -568,10 +545,12 @@ static void write16(const uint8_t *ptr, int len) } } -static void write32(const uint8_t *ptr, int len) +static void write32(FAR const uint8_t *ptr, int len) { - register uint32_t *ptr32 = (uint32_t*)ptr; + FAR uint32_t *ptr32 = (FAR uint32_t *)ptr; + nvdbg("Write %d bytes (32-bit mode)\n", len); + for (; len > 0; len -= sizeof(uint32_t)) { DM9X_DATA = *ptr32++; @@ -602,7 +581,7 @@ static uint16_t dm9x_readsrom(struct dm9x_driver_s *dm9x, int offset) putreg(DM9X_EEPHYC, DM9X_EEPHYC_ERPRR); up_udelay(200); putreg(DM9X_EEPHYC, 0x00); - return (getreg(DM9X_EEPHYDL) + (getreg(DM9X_EEPHYDH) << 8) ); + return (getreg(DM9X_EEPHYDL) + (getreg(DM9X_EEPHYDH) << 8)); } #endif @@ -632,7 +611,7 @@ static uint16_t dm9x_phyread(struct dm9x_driver_s *dm9x, int reg) /* Issue PHY read command pulse in the EEPROM/PHY control register */ - putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRR|DM9X_EEPHYC_EPOS)); + putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRR | DM9X_EEPHYC_EPOS)); up_udelay(100); putreg(DM9X_EEPHYC, 0x00); @@ -654,77 +633,11 @@ static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value) /* Issue PHY write command pulse in the EEPROM/PHY control register */ - putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRW|DM9X_EEPHYC_EPOS)); + putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRW | DM9X_EEPHYC_EPOS)); up_udelay(500); putreg(DM9X_EEPHYC, 0x0); } -/**************************************************************************** - * Function: dm9x_resetstatistics - * - * Description: - * Reset all DM90x0 statistics - * - * Parameters: - * dm9x - Reference to the driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#if defined(CONFIG_DM9X_STATS) -static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x) -{ - dm9x->dm_ntxpackets = 0; /* Count of packets sent */ - dm9x->dm_ntxbytes = 0; /* Count of bytes sent */ - dm9x->dm_ntxerrors = 0; /* Count of TX errors */ - dm9x->dm_nrxpackets = 0; /* Count of packets received */ - dm9x->dm_nrxbytes = 0; /* Count of bytes received */ - dm9x->dm_nrxfifoerrors = 0; /* Count of RX FIFO overflow errors */ - dm9x->dm_nrxcrcerrors = 0; /* Count of RX CRC errors */ - dm9x->dm_nrxlengtherrors = 0; /* Count of RX length errors */ - dm9x->dm_nphyserrors = 0; /* Count of physical layer errors */ - dm9x->dm_nresets = 0; /* Counts number of resets */ - dm9x->dm_ntxtimeouts = 0; /* Counts resets caused by TX timeouts */ -} -#endif - -/**************************************************************************** - * Function: dm9x_dumpstatistics - * - * Description: - * Print the current value of all DM90x0 statistics - * - * Parameters: - * dm9x - Reference to the driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG) -static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x) -{ - ndbg("TX packets: %d\n", dm9x->dm_ntxpackets); - ndbg(" bytes: %d\n", dm9x->dm_ntxbytes); - ndbg(" errors: %d\n", dm9x->dm_ntxerrors); - ndbg("RX packets: %d\n", dm9x->dm_nrxpackets); - ndbg(" bytes: %d\n", dm9x->dm_nrxbytes); - ndbg(" FIFO overflows: %d\n", dm9x->dm_nrxfifoerrors); - ndbg(" CRC errors: %d\n", dm9x->dm_nrxcrcerrors); - ndbg(" length errors: %d\n", dm9x->dm_nrxlengtherrors); - ndbg("Physical layer errors: %d\n", dm9x->dm_nphyserrors); - ndbg("Resets: %d\n", dm9x->dm_nresets); - ndbg("TX timeout resets: %d\n", dm9x->dm_ntxtimeouts); -} -#endif - /**************************************************************************** * Function: dm9x_rxchecksumready * @@ -781,10 +694,7 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x) /* Increment count of packets transmitted */ dm9x->dm_ntxpending++; -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_ntxpackets++; - dm9x->dm_ntxbytes += dm9x->dm_dev.d_len; -#endif + NETDEV_TXPACKETS(&dm9x0->dm_dev); /* Disable all DM90x0 interrupts */ @@ -803,7 +713,7 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x) #if !defined(CONFIG_DM9X_ETRANS) /* Issue TX polling command */ - putreg(DM9X_TXC, 0x1); /* Cleared after TX complete*/ + putreg(DM9X_TXC, 0x1); /* Cleared after TX complete */ #endif /* Clear count of back-to-back RX packet transfers */ @@ -816,7 +726,8 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x) /* Setup the TX timeout watchdog (perhaps restarting the timer) */ - (void)wd_start(dm9x->dm_txtimeout, DM6X_TXTIMEOUT, dm9x_txtimeout, 1, (uint32_t)dm9x); + (void)wd_start(dm9x->dm_txtimeout, DM6X_TXTIMEOUT, dm9x_txtimeout, 1, + (wdparm_t)dm9x); return OK; } return -EBUSY; @@ -914,7 +825,7 @@ static int dm9x_txpoll(struct net_driver_s *dev) * ****************************************************************************/ -static void dm9x_receive(struct dm9x_driver_s *dm9x) +static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) { union rx_desc_u rx; bool bchecksumready; @@ -946,7 +857,7 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) /* Read packet status & length */ - dm9x->dm_read((uint8_t*)&rx, 4); + dm9x->dm_read((FAR uint8_t *)&rx, 4); /* Check if any errors were reported by the hardware */ @@ -954,33 +865,9 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) { /* Bad RX packet... update statistics */ -#if defined(CONFIG_DM9X_STATS) - if (rx.desc.rx_status & 0x01) - { - dm9x->dm_nrxfifoerrors++; - ndbg("RX FIFO error: %d\n", dm9x->dm_nrxfifoerrors); - } - - if (rx.desc.rx_status & 0x02) - { - dm9x->dm_nrxcrcerrors++; - ndbg("RX CRC error: %d\n", dm9x->dm_nrxcrcerrors); - } - - if (rx.desc.rx_status & 0x80) - { - dm9x->dm_nrxlengtherrors++; - ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors); - } - - if (rx.desc.rx_status & 0x08) - { - dm9x->dm_nphyserrors++; - ndbg("Physical Layer error: %d\n", dm9x->dm_nphyserrors); - } -#else ndbg("Received packet with errors: %02x\n", rx.desc.rx_status); -#endif + NETDEV_RXERRORS(&dm9x->dm_dev); + /* Drop this packet and continue to check the next packet */ dm9x->dm_discard(rx.desc.rx_len); @@ -990,10 +877,9 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) else if (rx.desc.rx_len < ETH_HDRLEN || rx.desc.rx_len > (CONFIG_NET_ETH_MTU + 2)) { -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nrxlengtherrors++; - ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors); -#endif + ndbg("RX length error\n"); + NETDEV_RXERRORS(&dm9x->dm_dev); + /* Drop this packet and continue to check the next packet */ dm9x->dm_discard(rx.desc.rx_len); @@ -1017,6 +903,7 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dm_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1025,9 +912,9 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) arp_ipin(&dm9x->dm_dev); ipv4_input(&dm9x->dm_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ if (dm9x->dm_dev.d_len > 0) { @@ -1057,14 +944,15 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dm_dev); /* Give the IPv6 packet to the network layer */ ipv6_input(&dm9x->dm_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ if (dm9x->dm_dev.d_len > 0) { @@ -1094,10 +982,11 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&dm9x->dm_dev); + NETDEV_RXARP(&priv->dm_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ if (dm9x->dm_dev.d_len > 0) { @@ -1105,12 +994,13 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) } } #endif + else + { + NETDEV_RXDROPPED(&priv->dm_dev); + } } -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nrxpackets++; - dm9x->dm_nrxbytes += rx.desc.rx_len; -#endif + NETDEV_RXPACKETS(&dm9x->dm_dev); dm9x->ncrxpackets++; } while ((rxbyte & 0x01) == DM9X_PKTRDY && dm9x->ncrxpackets < DM9X_CRXTHRES); @@ -1230,8 +1120,8 @@ static int dm9x_interrupt(int irq, FAR void *context) for (i = 0; i < 500; i++) { - dm9x_phyread(dm9x,0x1); - if (dm9x_phyread(dm9x,0x1) & 0x4) /*Link OK*/ + dm9x_phyread(dm9x, 0x1); + if (dm9x_phyread(dm9x, 0x1) & 0x4) /* Link OK */ { /* Wait to get detected speed */ @@ -1257,16 +1147,16 @@ static int dm9x_interrupt(int irq, FAR void *context) ndbg("delay: %dmS speed: %s\n", i, dm9x->dm_b100M ? "100M" : "10M"); } - /* Check if we received an incoming packet */ + /* Check if we received an incoming packet */ - if (isr & DM9X_INT_PR) + if (isr & DM9X_INT_PR) { dm9x_receive(dm9x); } - /* Check if we are able to transmit a packet */ + /* Check if we are able to transmit a packet */ - if (isr & DM9X_INT_PT) + if (isr & DM9X_INT_PT) { dm9x_txdone(dm9x); } @@ -1320,15 +1210,9 @@ static void dm9x_txtimeout(int argc, uint32_t arg, ...) /* Increment statistics and dump debug info */ -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_ntxtimeouts++; - dm9x->dm_ntxerrors++; -#endif + NETDEV_TXTIMEOUTS(dm9x->dm_dev); ndbg(" TX packet count: %d\n", dm9x->dm_ntxpending); -#if defined(CONFIG_DM9X_STATS) - ndbg(" TX timeouts: %d\n", dm9x->dm_ntxtimeouts); -#endif ndbg(" TX read pointer address: 0x%02x:%02x\n", getreg(DM9X_TRPAH), getreg(DM9X_TRPAL)); ndbg(" Memory data write address: 0x%02x:%02x (DM9010)\n", @@ -1382,12 +1266,13 @@ static void dm9x_polltimer(int argc, uint32_t arg, ...) { /* If so, update TCP timing states and poll uIP for new XMIT data */ - (void)devif_timer(&dm9x->dm_dev, dm9x_txpoll, DM6X_POLLHSEC); + (void)devif_timer(&dm9x->dm_dev, dm9x_txpoll); } /* Setup the watchdog poll timer again */ - (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, arg); + (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, + (wdparm_t)arg); } /**************************************************************************** @@ -1411,19 +1296,19 @@ static inline void dm9x_phymode(struct dm9x_driver_s *dm9x) uint16_t phyreg0; uint16_t phyreg4; -#if CONFIG_DM9X_MODE_AUTO +#ifdef CONFIG_DM9X_MODE_AUTO phyreg0 = 0x1200; /* Auto-negotiation & Restart Auto-negotiation */ - phyreg4 = 0x01e1; /* Default flow control disable*/ -#elif CONFIG_DM9X_MODE_10MHD + phyreg4 = 0x01e1; /* Default flow control disable */ +#elif defined(CONFIG_DM9X_MODE_10MHD) phyreg4 = 0x21; phyreg0 = 0x1000; -#elif CONFIG_DM9X_MODE_10MFD +#elif defined(CONFIG_DM9X_MODE_10MFD) phyreg4 = 0x41; phyreg0 = 0x1100; -#elif CONFIG_DM9X_MODE_100MHD +#elif defined(CONFIG_DM9X_MODE_100MHD) phyreg4 = 0x81; phyreg0 = 0x3000; -#elif CONFIG_DM9X_MODE_100MFD +#elif defined(CONFIG_DM9X_MODE_100MFD) phyreg4 = 0x101; phyreg0 = 0x3100; #else @@ -1459,7 +1344,7 @@ static int dm9x_ifup(struct net_driver_s *dev) ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Initilize DM90x0 chip */ @@ -1491,7 +1376,8 @@ static int dm9x_ifup(struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, (uint32_t)dm9x); + (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, + (wdparm_t)dm9x); /* Enable the DM9X interrupt */ @@ -1525,7 +1411,7 @@ static int dm9x_ifdown(struct net_driver_s *dev) /* Disable the DM9X interrupt */ - flags = irqsave(); + flags = enter_critical_section(); up_disable_irq(CONFIG_DM9X_IRQ); /* Cancel the TX poll timer and TX timeout timers */ @@ -1542,11 +1428,7 @@ static int dm9x_ifdown(struct net_driver_s *dev) putreg(DM9X_ISR, DM9X_INT_ALL); /* Clear interrupt status */ dm9x->dm_bifup = false; - irqrestore(flags); - - /* Dump statistics */ - - dm9x_dumpstatistics(dm9x); + leave_critical_section(flags); return OK; } @@ -1575,7 +1457,7 @@ static int dm9x_txavail(struct net_driver_s *dev) irqstate_t flags; ndbg("Polling\n"); - flags = irqsave(); + flags = enter_critical_section(); /* Ignore the notification if the interface is not yet up */ @@ -1593,7 +1475,7 @@ static int dm9x_txavail(struct net_driver_s *dev) (void)devif_poll(&dm9x->dm_dev, dm9x_txpoll); } } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -1688,9 +1570,9 @@ static void dm9x_bringup(struct dm9x_driver_s *dm9x) * in 10us; 20us guarantees completion of the reset */ - putreg(DM9X_NETC, (DM9X_NETC_RST|DM9X_NETC_LBK1)); + putreg(DM9X_NETC, (DM9X_NETC_RST | DM9X_NETC_LBK1)); up_udelay(20); - putreg(DM9X_NETC, (DM9X_NETC_RST|DM9X_NETC_LBK1)); + putreg(DM9X_NETC, (DM9X_NETC_RST | DM9X_NETC_LBK1)); up_udelay(20); /* Configure I/O mode */ @@ -1729,7 +1611,7 @@ static void dm9x_bringup(struct dm9x_driver_s *dm9x) putreg(DM9X_TXC, 0x00); /* Clear TX Polling */ putreg(DM9X_BPTHRES, 0x3f); /* Less 3kb, 600us */ putreg(DM9X_SMODEC, 0x00); /* Special mode */ - putreg(DM9X_NETS, (DM9X_NETS_WAKEST|DM9X_NETS_TX1END|DM9X_NETS_TX2END)); /* Clear TX status */ + putreg(DM9X_NETS, (DM9X_NETS_WAKEST | DM9X_NETS_TX1END | DM9X_NETS_TX2END)); /* Clear TX status */ putreg(DM9X_ISR, DM9X_INT_ALL); /* Clear interrupt status */ #if defined(CONFIG_DM9X_CHECKSUM) @@ -1745,7 +1627,7 @@ static void dm9x_bringup(struct dm9x_driver_s *dm9x) dm9x->ncrxpackets = 0; /* Number of continuous RX packets */ dm9x->dm_ntxpending = 0; /* Number of pending TX packets */ - dm9x_resetstatistics(dm9x); + NETDEV_RESET_STATISTICS(&dm9x->dm_dev); /* Activate DM9000A/DM9010 */ @@ -1783,10 +1665,6 @@ static void dm9x_reset(struct dm9x_driver_s *dm9x) /* Save previous register address */ save = (uint8_t)DM9X_INDEX; - -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nresets++; -#endif dm9x_bringup(dm9x); /* Wait up to 1 second for the link to be OK */ @@ -1794,7 +1672,7 @@ static void dm9x_reset(struct dm9x_driver_s *dm9x) dm9x->dm_b100M = false; for (i = 0; i < 1000; i++) { - if (dm9x_phyread(dm9x,0x1) & 0x4) + if (dm9x_phyread(dm9x, 0x1) & 0x4) { if (dm9x_phyread(dm9x, 0) &0x2000) { @@ -1874,12 +1752,12 @@ int dm9x_initialize(void) g_dm9x[0].dm_dev.d_addmac = dm9x_addmac; /* Add multicast MAC address */ g_dm9x[0].dm_dev.d_rmmac = dm9x_rmmac; /* Remove multicast MAC address */ #endif - g_dm9x[0].dm_dev.d_private = (void*)g_dm9x; /* Used to recover private state from dev */ + g_dm9x[0].dm_dev.d_private = (FAR void *)g_dm9x; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmisstions */ - g_dm9x[0].dm_txpoll = wd_create(); /* Create periodic poll timer */ - g_dm9x[0].dm_txtimeout = wd_create(); /* Create TX timeout timer */ + g_dm9x[0].dm_txpoll = wd_create(); /* Create periodic poll timer */ + g_dm9x[0].dm_txtimeout = wd_create(); /* Create TX timeout timer */ /* Read the MAC address */ diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index b122b75d983446f1c81f598dae6367ef22188c77..11a445298922c00fca6f2b7a99eca5523a5115bd 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -78,7 +78,6 @@ /* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define E1000_WDDELAY (1*CLK_TCK) -#define E1000_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -142,7 +141,10 @@ struct e1000_dev_head * Private Data ****************************************************************************/ -static struct e1000_dev_head e1000_list = {0}; +static struct e1000_dev_head e1000_list = +{ + 0 +}; /**************************************************************************** * Private Function Prototypes @@ -195,24 +197,24 @@ void e1000_reset(struct e1000_dev *dev) /* Reset the network controller hardware */ dev_control = 0; - dev_control |= (1<<0); /* FD-bit (Full Duplex) */ - dev_control |= (0<<2); /* GIOMD-bit (GIO Master Disable) */ - dev_control |= (1<<3); /* LRST-bit (Link Reset) */ - dev_control |= (1<<6); /* SLU-bit (Set Link Up) */ - dev_control |= (2<<8); /* SPEED=2 (1000Mbps) */ - dev_control |= (0<<11); /* FRCSPD-bit (Force Speed) */ - dev_control |= (0<<12); /* FRCDPLX-bit (Force Duplex) */ - dev_control |= (0<<20); /* ADVD3WUC-bit (Advertise D3 Wake Up Cap) */ - dev_control |= (1<<26); /* RST-bit (Device Reset) */ - dev_control |= (1<<27); /* RFCE-bit (Receive Flow Control Enable) */ - dev_control |= (1<<28); /* TFCE-bit (Transmit Flow Control Enable) */ - dev_control |= (0<<30); /* VME-bit (VLAN Mode Enable) */ - dev_control |= (0<<31); /* PHY_RST-bit (PHY Reset) */ + dev_control |= (1 << 0); /* FD-bit (Full Duplex) */ + dev_control |= (0 << 2); /* GIOMD-bit (GIO Master Disable) */ + dev_control |= (1 << 3); /* LRST-bit (Link Reset) */ + dev_control |= (1 << 6); /* SLU-bit (Set Link Up) */ + dev_control |= (2 << 8); /* SPEED=2 (1000Mbps) */ + dev_control |= (0 << 11); /* FRCSPD-bit (Force Speed) */ + dev_control |= (0 << 12); /* FRCDPLX-bit (Force Duplex) */ + dev_control |= (0 << 20); /* ADVD3WUC-bit (Advertise D3 Wake Up Cap) */ + dev_control |= (1 << 26); /* RST-bit (Device Reset) */ + dev_control |= (1 << 27); /* RFCE-bit (Receive Flow Control Enable) */ + dev_control |= (1 << 28); /* TFCE-bit (Transmit Flow Control Enable) */ + dev_control |= (0 << 30); /* VME-bit (VLAN Mode Enable) */ + dev_control |= (0 << 31); /* PHY_RST-bit (PHY Reset) */ e1000_outl(dev, E1000_IMC, 0xFFFFFFFF); e1000_outl(dev, E1000_STATUS, 0x00000000); e1000_outl(dev, E1000_CTRL, dev_control); - dev_control &= ~(1<<26); /* clear RST-bit (Device Reset) */ + dev_control &= ~(1 << 26); /* clear RST-bit (Device Reset) */ e1000_outl(dev, E1000_CTRL, dev_control); up_mdelay(10); e1000_outl(dev, E1000_CTRL_EXT, 0x001401C0); @@ -228,13 +230,13 @@ void e1000_turn_on(struct e1000_dev *dev) /* turn on the controller's receive engine */ rx_control = e1000_inl(dev, E1000_RCTL); - rx_control |= (1<<1); + rx_control |= (1 << 1); e1000_outl(dev, E1000_RCTL, rx_control); /* turn on the controller's transmit engine */ tx_control = e1000_inl(dev, E1000_TCTL); - tx_control |= (1<<1); + tx_control |= (1 << 1); e1000_outl(dev, E1000_TCTL, tx_control); /* enable the controller's interrupts */ @@ -242,11 +244,11 @@ void e1000_turn_on(struct e1000_dev *dev) e1000_outl(dev, E1000_ICR, 0xFFFFFFFF); e1000_outl(dev, E1000_IMC, 0xFFFFFFFF); - ims |= 1<<0; /* TXDW */ - ims |= 1<<1; /* TXQE */ - ims |= 1<<2; /* LSC */ - ims |= 1<<4; /* RXDMT0 */ - ims |= 1<<7; /* RXT0 */ + ims |= 1 << 0; /* TXDW */ + ims |= 1 << 1; /* TXQE */ + ims |= 1 << 2; /* LSC */ + ims |= 1 << 4; /* RXDMT0 */ + ims |= 1 << 7; /* RXT0 */ e1000_outl(dev, E1000_IMS, ims); } @@ -258,13 +260,13 @@ void e1000_turn_off(struct e1000_dev *dev) /* turn off the controller's receive engine */ rx_control = e1000_inl(dev, E1000_RCTL); - rx_control &= ~(1<<1); + rx_control &= ~(1 << 1); e1000_outl(dev, E1000_RCTL, rx_control); /* turn off the controller's transmit engine */ tx_control = e1000_inl(dev, E1000_TCTL); - tx_control &= ~(1<<1); + tx_control &= ~(1 << 1); e1000_outl(dev, E1000_TCTL, tx_control); /* turn off the controller's interrupts */ @@ -287,39 +289,39 @@ void e1000_init(struct e1000_dev *dev) /* configure the controller's 'receive' engine */ rx_control = 0; - rx_control |= (0<<1); /* EN-bit (Enable) */ - rx_control |= (0<<2); /* SPB-bit (Store Bad Packets) */ - rx_control |= (0<<3); /* UPE-bit (Unicast Promiscuous Mode) */ - rx_control |= (1<<4); /* MPE-bit (Multicast Promiscuous Mode) */ - rx_control |= (0<<5); /* LPE-bit (Long Packet Enable) */ - rx_control |= (0<<6); /* LBM=0 (Loop-Back Mode) */ - rx_control |= (0<<8); /* RDMTS=0 (Rx Descriptor Min Threshold Size) */ - rx_control |= (0<<10); /* DTYPE=0 (Descriptor Type) */ - rx_control |= (0<<12); /* MO=0 (Multicast Offset) */ - rx_control |= (1<<15); /* BAM-bit (Broadcast Address Mode) */ - rx_control |= (0<<16); /* BSIZE=0 (Buffer Size = 2048) */ - rx_control |= (0<<18); /* VLE-bit (VLAN filter Enable) */ - rx_control |= (0<<19); /* CFIEN-bit (Canonical Form Indicator Enable) */ - rx_control |= (0<<20); /* CFI-bit (Canonical Form Indicator) */ - rx_control |= (1<<22); /* DPF-bit (Discard Pause Frames) */ - rx_control |= (0<<23); /* PMCF-bit (Pass MAC Control Frames) */ - rx_control |= (0<<25); /* BSEX=0 (Buffer Size EXtension) */ - rx_control |= (1<<26); /* SECRC-bit (Strip Ethernet CRC) */ - rx_control |= (0<<27); /* FLEXBUF=0 (Flexible Buffer size) */ + rx_control |= (0 << 1); /* EN-bit (Enable) */ + rx_control |= (0 << 2); /* SPB-bit (Store Bad Packets) */ + rx_control |= (0 << 3); /* UPE-bit (Unicast Promiscuous Mode) */ + rx_control |= (1 << 4); /* MPE-bit (Multicast Promiscuous Mode) */ + rx_control |= (0 << 5); /* LPE-bit (Long Packet Enable) */ + rx_control |= (0 << 6); /* LBM=0 (Loop-Back Mode) */ + rx_control |= (0 << 8); /* RDMTS=0 (Rx Descriptor Min Threshold Size) */ + rx_control |= (0 << 10); /* DTYPE=0 (Descriptor Type) */ + rx_control |= (0 << 12); /* MO=0 (Multicast Offset) */ + rx_control |= (1 << 15); /* BAM-bit (Broadcast Address Mode) */ + rx_control |= (0 << 16); /* BSIZE=0 (Buffer Size = 2048) */ + rx_control |= (0 << 18); /* VLE-bit (VLAN filter Enable) */ + rx_control |= (0 << 19); /* CFIEN-bit (Canonical Form Indicator Enable) */ + rx_control |= (0 << 20); /* CFI-bit (Canonical Form Indicator) */ + rx_control |= (1 << 22); /* DPF-bit (Discard Pause Frames) */ + rx_control |= (0 << 23); /* PMCF-bit (Pass MAC Control Frames) */ + rx_control |= (0 << 25); /* BSEX=0 (Buffer Size EXtension) */ + rx_control |= (1 << 26); /* SECRC-bit (Strip Ethernet CRC) */ + rx_control |= (0 << 27); /* FLEXBUF=0 (Flexible Buffer size) */ e1000_outl(dev, E1000_RCTL, rx_control); /* configure the controller's 'transmit' engine */ tx_control = 0; - tx_control |= (0<<1); /* EN-bit (Enable) */ - tx_control |= (1<<3); /* PSP-bit (Pad Short Packets) */ - tx_control |= (15<<4); /* CT=15 (Collision Threshold) */ - tx_control |= (63<<12); /* COLD=63 (Collision Distance) */ - tx_control |= (0<<22); /* SWXOFF-bit (Software XOFF) */ - tx_control |= (1<<24); /* RTLC-bit (Re-Transmit on Late Collision) */ - tx_control |= (0<<25); /* UNORTX-bit (Underrun No Re-Transmit) */ - tx_control |= (0<<26); /* TXCSCMT=0 (TxDesc Mininum Threshold) */ - tx_control |= (0<<28); /* MULR-bit (Multiple Request Support) */ + tx_control |= (0 << 1); /* EN-bit (Enable) */ + tx_control |= (1 << 3); /* PSP-bit (Pad Short Packets) */ + tx_control |= (15 << 4); /* CT=15 (Collision Threshold) */ + tx_control |= (63 << 12); /* COLD=63 (Collision Distance) */ + tx_control |= (0 << 22); /* SWXOFF-bit (Software XOFF) */ + tx_control |= (1 << 24); /* RTLC-bit (Re-Transmit on Late Collision) */ + tx_control |= (0 << 25); /* UNORTX-bit (Underrun No Re-Transmit) */ + tx_control |= (0 << 26); /* TXCSCMT=0 (TxDesc Mininum Threshold) */ + tx_control |= (0 << 28); /* MULR-bit (Multiple Request Support) */ e1000_outl(dev, E1000_TCTL, tx_control); /* hardware flow control */ @@ -328,27 +330,27 @@ void e1000_init(struct e1000_dev *dev) /* get receive FIFO size */ - pba = (pba & 0x000000ff)<<10; + pba = (pba & 0x000000ff) << 10; e1000_outl(dev, E1000_FCAL, 0x00C28001); e1000_outl(dev, E1000_FCAH, 0x00000100); e1000_outl(dev, E1000_FCT, 0x00008808); e1000_outl(dev, E1000_FCTTV, 0x00000680); - e1000_outl(dev, E1000_FCRTL, (pba*8/10)|0x80000000); - e1000_outl(dev, E1000_FCRTH, pba*9/10); + e1000_outl(dev, E1000_FCRTL, (pba * 8 / 10) | 0x80000000); + e1000_outl(dev, E1000_FCRTH, pba * 9 / 10); /* setup tx rings */ txd_phys = PADDR((uintptr_t)dev->tx_ring.desc); kmem_phys = PADDR((uintptr_t)dev->tx_ring.buf); - for (i=0; itx_ring.desc[i].base_address = kmem_phys; + dev->tx_ring.desc[i].base_address = kmem_phys; dev->tx_ring.desc[i].packet_length = 0; - dev->tx_ring.desc[i].cksum_offset = 0; - dev->tx_ring.desc[i].cksum_origin = 0; - dev->tx_ring.desc[i].desc_status = 1; - dev->tx_ring.desc[i].desc_command = (1<<0)|(1<<1)|(1<<3); - dev->tx_ring.desc[i].special_info = 0; + dev->tx_ring.desc[i].cksum_offset = 0; + dev->tx_ring.desc[i].cksum_origin = 0; + dev->tx_ring.desc[i].desc_status = 1; + dev->tx_ring.desc[i].desc_command = (1 << 0) | (1 << 1) | (1 << 3); + dev->tx_ring.desc[i].special_info = 0; } dev->tx_ring.tail = 0; @@ -359,14 +361,14 @@ void e1000_init(struct e1000_dev *dev) e1000_outl(dev, E1000_TDBAL, txd_phys); e1000_outl(dev, E1000_TDBAH, 0x00000000); - e1000_outl(dev, E1000_TDLEN, CONFIG_E1000_N_TX_DESC*16); + e1000_outl(dev, E1000_TDLEN, CONFIG_E1000_N_TX_DESC * 16); e1000_outl(dev, E1000_TXDCTL, 0x01010000); /* setup rx rings */ rxd_phys = PADDR((uintptr_t)dev->rx_ring.desc); kmem_phys = PADDR((uintptr_t)dev->rx_ring.buf); - for (i=0; irx_ring.desc[i].base_address = kmem_phys; dev->rx_ring.desc[i].packet_length = 0; @@ -432,15 +434,13 @@ static int e1000_transmit(struct e1000_dev *e1000) return -1; } - /* Increment statistics */ - /* Send the packet: address=skel->sk_dev.d_buf, length=skel->sk_dev.d_len */ memcpy(cp, e1000->netdev.d_buf, e1000->netdev.d_len); /* prepare the transmit-descriptor */ - e1000->tx_ring.desc[tail].packet_length = count<60 ? 60:count; + e1000->tx_ring.desc[tail].packet_length = count < 60 ? 60 : count; e1000->tx_ring.desc[tail].desc_status = 0; /* give ownership of this descriptor to the network controller */ @@ -453,7 +453,8 @@ static int e1000_transmit(struct e1000_dev *e1000) /* Setup the TX timeout watchdog (perhaps restarting the timer) */ - wd_start(e1000->txtimeout, E1000_TXTIMEOUT, e1000_txtimeout, 1, (uint32_t)e1000); + wd_start(e1000->txtimeout, E1000_TXTIMEOUT, e1000_txtimeout, 1, + (wdparm_t)e1000); return OK; } @@ -561,8 +562,6 @@ static void e1000_receive(struct e1000_dev *e1000) while (e1000->rx_ring.desc[head].desc_status) { - /* Check for errors and update statistics */ - /* Here we do not handle packets that exceed packet-buffer size */ if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) @@ -725,8 +724,6 @@ static void e1000_txtimeout(int argc, uint32_t arg, ...) { struct e1000_dev *e1000 = (struct e1000_dev *)arg; - /* Increment statistics and dump debug info */ - /* Then reset the hardware */ e1000_init(e1000); @@ -773,11 +770,12 @@ static void e1000_polltimer(int argc, uint32_t arg, ...) * we will missing TCP time state updates? */ - (void)devif_timer(&e1000->netdev, e1000_txpoll, E1000_POLLHSEC); + (void)devif_timer(&e1000->netdev, e1000_txpoll); /* Setup the watchdog poll timer again */ - (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, arg); + (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, + (wdparm_t)arg); } /**************************************************************************** @@ -803,7 +801,7 @@ static int e1000_ifup(struct net_driver_s *dev) ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */ @@ -811,7 +809,8 @@ static int e1000_ifup(struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, (uint32_t)e1000); + (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, + (wdparm_t)e1000); if (e1000_inl(e1000, E1000_STATUS) & 2) { @@ -848,7 +847,7 @@ static int e1000_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); e1000_turn_off(e1000); @@ -867,7 +866,7 @@ static int e1000_ifdown(struct net_driver_s *dev) /* Mark the device "down" */ e1000->bifup = false; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -901,7 +900,7 @@ static int e1000_txavail(struct net_driver_s *dev) * level processing. */ - flags = irqsave(); + flags = enter_critical_section(); /* Ignore the notification if the interface is not yet up */ @@ -915,7 +914,7 @@ static int e1000_txavail(struct net_driver_s *dev) } } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -993,7 +992,7 @@ static irqreturn_t e1000_interrupt_handler(int irq, void *dev_id) /* Link status change */ - if (intr_cause & (1<<2)) + if (intr_cause & (1 << 2)) { if (e1000_inl(e1000, E1000_STATUS) & 2) { @@ -1009,34 +1008,28 @@ static irqreturn_t e1000_interrupt_handler(int irq, void *dev_id) /* Rx-descriptor Timer expired */ - if (intr_cause & (1<<7)) + if (intr_cause & (1 << 7)) { e1000_receive(e1000); } /* Tx queue empty */ - if (intr_cause & (1<<1)) + if (intr_cause & (1 << 1)) { wd_cancel(e1000->txtimeout); } - /* Check is a packet transmission just completed. If so, call skel_txdone. - * This may disable further Tx interrupts if there are no pending - * tansmissions. - */ - /* Tx-descriptor Written back */ - if (intr_cause & (1<<0)) + if (intr_cause & (1 << 0)) { devif_poll(&e1000->netdev, e1000_txpoll); } - /* Rx-Descriptors Low */ - if (intr_cause & (1<<4)) + if (intr_cause & (1 << 4)) { int tail; @@ -1054,12 +1047,42 @@ static irqreturn_t e1000_interrupt_handler(int irq, void *dev_id) static pci_id_t e1000_id_table[] = { - {.sep = {INTEL_VENDERID, E1000_82573L}}, - {.sep = {INTEL_VENDERID, E1000_82540EM}}, - {.sep = {INTEL_VENDERID, E1000_82574L}}, - {.sep = {INTEL_VENDERID, E1000_82567LM}}, - {.sep = {INTEL_VENDERID, E1000_82541PI}}, - {.sep = {0,0}} + { + .sep = + { + INTEL_VENDERID, E1000_82573L + } + }, + { + .sep = + { + INTEL_VENDERID, E1000_82540EM + } + }, + { + .sep = + { + INTEL_VENDERID, E1000_82574L + } + }, + { + .sep = + { + INTEL_VENDERID, E1000_82567LM + } + }, + { + .sep = + { + INTEL_VENDERID, E1000_82541PI + } + }, + { + .sep = + { + 0, 0 + } + } }; static int e1000_probe(uint16_t addr, pci_id_t id) @@ -1128,8 +1151,8 @@ static int e1000_probe(uint16_t addr, pci_id_t id) * access performance. The page size alloc will restrict * this bad effect only within the memory we alloc here. * - * NEED FIX: the memalign may alloc memory continous in - * virtual address but dis-continous in physical address + * NEED FIX: the memalign may alloc memory continuous in + * virtual address but dis-continuous in physical address * due to RGMP memory setup. */ @@ -1149,14 +1172,14 @@ static int e1000_probe(uint16_t addr, pci_id_t id) /* alloc memory for tx ring */ - dev->tx_ring.desc = (struct tx_desc*)kmem; + dev->tx_ring.desc = (FAR struct tx_desc *)kmem; kmem += CONFIG_E1000_N_TX_DESC * sizeof(struct tx_desc); dev->tx_ring.buf = kmem; kmem += CONFIG_E1000_N_TX_DESC * CONFIG_E1000_BUFF_SIZE; /* alloc memory for rx rings */ - dev->rx_ring.desc = (struct rx_desc*)kmem; + dev->rx_ring.desc = (FAR struct rx_desc *)kmem; kmem += CONFIG_E1000_N_RX_DESC * sizeof(struct rx_desc); dev->rx_ring.buf = kmem; @@ -1235,7 +1258,7 @@ void e1000_mod_exit(void) CONFIG_E1000_N_RX_DESC * CONFIG_E1000_BUFF_SIZE; size = ROUNDUP(size, PGSIZE); - for (dev=e1000_list.next; dev!=NULL; dev=dev->next) + for (dev = e1000_list.next; dev != NULL; dev = dev->next) { netdev_unregister(&dev->netdev); e1000_reset(dev); diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 34bffa07c75d42541efd53eb8060b0483727af49..2ae3a01ebd53ffba86cea1857d7319e34cfa3437 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/enc28j60.c * - * Copyright (C) 2010-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2012, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -55,8 +55,8 @@ #include -#include #include +#include #include #include #include @@ -85,7 +85,6 @@ * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 * devices that will be supported. - * CONFIG_ENC28J60_STATS - Collect network statistics * CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex */ @@ -145,7 +144,6 @@ /* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define ENC_WDDELAY (1*CLK_TCK) -#define ENC_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -203,7 +201,7 @@ # define enc_cmddump(c) \ lowsyslog(LOG_DEBUG, "ENC28J60: CMD: %02x\n", c); # define enc_bmdump(c,b,s) \ - lowsyslog(LOG_DEBUG, "ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s); + lowsyslog(LOG_DEBUG, "ENC28J60: CMD: %02x buffer: %p length: %d\n", c, b, s); #else # define enc_wrdump(a,v) # define enc_rddump(a,v) @@ -257,12 +255,6 @@ struct enc_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ - - /* Statistics */ - -#ifdef CONFIG_ENC28J60_STATS - struct enc_stats_s stats; -#endif }; /**************************************************************************** @@ -277,15 +269,9 @@ static struct enc_driver_s g_enc28j60[CONFIG_ENC28J60_NINTERFACES]; /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS static inline void enc_configspi(FAR struct spi_dev_s *spi); -# define enc_lock(priv); -# define enc_unlock(priv); -#else -# define enc_configspi(spi) static void enc_lock(FAR struct enc_driver_s *priv); static inline void enc_unlock(FAR struct enc_driver_s *priv); -#endif /* SPI control register access */ @@ -379,18 +365,15 @@ static int enc_reset(FAR struct enc_driver_s *priv); * ****************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS static inline void enc_configspi(FAR struct spi_dev_s *spi) { - /* Configure SPI for the ENC28J60. But only if we own the SPI bus. - * Otherwise, don't bother because it might change. - */ + /* Configure SPI for the ENC28J60. */ SPI_SETMODE(spi, CONFIG_ENC28J60_SPIMODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_ENC28J60_FREQUENCY) + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_ENC28J60_FREQUENCY); } -#endif /**************************************************************************** * Function: enc_lock @@ -408,7 +391,6 @@ static inline void enc_configspi(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void enc_lock(FAR struct enc_driver_s *priv) { /* Lock the SPI bus in case there are multiple devices competing for the SPI @@ -423,9 +405,9 @@ static void enc_lock(FAR struct enc_driver_s *priv) SPI_SETMODE(priv->spi, CONFIG_ENC28J60_SPIMODE); SPI_SETBITS(priv->spi, 8); - SPI_SETFREQUENCY(priv->spi, CONFIG_ENC28J60_FREQUENCY); + (void)SPI_HWFEATURES(priv->spi, 0); + (void)SPI_SETFREQUENCY(priv->spi, CONFIG_ENC28J60_FREQUENCY); } -#endif /**************************************************************************** * Function: enc_unlock @@ -443,14 +425,12 @@ static void enc_lock(FAR struct enc_driver_s *priv) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void enc_unlock(FAR struct enc_driver_s *priv) { /* Relinquish the lock on the bus. */ SPI_LOCK(priv->spi, false); } -#endif /**************************************************************************** * Function: enc_rdgreg2 @@ -478,7 +458,7 @@ static uint8_t enc_rdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd) /* Select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the read command and collect the data. The sequence requires * 16-clocks: 8 to clock out the cmd + 8 to clock in the data. @@ -521,7 +501,7 @@ static void enc_wrgreg2(FAR struct enc_driver_s *priv, uint8_t cmd, /* Select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the write command and data. The sequence requires 16-clocks: * 8 to clock out the cmd + 8 to clock out the data. @@ -565,7 +545,7 @@ static inline void enc_src(FAR struct enc_driver_s *priv) /* Select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the system reset command. */ @@ -612,7 +592,7 @@ static inline void enc_src(FAR struct enc_driver_s *priv) static void enc_setbank(FAR struct enc_driver_s *priv, uint8_t bank) { - /* Check if the bank setting has changed*/ + /* Check if the bank setting has changed */ if (bank != priv->bank) { @@ -662,7 +642,7 @@ static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg) /* Re-select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the RCR command and collect the data. How we collect the data * depends on if this is a PHY/CAN or not. The normal sequence requires @@ -719,7 +699,7 @@ static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, /* Re-select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the WCR command and data. The sequence requires 16-clocks: * 8 to clock out the cmd + 8 to clock out the data. @@ -757,8 +737,8 @@ static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg, uint8_t bits, uint8_t value) { - uint32_t start = clock_systimer(); - uint32_t elapsed; + systime_t start = clock_systimer(); + systime_t elapsed; uint8_t rddata; /* Loop until the exit condition is met */ @@ -823,8 +803,8 @@ static void enc_rxdump(FAR struct enc_driver_s *priv) static void enc_txdump(FAR struct enc_driver_s *priv) { lowsyslog(LOG_DEBUG, "Tx Registers:\n"); - lowsyslog(LOG_DEBUG, " EIE: %02x EIR: %02x ESTAT: %02x\n", - enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),); + lowsyslog(LOG_DEBUG, " EIE: %02x EIR: %02x\n", + enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR)); lowsyslog(LOG_DEBUG, " ESTAT: %02x ECON1: %02x\n", enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1)); lowsyslog(LOG_DEBUG, " ETXST: %02x %02x\n", @@ -873,7 +853,7 @@ static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer, /* Select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the read buffer memory command (ignoring the response) */ @@ -918,7 +898,7 @@ static inline void enc_wrbuffer(FAR struct enc_driver_s *priv, * "The WBM command is started by lowering the CS pin. ..." */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the write buffer memory command (ignoring the response) * @@ -1113,9 +1093,7 @@ static int enc_transmit(FAR struct enc_driver_s *priv) /* Increment statistics */ nllvdbg("Sending packet, pktlen: %d\n", priv->dev.d_len); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txrequests++; -#endif + NETDEV_TXPACKETS(&priv->dev); /* Verify that the hardware is ready to send another packet. The driver * starts a transmission process by setting ECON1.TXRTS. When the packet is @@ -1167,7 +1145,8 @@ static int enc_transmit(FAR struct enc_driver_s *priv) * the timer is started? */ - (void)wd_start(priv->txtimeout, ENC_TXTIMEOUT, enc_txtimeout, 1, (uint32_t)priv); + (void)wd_start(priv->txtimeout, ENC_TXTIMEOUT, enc_txtimeout, 1, + (wdparm_t)priv); return OK; } @@ -1290,13 +1269,7 @@ static void enc_txif(FAR struct enc_driver_s *priv) { /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txifs++; - if (enc_rdgreg(priv, ENC_ESTAT) & ESTAT_TXABRT) - { - priv->stats.txabrts++; - } -#endif + NETDEV_TXDONE(&priv->dev); /* Clear the request to send bit */ @@ -1306,6 +1279,15 @@ static void enc_txif(FAR struct enc_driver_s *priv) wd_cancel(priv->txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, + (wdparm_t)priv); + /* Then poll uIP for new XMIT data */ (void)devif_poll(&priv->dev, enc_txpoll); @@ -1331,9 +1313,7 @@ static void enc_txerif(FAR struct enc_driver_s *priv) { /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txerifs++; -#endif + NETDEV_TXERRORS(&priv->dev); /* Reset TX */ @@ -1375,11 +1355,7 @@ static void enc_txerif(FAR struct enc_driver_s *priv) static void enc_rxerif(FAR struct enc_driver_s *priv) { - /* Update statistics */ - -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxerifs++; -#endif + /* REVISIT: Update statistics */ } /**************************************************************************** @@ -1413,6 +1389,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1453,6 +1430,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); /* Give the IPv6 packet to the network layer */ @@ -1490,6 +1468,8 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { nllvdbg("ARP packet received (%02x)\n", BUF->type); + NETDEV_RXARP(&priv->dev); + arp_arpin(&priv->dev); /* If the above function invocation resulted in data that should be @@ -1505,6 +1485,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) #endif { nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type)); + NETDEV_RXDROPPED(&priv->dev); } } @@ -1533,9 +1514,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.pktifs++; -#endif + NETDEV_RXPACKETS(&priv->dev); /* Set the read pointer to the start of the received packet (ERDPT) */ @@ -1572,9 +1551,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) if ((rxstat & RXSTAT_OK) == 0) { nlldbg("ERROR: RXSTAT: %04x\n", rxstat); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxnotok++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Check for a usable packet length (4 added for the CRC) */ @@ -1582,16 +1559,14 @@ static void enc_pktif(FAR struct enc_driver_s *priv) else if (pktlen > (CONFIG_NET_ETH_MTU + 4) || pktlen <= (ETH_HDRLEN + 4)) { nlldbg("Bad packet size dropped (%d)\n", pktlen); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxpktlen++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Otherwise, read and process the packet */ else { - /* Save the packet length (without the 4 byte CRC) in priv->dev.d_len*/ + /* Save the packet length (without the 4 byte CRC) in priv->dev.d_len */ priv->dev.d_len = pktlen - 4; @@ -1615,7 +1590,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) enc_wrbreg(priv, ENC_ERXRDPTL, (priv->nextpkt)); enc_wrbreg(priv, ENC_ERXRDPTH, (priv->nextpkt) >> 8); - /* Decrement the packet counter indicate we are done with this packet */ + /* Decrement the packet counter indicate we are done with this packet */ enc_bfsgreg(priv, ENC_ECON2, ECON2_PKTDEC); } @@ -1787,18 +1762,13 @@ static void enc_irqworker(FAR void *arg) /* Ignore PKTIF because is unreliable. Use EPKTCNT instead */ /* if ((eir & EIR_PKTIF) != 0) */ + { uint8_t pktcnt = enc_rdbreg(priv, ENC_EPKTCNT); if (pktcnt > 0) { nllvdbg("EPKTCNT: %02x\n", pktcnt); -#ifdef CONFIG_ENC28J60_STATS - if (pktcnt > priv->stats.maxpktcnt) - { - priv->stats.maxpktcnt = pktcnt; - } -#endif /* Handle packet receipt */ enc_pktif(priv); @@ -1917,9 +1887,7 @@ static void enc_toworker(FAR void *arg) /* Increment statistics and dump debug info */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txtimeouts++; -#endif + NETDEV_TXTIMEOUTS(&priv->dev); /* Then reset the hardware: Take the interface down, then bring it * back up @@ -2023,7 +1991,7 @@ static void enc_pollworker(FAR void *arg) * in progress, we will missing TCP time state updates? */ - (void)devif_timer(&priv->dev, enc_txpoll, ENC_POLLHSEC); + (void)devif_timer(&priv->dev, enc_txpoll); } /* Release lock on the SPI bus and uIP */ @@ -2033,7 +2001,8 @@ static void enc_pollworker(FAR void *arg) /* Setup the watchdog poll timer again */ - (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, arg); + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, + (wdparm_t)arg); } /**************************************************************************** @@ -2100,7 +2069,7 @@ static int enc_ifup(struct net_driver_s *dev) nlldbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Lock the SPI bus so that we have exclusive access */ @@ -2131,7 +2100,8 @@ static int enc_ifup(struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, (uint32_t)priv); + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, + (wdparm_t)priv); /* Mark the interface up and enable the Ethernet interrupt at the * controller @@ -2171,7 +2141,7 @@ static int enc_ifdown(struct net_driver_s *dev) nlldbg("Taking down: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Lock the SPI bus so that we have exclusive access */ @@ -2179,7 +2149,7 @@ static int enc_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); priv->lower->disable(priv->lower); /* Cancel the TX poll timer and TX timeout timers */ @@ -2193,7 +2163,7 @@ static int enc_ifdown(struct net_driver_s *dev) enc_pwrsave(priv); priv->ifstate = ENCSTATE_DOWN; - irqrestore(flags); + leave_critical_section(flags); /* Un-lock the SPI bus */ @@ -2231,7 +2201,7 @@ static int enc_txavail(struct net_driver_s *dev) /* Ignore the notification if the interface is not yet up */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->ifstate == ENCSTATE_UP) { /* Check if the hardware is ready to send another packet. The driver @@ -2250,7 +2220,7 @@ static int enc_txavail(struct net_driver_s *dev) /* Un-lock the SPI bus */ - irqrestore(flags); + leave_critical_section(flags); enc_unlock(priv); return OK; } @@ -2693,42 +2663,4 @@ int enc_initialize(FAR struct spi_dev_s *spi, return netdev_register(&priv->dev, NET_LL_ETHERNET); } -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENC28J60 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENC28J60 is supported, then this is the - * zero based number that identifies the ENC28J60; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENC28J60_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats) -{ - FAR struct enc_driver_s *priv ; - irqstate_t flags; - - DEBUGASSERT(devno < CONFIG_ENC28J60_NINTERFACES); - priv = &g_enc28j60[devno]; - - /* Disable the Ethernet interrupt */ - - flags = irqsave(); - memcpy(stats, &priv->stats, sizeof(struct enc_stats_s)); - memset(&priv->stats, 0, sizeof(struct enc_stats_s)); - irqrestore(flags); - return OK; -} -#endif #endif /* CONFIG_NET && CONFIG_ENC28J60_NET */ - diff --git a/drivers/net/enc28j60.h b/drivers/net/enc28j60.h index d717ff82a3031fd9f625b3ee2390904b7488cfd1..324efa4bacd989ee2c6f1185822e23276517f3c9 100644 --- a/drivers/net/enc28j60.h +++ b/drivers/net/enc28j60.h @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/enc28j60.h * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -460,7 +460,8 @@ #ifdef __cplusplus #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif diff --git a/drivers/net/encx24j600.c b/drivers/net/encx24j600.c index ca47a01730c2a39ed18108dca57784934bedc4d8..aae63dcebb0580bebc1aa61aac627c916d0a2859 100644 --- a/drivers/net/encx24j600.c +++ b/drivers/net/encx24j600.c @@ -91,7 +91,6 @@ * CONFIG_ENCX24J600_FREQUENCY - Define to use a different bus frequency * CONFIG_ENCX24J600_NINTERFACES - Specifies the number of physical ENCX24J600 * devices that will be supported. - * CONFIG_ENCX24J600_STATS - Collect network statistics */ /* The ENCX24J600 spec says that it supports SPI mode 0,0 only: "The @@ -150,7 +149,6 @@ /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define ENC_WDDELAY (1*CLK_TCK) -#define ENC_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -199,7 +197,7 @@ # define enc_cmddump(c) \ lowsyslog(LOG_DEBUG, "ENCX24J600: CMD: %02x\n", c); # define enc_bmdump(c,b,s) \ - lowsyslog(LOG_DEBUG, "ENCX24J600: CMD: %02x buffer: %p length: %d\n", c,b,s); + lowsyslog(LOG_DEBUG, "ENCX24J600: CMD: %02x buffer: %p length: %d\n", c, b, s); #else # define enc_wrdump(a,v) # define enc_rddump(a,v) @@ -249,9 +247,7 @@ struct enc_driver_s WDOG_ID txpoll; /* TX poll timer */ WDOG_ID txtimeout; /* TX timeout timer */ - /* If we don't own the SPI bus, then we cannot do SPI accesses from the - * interrupt handler. - */ + /* Avoid SPI accesses from the interrupt handler by using the work queue */ struct work_s irqwork; /* Interrupt continuation work queue support */ struct work_s towork; /* Tx timeout work queue support */ @@ -272,12 +268,6 @@ struct enc_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ - - /* Statistics */ - -#ifdef CONFIG_ENCX24J600_STATS - struct enc_stats_s stats; -#endif }; /**************************************************************************** @@ -292,15 +282,8 @@ static struct enc_driver_s g_encx24j600[CONFIG_ENCX24J600_NINTERFACES]; /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS -static inline void enc_configspi(FAR struct spi_dev_s *spi); -# define enc_lock(priv); -# define enc_unlock(priv); -#else -# define enc_configspi(spi) static void enc_lock(FAR struct enc_driver_s *priv); static inline void enc_unlock(FAR struct enc_driver_s *priv); -#endif /* SPI control register access */ @@ -344,8 +327,8 @@ static int enc_txpoll(struct net_driver_s *dev); /* Common RX logic */ static struct enc_descr_s *enc_rxgetdescr(FAR struct enc_driver_s *priv); -static void enc_rxldpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr); -static void enc_rxrmpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr); +static void enc_rxldpkt(FAR struct enc_driver_s *priv, FAR struct enc_descr_s *descr); +static void enc_rxrmpkt(FAR struct enc_driver_s *priv, FAR struct enc_descr_s *descr); static void enc_rxdispatch(FAR struct enc_driver_s *priv); /* Interrupt handling */ @@ -386,35 +369,6 @@ static int enc_reset(FAR struct enc_driver_s *priv); * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: enc_configspi - * - * Description: - * Configure the SPI for use with the ENCX24J600 - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void enc_configspi(FAR struct spi_dev_s *spi) -{ - /* Configure SPI for the ENCX24J600. But only if we own the SPI bus. - * Otherwise, don't bother because it might change. - */ - - SPI_SETMODE(spi, CONFIG_ENCX24J600_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_ENCX24J600_FREQUENCY); -} -#endif - /**************************************************************************** * Function: enc_lock * @@ -431,7 +385,6 @@ static inline void enc_configspi(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void enc_lock(FAR struct enc_driver_s *priv) { /* Lock the SPI bus in case there are multiple devices competing for the SPI @@ -446,9 +399,9 @@ static void enc_lock(FAR struct enc_driver_s *priv) SPI_SETMODE(priv->spi, CONFIG_ENCX24J600_SPIMODE); SPI_SETBITS(priv->spi, 8); - SPI_SETFREQUENCY(priv->spi, CONFIG_ENCX24J600_FREQUENCY); + (void)SPI_HWFEATURES(priv->spi, 0); + (void)SPI_SETFREQUENCY(priv->spi, CONFIG_ENCX24J600_FREQUENCY); } -#endif /**************************************************************************** * Function: enc_unlock @@ -466,14 +419,12 @@ static void enc_lock(FAR struct enc_driver_s *priv) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void enc_unlock(FAR struct enc_driver_s *priv) { /* Relinquish the lock on the bus. */ SPI_LOCK(priv->spi, false); } -#endif /**************************************************************************** * Function: enc_cmd @@ -499,7 +450,7 @@ static void enc_cmd(FAR struct enc_driver_s *priv, uint8_t cmd, uint16_t arg) /* Select ENCX24J600 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); (void)SPI_SEND(priv->spi, cmd); /* Clock out the command */ (void)SPI_SEND(priv->spi, arg & 0xff); /* Clock out the low byte */ @@ -533,7 +484,7 @@ static inline void enc_setethrst(FAR struct enc_driver_s *priv) /* Select ENC28J60 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Send the system reset command. */ @@ -651,7 +602,7 @@ static void enc_wrreg(FAR struct enc_driver_s *priv, uint16_t ctrlreg, DEBUGASSERT(priv && priv->spi); DEBUGASSERT((ctrlreg & 0xe0) == 0); /* banked regeitsers only */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); enc_setbank(priv, GETBANK(ctrlreg)); @@ -686,8 +637,8 @@ static void enc_wrreg(FAR struct enc_driver_s *priv, uint16_t ctrlreg, static int enc_waitreg(FAR struct enc_driver_s *priv, uint16_t ctrlreg, uint16_t bits, uint16_t value) { - uint32_t start = clock_systimer(); - uint32_t elapsed; + systime_t start = clock_systimer(); + systime_t elapsed; uint16_t rddata; /* Loop until the exit condition is met */ @@ -729,7 +680,7 @@ static void enc_bfs(FAR struct enc_driver_s *priv, uint16_t ctrlreg, /* Select ENCX24J600 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Set the bank */ @@ -774,7 +725,7 @@ static void enc_bfc(FAR struct enc_driver_s *priv, uint16_t ctrlreg, /* Select ENCX24J600 chip */ - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); /* Set the bank */ @@ -842,8 +793,8 @@ static void enc_rxdump(FAR struct enc_driver_s *priv) static void enc_txdump(FAR struct enc_driver_s *priv) { lowsyslog(LOG_DEBUG, "Tx Registers:\n"); - lowsyslog(LOG_DEBUG, " EIE: %02x EIR: %02x ESTAT: %02x\n", - enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),); + lowsyslog(LOG_DEBUG, " EIE: %02x EIR: %02x\n", + enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR)); lowsyslog(LOG_DEBUG, " ESTAT: %02x ECON1: %02x\n", enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1)); lowsyslog(LOG_DEBUG, " ETXST: %02x %02x\n", @@ -932,7 +883,7 @@ static inline void enc_wrbuffer(FAR struct enc_driver_s *priv, { DEBUGASSERT(priv && priv->spi); - SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);; + SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true); SPI_SEND(priv->spi, ENC_WGPDATA); SPI_SNDBLOCK(priv->spi, buffer, buflen); @@ -1071,11 +1022,11 @@ static void enc_wrphy(FAR struct enc_driver_s *priv, uint8_t phyaddr, static int enc_transmit(FAR struct enc_driver_s *priv) { - struct enc_descr_s *descr; + FAR struct enc_descr_s *descr; /* dequeue next packet to transmit */ - descr = (struct enc_descr_s*)sq_remfirst(&priv->txqueue); + descr = (FAR struct enc_descr_s *)sq_remfirst(&priv->txqueue); DEBUGASSERT(descr != NULL); @@ -1106,11 +1057,11 @@ static int enc_transmit(FAR struct enc_driver_s *priv) */ (void)wd_start(priv->txtimeout, ENC_TXTIMEOUT, enc_txtimeout, 1, - (uint32_t)priv); + (wdparm_t)priv); /* free the descriptor */ - sq_addlast((sq_entry_t*)descr, &priv->txfreedescr); + sq_addlast((FAR sq_entry_t *)descr, &priv->txfreedescr); return OK; } @@ -1137,17 +1088,15 @@ static int enc_transmit(FAR struct enc_driver_s *priv) static int enc_txenqueue(FAR struct enc_driver_s *priv) { int ret = OK; - struct enc_descr_s *descr; + FAR struct enc_descr_s *descr; DEBUGASSERT(priv->dev.d_len > 0); /* Increment statistics */ -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.txrequests++; -#endif + NETDEV_TXPACKETS(&priv->dev); - descr = (struct enc_descr_s*)sq_remfirst(&priv->txfreedescr); + descr = (FAR struct enc_descr_s *)sq_remfirst(&priv->txfreedescr); if (descr != NULL) { @@ -1167,7 +1116,7 @@ static int enc_txenqueue(FAR struct enc_driver_s *priv) /* enqueue packet */ - sq_addlast((sq_entry_t*)descr, &priv->txqueue); + sq_addlast((FAR sq_entry_t *)descr, &priv->txqueue); /* if currently no transmission is active, trigger the transmission */ @@ -1330,19 +1279,30 @@ static void enc_linkstatus(FAR struct enc_driver_s *priv) static void enc_txif(FAR struct enc_driver_s *priv) { + NETDEV_TXDONE(&priv->dev); + if (sq_empty(&priv->txqueue)) { /* If no further xmits are pending, then cancel the TX timeout */ wd_cancel(priv->txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, + (wdparm_t)priv); + /* Poll for TX packets from the networking layer */ devif_poll(&priv->dev, enc_txpoll); } else { - /* process txqueue */ + /* Process txqueue */ enc_transmit(priv); } @@ -1367,7 +1327,7 @@ static void enc_txif(FAR struct enc_driver_s *priv) ****************************************************************************/ static void enc_rxldpkt(FAR struct enc_driver_s *priv, - struct enc_descr_s *descr) + FAR struct enc_descr_s *descr) { DEBUGASSERT(priv != NULL && descr != NULL); @@ -1414,10 +1374,10 @@ static struct enc_descr_s *enc_rxgetdescr(FAR struct enc_driver_s *priv) /* Packets are held in the enc's SRAM until the space is needed */ - enc_rxrmpkt(priv, (struct enc_descr_s*)sq_peek(&priv->rxqueue)); + enc_rxrmpkt(priv, (FAR struct enc_descr_s *)sq_peek(&priv->rxqueue)); } - return (struct enc_descr_s*)sq_remfirst(&priv->rxfreedescr); + return (FAR struct enc_descr_s *)sq_remfirst(&priv->rxfreedescr); } /**************************************************************************** @@ -1439,7 +1399,7 @@ static struct enc_descr_s *enc_rxgetdescr(FAR struct enc_driver_s *priv) * ****************************************************************************/ -static void enc_rxrmpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr) +static void enc_rxrmpkt(FAR struct enc_driver_s *priv, FAR struct enc_descr_s *descr) { uint16_t addr; @@ -1452,7 +1412,7 @@ static void enc_rxrmpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr if (descr != NULL) { - if (descr == (struct enc_descr_s*)sq_peek(&priv->rxqueue)) + if (descr == (FAR struct enc_descr_s *)sq_peek(&priv->rxqueue)) { /* Wrap address properly around */ addr = (descr->addr - PKTMEM_RX_START + descr->len - 2 + PKTMEM_RX_SIZE) @@ -1472,10 +1432,10 @@ static void enc_rxrmpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr { /* Remove packet from RX queue */ - sq_rem((sq_entry_t*)descr, &priv->rxqueue); + sq_rem((FAR sq_entry_t *)descr, &priv->rxqueue); } - sq_addlast((sq_entry_t*)descr, &priv->rxfreedescr); + sq_addlast((FAR sq_entry_t *)descr, &priv->rxfreedescr); } } @@ -1498,14 +1458,14 @@ static void enc_rxrmpkt(FAR struct enc_driver_s *priv, struct enc_descr_s *descr static void enc_rxdispatch(FAR struct enc_driver_s *priv) { - struct enc_descr_s *descr; + FAR struct enc_descr_s *descr; struct enc_descr_s *next; int ret = ERROR; /* Process the RX queue */ - descr = (struct enc_descr_s*)sq_peek(&priv->rxqueue); + descr = (FAR struct enc_descr_s *)sq_peek(&priv->rxqueue); while (descr != NULL) { @@ -1513,7 +1473,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) * flink to NULL */ - next = (struct enc_descr_s*)sq_next(descr); + next = (FAR struct enc_descr_s *)sq_next(descr); /* Load the packet from the enc's SRAM */ @@ -1531,6 +1491,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1539,7 +1500,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) arp_ipin(&priv->dev); ret = ipv4_input(&priv->dev); - if (ret == OK || (clock_systimer() - descr->ts) > ENC_RXTIMEOUT) + if (ret == OK || (clock_systimer() - (systime_t)descr->ts) > ENC_RXTIMEOUT) { /* If packet has been successfully processed or has timed out, * free it. @@ -1580,12 +1541,13 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); /* Give the IPv6 packet to the network layer */ ret = ipv6_input(&priv->dev); - if (ret == OK || (clock_systimer() - descr->ts) > ENC_RXTIMEOUT) + if (ret == OK || (clock_systimer() - (systime_t)descr->ts) > ENC_RXTIMEOUT) { /* If packet has been successfully processed or has timed out, * free it. @@ -1626,6 +1588,8 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { nllvdbg("ARP packet received (%02x)\n", BUF->type); + NETDEV_RXARP(&priv->dev); + arp_arpin(&priv->dev); /* ARP packets are freed immediately */ @@ -1649,6 +1613,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) enc_rxrmpkt(priv, descr); nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type)); + NETDEV_RXDROPPED(&priv->dev); } descr = next; @@ -1674,7 +1639,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) static void enc_pktif(FAR struct enc_driver_s *priv) { - struct enc_descr_s *descr; + FAR struct enc_descr_s *descr; uint8_t rsv[8]; uint16_t pktlen; uint32_t rxstat; @@ -1730,13 +1695,13 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Set current timestamp */ - descr->ts = clock_systimer(); + descr->ts = (uint32_t)clock_systimer(); /* Store the start address of the frame without the enc's header */ descr->addr = curpkt + 8; descr->len = pktlen; - sq_addlast((sq_entry_t*)descr, &priv->rxqueue); + sq_addlast((FAR sq_entry_t *)descr, &priv->rxqueue); /* Check if the packet was received OK */ @@ -1747,10 +1712,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Discard packet */ enc_rxrmpkt(priv, descr); - -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxnotok++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Check for a usable packet length (4 added for the CRC) */ @@ -1762,10 +1724,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Discard packet */ enc_rxrmpkt(priv, descr); - -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxpktlen++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Decrement PKTCNT */ @@ -1810,7 +1769,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) static void enc_rxabtif(FAR struct enc_driver_s *priv) { - struct enc_descr_s *descr; + FAR struct enc_descr_s *descr; #if 0 /* Free the last received packet from the RX queue */ @@ -1821,18 +1780,18 @@ static void enc_rxabtif(FAR struct enc_driver_s *priv) nlldbg("ERXTAIL: %04x\n", enc_rdreg(priv, ENC_ERXTAIL)); nlldbg("ERXHAED: %04x\n", enc_rdreg(priv, ENC_ERXHEAD)); - descr = (struct enc_descr_s*)sq_peek(&priv->rxqueue); + descr = (FAR struct enc_descr_s *)sq_peek(&priv->rxqueue); while (descr != NULL) { nlldbg("addr: %04x len: %d\n", descr->addr, descr->len); - descr = (struct enc_descr_s*)sq_next(descr); + descr = (FAR struct enc_descr_s *)sq_next(descr); } DEBUGASSERT(false); #endif - descr = (struct enc_descr_s*)sq_peek(&priv->rxqueue); + descr = (FAR struct enc_descr_s *)sq_peek(&priv->rxqueue); if (descr != NULL) { @@ -1951,9 +1910,7 @@ static void enc_irqworker(FAR void *arg) if ((eir & EIR_RXABTIF) != 0) /* Receive Abort */ { -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxerifs++; -#endif + NETDEV_RXERRORS(&priv->dev); enc_rxabtif(priv); enc_bfc(priv, ENC_EIR, EIR_RXABTIF); /* Clear the RXABTIF interrupt */ } @@ -1980,7 +1937,7 @@ static void enc_irqworker(FAR void *arg) */ } -#ifdef CONFIG_ENCX24J600_STATS +#ifdef CONFIG_NETDEV_STATISTICS /* The transmit abort interrupt occurs when the transmission of a frame * has been aborted. An abort can occur for any of the following reasons: * @@ -2004,7 +1961,7 @@ static void enc_irqworker(FAR void *arg) if ((eir & EIR_TXABTIF) != 0) /* Transmit Abort */ { - priv->stats.txerifs++; + NETDEV_TXERRORS(&priv->dev); enc_bfc(priv, ENC_EIR, EIR_TXABTIF); /* Clear the TXABTIF interrupt */ } #endif @@ -2095,9 +2052,7 @@ static void enc_toworker(FAR void *arg) /* Increment statistics and dump debug info */ -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.txtimeouts++; -#endif + NETDEV_TXTIMEOUTS(&priv->dev); /* Then reset the hardware: Take the interface down, then bring it * back up @@ -2201,7 +2156,7 @@ static void enc_pollworker(FAR void *arg) * in progress, we will missing TCP time state updates? */ - (void)devif_timer(&priv->dev, enc_txpoll, ENC_POLLHSEC); + (void)devif_timer(&priv->dev, enc_txpoll); } /* Release lock on the SPI bus and uIP */ @@ -2211,7 +2166,7 @@ static void enc_pollworker(FAR void *arg) /* Setup the watchdog poll timer again */ - (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, arg); + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, (wdparm_t)arg); } /**************************************************************************** @@ -2278,7 +2233,7 @@ static int enc_ifup(struct net_driver_s *dev) nlldbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Lock the SPI bus so that we have exclusive access */ @@ -2300,9 +2255,9 @@ static int enc_ifup(struct net_driver_s *dev) enc_bfc(priv, ENC_EIR, EIR_ALLINTS); enc_bfs(priv, ENC_EIE, EIE_INTIE | EIE_LINKIE | EIE_PKTIE | EIE_RXABTIE | - EIE_TXIE ); + EIE_TXIE); -#ifdef CONFIG_ENCX24J600_STATS +#ifdef CONFIG_NETDEV_STATISTICS enc_bfs(priv, ENC_EIE, EIE_TXABTIE); #endif @@ -2312,7 +2267,8 @@ static int enc_ifup(struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, (uint32_t)priv); + (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, + (wdparm_t)priv); /* Mark the interface up and enable the Ethernet interrupt at the * controller @@ -2353,7 +2309,7 @@ static int enc_ifdown(struct net_driver_s *dev) nlldbg("Taking down: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Lock the SPI bus so that we have exclusive access */ @@ -2361,7 +2317,7 @@ static int enc_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); priv->lower->disable(priv->lower); /* Cancel the TX poll timer and TX timeout timers */ @@ -2375,7 +2331,7 @@ static int enc_ifdown(struct net_driver_s *dev) enc_pwrsave(priv); priv->ifstate = ENCSTATE_DOWN; - irqrestore(flags); + leave_critical_section(flags); /* Un-lock the SPI bus */ @@ -2414,7 +2370,7 @@ static int enc_txavail(struct net_driver_s *dev) /* Ignore the notification if the interface is not yet up */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->ifstate == ENCSTATE_RUNNING) { /* Check if the hardware is ready to send another packet. The driver @@ -2433,7 +2389,7 @@ static int enc_txavail(struct net_driver_s *dev) /* Un-lock the SPI bus */ - irqrestore(flags); + leave_critical_section(flags); enc_unlock(priv); return OK; @@ -2739,14 +2695,14 @@ static void enc_resetbuffers(FAR struct enc_driver_s *priv) for (i = 0; i < ENC_NTXDESCR; i++) { priv->txdescralloc[i].addr = PKTMEM_START + PKTMEM_ALIGNED_BUFSIZE * i; - sq_addlast((sq_entry_t*)&priv->txdescralloc[i], &priv->txfreedescr); + sq_addlast((FAR sq_entry_t *)&priv->txdescralloc[i], &priv->txfreedescr); } /* Receive descriptors addresses are set on reception */ for (i = 0; i < CONFIG_ENCX24J600_NRXDESCR; i++) { - sq_addlast((sq_entry_t*)&priv->rxdescralloc[i], &priv->rxfreedescr); + sq_addlast((FAR sq_entry_t *)&priv->rxdescralloc[i], &priv->rxfreedescr); } } @@ -2936,10 +2892,6 @@ int enc_initialize(FAR struct spi_dev_s *spi, return -EAGAIN; } - /* Configure SPI for the ENCX24J600 */ - - enc_configspi(priv->spi); - /* Lock the SPI bus so that we have exclusive access */ enc_lock(priv); @@ -2961,41 +2913,4 @@ int enc_initialize(FAR struct spi_dev_s *spi, return netdev_register(&priv->dev, NET_LL_ETHERNET); } -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENCX24J600 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENCX24J600 is supported, then this is the - * zero based number that identifies the ENCX24J600; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENCX24J600_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats) -{ - FAR struct enc_driver_s *priv ; - irqstate_t flags; - - DEBUGASSERT(devno < CONFIG_ENCX24J600_NINTERFACES); - priv = &g_encx24j600[devno]; - - /* Disable the Ethernet interrupt */ - - flags = irqsave(); - memcpy(stats, &priv->stats, sizeof(struct enc_stats_s)); - memset(&priv->stats, 0, sizeof(struct enc_stats_s)); - irqrestore(flags); - return OK; -} -#endif #endif /* CONFIG_NET && CONFIG_ENCX24J600_NET */ diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index 2a7b236ab47c1de034d6325b9d5d2c619dedbef0..fdf23a87e12514165be828cd3168c2ef9a585347 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -91,7 +91,6 @@ /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define FTMAC100_WDDELAY (1*CLK_TCK) -#define FTMAC100_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -163,6 +162,7 @@ struct ftmac100_driver_s uint32_t iobase; /* NuttX net data */ + bool ft_bifup; /* true:ifup false:ifdown */ WDOG_ID ft_txpoll; /* TX poll timer */ WDOG_ID ft_txtimeout; /* TX timeout timer */ @@ -283,9 +283,9 @@ static int ftmac100_transmit(FAR struct ftmac100_driver_s *priv) FAR struct ftmac100_register_s *iobase = (FAR struct ftmac100_register_s *)priv->iobase; FAR struct ftmac100_txdes_s *txdes; int len = priv->ft_dev.d_len; -// irqstate_t flags; -// flags = irqsave(); -// nvdbg("flags=%08x\n", flags); +//irqstate_t flags; +//flags = enter_critical_section(); +//nvdbg("flags=%08x\n", flags); txdes = ftmac100_current_txdes(priv); @@ -294,13 +294,11 @@ static int ftmac100_transmit(FAR struct ftmac100_driver_s *priv) * must have assured that there is no transmission in progress. */ - /* Increment statistics */ - len = len < ETH_ZLEN ? ETH_ZLEN : len; /* Send the packet: address=priv->ft_dev.d_buf, length=priv->ft_dev.d_len */ -// memcpy((void *)txdes->txdes2, priv->ft_dev.d_buf, len); +//memcpy((void *)txdes->txdes2, priv->ft_dev.d_buf, len); txdes->txdes2 = (unsigned int)priv->ft_dev.d_buf; txdes->txdes1 &= FTMAC100_TXDES1_EDOTR; txdes->txdes1 |= (FTMAC100_TXDES1_FTS | @@ -316,15 +314,16 @@ static int ftmac100_transmit(FAR struct ftmac100_driver_s *priv) priv->tx_pending++; /* Enable Tx polling */ - // FIXME: enable interrupts + /* FIXME: enable interrupts */ + putreg32(1, &iobase->txpd); /* Setup the TX timeout watchdog (perhaps restarting the timer) */ (void)wd_start(priv->ft_txtimeout, FTMAC100_TXTIMEOUT, - ftmac100_txtimeout_expiry, 1, (uint32_t)priv); + ftmac100_txtimeout_expiry, 1, (wdparm_t)priv); -// irqrestore(flags); +//leave_critical_section(flags); return OK; } @@ -482,10 +481,10 @@ static void ftmac100_init(FAR struct ftmac100_driver_s *priv) rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN; rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE(RX_BUF_SIZE); rxdes[i].rxdes2 = (unsigned int)(kmem + i * RX_BUF_SIZE); - rxdes[i].rxdes3 = (unsigned int)(rxdes + i + 1); // next ring + rxdes[i].rxdes3 = (unsigned int)(rxdes + i + 1); /* Next ring */ } - rxdes[CONFIG_FTMAC100_RX_DESC - 1].rxdes3 = (unsigned int)rxdes; // next ring + rxdes[CONFIG_FTMAC100_RX_DESC - 1].rxdes3 = (unsigned int)rxdes; /* Next ring */ for (i = 0; i < CONFIG_FTMAC100_TX_DESC; i++) { @@ -495,11 +494,11 @@ static void ftmac100_init(FAR struct ftmac100_driver_s *priv) txdes[i].txdes1 = 0; txdes[i].txdes2 = 0; txdes[i].txdes3 = 0; -// txdes[i].txdes3 = (unsigned int)(txdes + i + 1); // next ring +// txdes[i].txdes3 = (unsigned int)(txdes + i + 1); /* Next ring */ } txdes[CONFIG_FTMAC100_TX_DESC - 1].txdes1 = FTMAC100_TXDES1_EDOTR; -// txdes[CONFIG_FTMAC100_TX_DESC - 1].txdes3 = (unsigned int)txdes; // next ring +//txdes[CONFIG_FTMAC100_TX_DESC - 1].txdes3 = (unsigned int)txdes; /* Next ring */ /* transmit ring */ @@ -513,7 +512,7 @@ static void ftmac100_init(FAR struct ftmac100_driver_s *priv) /* set RXINT_THR and TXINT_THR */ -// putreg32 (FTMAC100_ITC_RXINT_THR(1) | FTMAC100_ITC_TXINT_THR(1), &iobase->itc); +//putreg32 (FTMAC100_ITC_RXINT_THR(1) | FTMAC100_ITC_TXINT_THR(1), &iobase->itc); /* poll receive descriptor automatically */ @@ -526,8 +525,8 @@ static void ftmac100_init(FAR struct ftmac100_driver_s *priv) FTMAC100_DBLAC_RXFIFO_HTHR(6) | FTMAC100_DBLAC_RX_THR_EN, &iobase->dblac); -// putreg32 (getreg32(&iobase->fcr) | 0x1, &iobase->fcr); -// putreg32 (getreg32(&iobase->bpr) | 0x1, &iobase->bpr); +//putreg32 (getreg32(&iobase->fcr) | 0x1, &iobase->fcr); +//putreg32 (getreg32(&iobase->bpr) | 0x1, &iobase->bpr); #endif /* enable transmitter, receiver */ @@ -668,10 +667,6 @@ static void ftmac100_receive(FAR struct ftmac100_driver_s *priv) nvdbg ("RX buffer %d (%08x), %x received (%d)\n", priv->rx_pointer, data, len, (rxdes->rxdes0 & FTMAC100_RXDES0_LRS)); - /* Check for errors and update statistics */ - - /* Check if the packet is a valid size for the uIP buffer configuration */ - /* Copy the data data from the hardware to priv->ft_dev.d_buf. Set * amount of data in priv->ft_dev.d_len */ @@ -809,7 +804,7 @@ static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv) { FAR struct ftmac100_txdes_s *txdes; - /* Check for errors and update statistics */ + /* Check if a Tx was pending */ while (priv->tx_pending) { @@ -842,8 +837,18 @@ static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv) nvdbg("txpending=%d\n", priv->tx_pending); + /* Cancel the TX timeout */ + wd_cancel(priv->ft_txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to avoid + * certain race conditions where the polling sequence can be interrupted. + */ + + (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, + (wdparm_t)priv); + /* Then poll uIP for new XMIT data */ (void)devif_poll(&priv->ft_dev, ftmac100_txpoll); @@ -971,16 +976,16 @@ static void ftmac100_interrupt_work(FAR void *arg) { FAR struct ftmac100_driver_s *priv = (FAR struct ftmac100_driver_s *)arg; net_lock_t state; -// irqstate_t flags; +//irqstate_t flags; /* Process pending Ethernet interrupts */ state = net_lock(); -// flags = irqsave(); +//flags = enter_critical_section(); ftmac100_interrupt_process(priv); -// irqrestore(flags); +//leave_critical_section(flags); net_unlock(state); /* Re-enable Ethernet interrupts */ @@ -1019,7 +1024,7 @@ static int ftmac100_interrupt(int irq, FAR void *context) * condition here. */ - flags = irqsave(); + flags = enter_critical_section(); priv->status = getreg32 (&iobase->isr); @@ -1050,7 +1055,7 @@ static int ftmac100_interrupt(int irq, FAR void *context) work_queue(HPWORK, &priv->ft_work, ftmac100_interrupt_work, priv, 0); - irqrestore(flags); + leave_critical_section(flags); #else /* Process the interrupt now */ putreg32 (INT_MASK_ALL_DISABLED, &iobase->imr); @@ -1080,8 +1085,6 @@ static int ftmac100_interrupt(int irq, FAR void *context) static inline void ftmac100_txtimeout_process(FAR struct ftmac100_driver_s *priv) { - /* Increment statistics and dump debug info */ - /* Then reset the hardware */ nvdbg("TXTIMEOUT\n"); @@ -1197,11 +1200,12 @@ static inline void ftmac100_poll_process(FAR struct ftmac100_driver_s *priv) * we will missing TCP time state updates? */ - (void)devif_timer(&priv->ft_dev, ftmac100_txpoll, FTMAC100_POLLHSEC); + (void)devif_timer(&priv->ft_dev, ftmac100_txpoll); /* Setup the watchdog poll timer again */ - (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, priv); + (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, + (wdparm_t)priv); } /**************************************************************************** @@ -1274,7 +1278,8 @@ static void ftmac100_poll_expiry(int argc, uint32_t arg, ...) * cycle. */ - (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, arg); + (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, + 1, (wdparm_t)arg); } #else @@ -1335,7 +1340,8 @@ static int ftmac100_ifup(struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, (uint32_t)priv); + (void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1, + (wdparm_t)priv); /* Enable the Ethernet interrupt */ @@ -1368,7 +1374,7 @@ static int ftmac100_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); up_disable_irq(CONFIG_FTMAC100_IRQ); /* Cancel the TX poll timer and TX timeout timers */ @@ -1386,7 +1392,7 @@ static int ftmac100_ifdown(struct net_driver_s *dev) /* Mark the device "down" */ priv->ft_bifup = false; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -1495,12 +1501,12 @@ static int ftmac100_txavail(struct net_driver_s *dev) * level processing. */ - flags = irqsave(); + flags = enter_critical_section(); /* Perform the out-of-cycle poll now */ ftmac100_txavail_process(priv); - irqrestore(flags); + leave_critical_section(flags); #endif return OK; @@ -1536,8 +1542,7 @@ static int ftmac100_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) hash_value = crc32part(mac, 6, ~0L); - /* - * The HASH Table is a register array of 2 32-bit registers. + /* The HASH Table is a register array of 2 32-bit registers. * It is treated like an array of 64 bits. We want to set * bit BitArray[hash_value]. So we figure out what register * the bit is in, read it, OR in the new bit, then write @@ -1728,12 +1733,12 @@ int ftmac100_initialize(int intf) priv->ft_dev.d_addmac = ftmac100_addmac; /* Add multicast MAC address */ priv->ft_dev.d_rmmac = ftmac100_rmmac; /* Remove multicast MAC address */ #endif - priv->ft_dev.d_private = (void*)g_ftmac100; /* Used to recover private state from dev */ + priv->ft_dev.d_private = (FAR void *)g_ftmac100; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmisstions */ - priv->ft_txpoll = wd_create(); /* Create periodic poll timer */ - priv->ft_txtimeout = wd_create(); /* Create TX timeout timer */ + priv->ft_txpoll = wd_create(); /* Create periodic poll timer */ + priv->ft_txtimeout = wd_create(); /* Create TX timeout timer */ priv->iobase = CONFIG_FTMAC100_BASE; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..3b750b8051367b175db665b3368a8fb718b0ea16 --- /dev/null +++ b/drivers/net/loopback.c @@ -0,0 +1,581 @@ +/**************************************************************************** + * drivers/net/loopback.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_NETDEV_LOOPBACK) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_NET_NOINTS +# error CONFIG_NET_NOINTS must be selected +#endif + +#ifndef CONFIG_SCHED_HPWORK +# error High priority work queue support is required (CONFIG_SCHED_HPWORK) +#endif + +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define LO_WDDELAY (1*CLK_TCK) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define IPv4BUF ((FAR struct ipv4_hdr_s *)priv->lo_dev.d_buf) +#define IPv6BUF ((FAR struct ipv6_hdr_s *)priv->lo_dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The lo_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct lo_driver_s +{ + bool lo_bifup; /* true:ifup false:ifdown */ + bool lo_txdone; /* One RX packet was looped back */ + WDOG_ID lo_polldog; /* TX poll timer */ + struct work_s lo_work; /* For deferring work to the work queue */ + + /* This holds the information visible to uIP/NuttX */ + + struct net_driver_s lo_dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct lo_driver_s g_loopback; + +#ifdef CONFIG_NET_MULTIBUFFER +static uint8_t g_iobuffer[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE]; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Polling logic */ + +static int lo_txpoll(FAR struct net_driver_s *dev); +static void lo_poll_work(FAR void *arg); +static void lo_poll_expiry(int argc, wdparm_t arg, ...); + +/* NuttX callback functions */ + +static int lo_ifup(FAR struct net_driver_s *dev); +static int lo_ifdown(FAR struct net_driver_s *dev); +static void lo_txavail_work(FAR void *arg); +static int lo_txavail(FAR struct net_driver_s *dev); +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac); +#ifdef CONFIG_NET_IGMP +static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac); +#endif +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: lo_txpoll + * + * Description: + * Check if the network has any outgoing packets ready to send. This is + * a callback from devif_poll() or devif_timer(). devif_poll() will be + * called only during normal TX polling. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * the network is locked. + * + ****************************************************************************/ + +static int lo_txpoll(FAR struct net_driver_s *dev) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; + + /* Loop while there is data "sent", i.e., while d_len > 0. That should be + * the case upon entry here and while the processing of the IPv4/6 packet + * generates a new packet to be sent. Sending, of course, just means + * relaying back through the network for this driver. + */ + + while (priv->lo_dev.d_len > 0) + { + NETDEV_TXPACKETS(&priv->lo_dev); + NETDEV_RXPACKETS(&priv->lo_dev); + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->lo_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if ((IPv4BUF->vhl & IP_VERSION_MASK) == IPv4_VERSION) + { + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->lo_dev); + ipv4_input(&priv->lo_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION) + { + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->lo_dev); + ipv6_input(&priv->lo_dev); + } + else +#endif + { + ndbg("WARNING: Unrecognized packet type dropped: %02x\n", IPv4BUF->vhl); + NETDEV_RXDROPPED(&priv->lo_dev); + priv->lo_dev.d_len = 0; + } + + priv->lo_txdone = true; + NETDEV_TXDONE(&priv->lo_dev); + } + + return 0; +} + +/**************************************************************************** + * Function: lo_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked + * + ****************************************************************************/ + +static void lo_poll_work(FAR void *arg) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg; + net_lock_t state; + + /* Perform the poll */ + + state = net_lock(); + priv->lo_txdone = false; + (void)devif_timer(&priv->lo_dev, lo_txpoll); + + /* Was something received and looped back? */ + + while (priv->lo_txdone) + { + /* Yes, poll again for more TX data */ + + priv->lo_txdone = false; + (void)devif_poll(&priv->lo_dev, lo_txpoll); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry, 1, priv); + net_unlock(state); +} + +/**************************************************************************** + * Function: lo_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lo_poll_expiry(int argc, wdparm_t arg, ...) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg; + + /* Is our single work structure available? It may not be if there are + * pending interrupt actions. + */ + + if (work_available(&priv->lo_work)) + { + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(HPWORK, &priv->lo_work, lo_poll_work, priv, 0); + } + else + { + /* No.. Just re-start the watchdog poll timer, missing one polling + * cycle. + */ + + (void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry, 1, arg); + } +} + +/**************************************************************************** + * Function: lo_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lo_ifup(FAR struct net_driver_s *dev) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; + +#ifdef CONFIG_NET_IPv4 + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Set and activate a timer process */ + + (void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry, 1, (wdparm_t)priv); + + priv->lo_bifup = true; + return OK; +} + +/**************************************************************************** + * Function: lo_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lo_ifdown(FAR struct net_driver_s *dev) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->lo_polldog); + + /* Mark the device "down" */ + + priv->lo_bifup = false; + return OK; +} + +/**************************************************************************** + * Function: lo_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +static void lo_txavail_work(FAR void *arg) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg; + net_lock_t state; + + /* Ignore the notification if the interface is not yet up */ + + state = net_lock(); + if (priv->lo_bifup) + { + do + { + /* If so, then poll the network for new XMIT data */ + + priv->lo_txdone = false; + (void)devif_poll(&priv->lo_dev, lo_txpoll); + } + while (priv->lo_txdone); + } + + net_unlock(state); +} + +/**************************************************************************** + * Function: lo_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int lo_txavail(FAR struct net_driver_s *dev) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; + + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->lo_work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->lo_work, lo_txavail_work, priv, 0); + } + + return OK; +} + +/**************************************************************************** + * Function: lo_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + /* There is no multicast support in the loopback driver */ + + return OK; +} +#endif + +/**************************************************************************** + * Function: lo_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + /* There is no multicast support in the loopback driver */ + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: localhost_initialize + * + * Description: + * Initialize the Ethernet controller and driver + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int localhost_initialize(void) +{ + FAR struct lo_driver_s *priv; + + /* Get the interface structure associated with this interface number. */ + + priv = &g_loopback; + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct lo_driver_s)); + priv->lo_dev.d_ifup = lo_ifup; /* I/F up (new IP address) callback */ + priv->lo_dev.d_ifdown = lo_ifdown; /* I/F down callback */ + priv->lo_dev.d_txavail = lo_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->lo_dev.d_addmac = lo_addmac; /* Add multicast MAC address */ + priv->lo_dev.d_rmmac = lo_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NET_MULTIBUFFER + priv->lo_dev.d_buf = g_iobuffer; /* Attach the IO buffer */ +#endif + priv->lo_dev.d_private = (FAR void *)priv; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmissions */ + + priv->lo_polldog = wd_create(); /* Create periodic poll timer */ + + /* Register the loopabck device with the OS so that socket IOCTLs can b + * performed. + */ + + (void)netdev_register(&priv->lo_dev, NET_LL_LOOPBACK); + + /* Set the local loopback IP address */ + +#ifdef CONFIG_NET_IPv4 + net_ipv4addr_copy(priv->lo_dev.d_ipaddr, g_lo_ipv4addr); + net_ipv4addr_copy(priv->lo_dev.d_draddr, g_lo_ipv4addr); + net_ipv4addr_copy(priv->lo_dev.d_netmask, g_lo_ipv4mask); +#endif + +#ifdef CONFIG_NET_IPv6 + net_ipv6addr_copy(priv->lo_dev.d_ipv6addr, g_lo_ipv6addr); + net_ipv6addr_copy(priv->lo_dev.d_ipv6draddr, g_lo_ipv6addr); + net_ipv6addr_copy(priv->lo_dev.d_ipv6netmask, g_ipv6_alloneaddr); +#endif + + /* Put the network in the UP state */ + + priv->lo_dev.d_flags = IFF_UP; + return lo_ifup(&priv->lo_dev); +} + +#endif /* CONFIG_NET && CONFIG_NETDEV_LOOPBACK */ diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index e0bef1ee44fbe93913b1cf63b2b0c3e0e34abdd6..6194fbce34133db9cb1bfb464389ff615b9e94e5 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -86,7 +86,6 @@ /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define skeleton_WDDELAY (1*CLK_TCK) -#define skeleton_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -113,9 +112,9 @@ struct skel_driver_s struct work_s sk_work; /* For deferring work to the work queue */ #endif - /* This holds the information visible to uIP/NuttX */ + /* This holds the information visible to the NuttX network */ - struct net_driver_s sk_dev; /* Interface understood by uIP */ + struct net_driver_s sk_dev; /* Interface understood by the network */ }; /**************************************************************************** @@ -149,13 +148,13 @@ static inline void skel_txtimeout_process(FAR struct skel_driver_s *priv); #ifdef CONFIG_NET_NOINTS static void skel_txtimeout_work(FAR void *arg); #endif -static void skel_txtimeout_expiry(int argc, uint32_t arg, ...); +static void skel_txtimeout_expiry(int argc, wdparm_t arg, ...); static inline void skel_poll_process(FAR struct skel_driver_s *priv); #ifdef CONFIG_NET_NOINTS static void skel_poll_work(FAR void *arg); #endif -static void skel_poll_expiry(int argc, uint32_t arg, ...); +static void skel_poll_expiry(int argc, wdparm_t arg, ...); /* NuttX callback functions */ @@ -195,8 +194,7 @@ static void skel_ipv6multicast(FAR struct skel_driver_s *priv); * * Assumptions: * May or may not be called from an interrupt handler. In either case, - * global interrupts are disabled, either explicitly or indirectly through - * interrupt handling logic. + * the network is locked. * ****************************************************************************/ @@ -209,13 +207,16 @@ static int skel_transmit(FAR struct skel_driver_s *priv) /* Increment statistics */ + NETDEV_TXPACKETS(priv->sk_dev); + /* Send the packet: address=priv->sk_dev.d_buf, length=priv->sk_dev.d_len */ /* Enable Tx interrupts */ /* Setup the TX timeout watchdog (perhaps restarting the timer) */ - (void)wd_start(priv->sk_txtimeout, skeleton_TXTIMEOUT, skel_txtimeout_expiry, 1, (uint32_t)priv); + (void)wd_start(priv->sk_txtimeout, skeleton_TXTIMEOUT, + skel_txtimeout_expiry, 1, (wdparm_t)priv); return OK; } @@ -223,8 +224,9 @@ static int skel_transmit(FAR struct skel_driver_s *priv) * Function: skel_txpoll * * Description: - * The transmitter is available, check if uIP has any outgoing packets ready - * to send. This is a callback from devif_poll(). devif_poll() may be called: + * The transmitter is available, check if the network has any outgoing + * packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: * * 1. When the preceding TX packet send is complete, * 2. When the preceding TX packet send timesout and the interface is reset @@ -238,8 +240,7 @@ static int skel_transmit(FAR struct skel_driver_s *priv) * * Assumptions: * May or may not be called from an interrupt handler. In either case, - * global interrupts are disabled, either explicitly or indirectly through - * interrupt handling logic. + * the network is locked. * ****************************************************************************/ @@ -304,7 +305,7 @@ static int skel_txpoll(FAR struct net_driver_s *dev) * None * * Assumptions: - * Global interrupts are disabled by interrupt handling logic. + * The network is locked. * ****************************************************************************/ @@ -314,7 +315,9 @@ static void skel_receive(FAR struct skel_driver_s *priv) { /* Check for errors and update statistics */ - /* Check if the packet is a valid size for the uIP buffer configuration */ + /* Check if the packet is a valid size for the network buffer + * configuration. + */ /* Copy the data data from the hardware to priv->sk_dev.d_buf. Set * amount of data in priv->sk_dev.d_len @@ -332,6 +335,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->sk_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -372,6 +376,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->sk_dev); /* Give the IPv6 packet to the network layer */ @@ -409,6 +414,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->sk_dev); + NETDEV_RXARP(&priv->sk_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. @@ -420,6 +426,10 @@ static void skel_receive(FAR struct skel_driver_s *priv) } } #endif + else + { + NETDEV_RXDROPPED(&priv->sk_dev); + } } while (); /* While there are more packets to be processed */ } @@ -437,7 +447,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) * None * * Assumptions: - * Global interrupts are disabled by the watchdog logic. + * The network is locked. * ****************************************************************************/ @@ -445,13 +455,28 @@ static void skel_txdone(FAR struct skel_driver_s *priv) { /* Check for errors and update statistics */ - /* If no further xmits are pending, then cancel the TX timeout and + NETDEV_TXDONE(priv->sk_dev); + + /* Check if there are pending transmissions */ + + /* If no further transmissions are pending, then cancel the TX timeout and * disable further Tx interrupts. */ wd_cancel(priv->sk_txtimeout); - /* Then poll uIP for new XMIT data */ + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would restart it). This is necessary to + * avoid certain race conditions where the polling sequence can be + * interrupted. + */ + + (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1, + (wdparm_t)priv); + + /* And disable further TX interrupts. */ + + /* In any event, poll the network for new TX data */ (void)devif_poll(&priv->sk_dev, skel_txpoll); } @@ -470,7 +495,7 @@ static void skel_txdone(FAR struct skel_driver_s *priv) * None * * Assumptions: - * Ethernet interrupts are disabled + * The network is locked. * ****************************************************************************/ @@ -505,7 +530,7 @@ static inline void skel_interrupt_process(FAR struct skel_driver_s *priv) * OK on success * * Assumptions: - * Ethernet interrupts are disabled + * The network is locked. * ****************************************************************************/ @@ -605,9 +630,11 @@ static inline void skel_txtimeout_process(FAR struct skel_driver_s *priv) { /* Increment statistics and dump debug info */ + NETDEV_TXTIMEOUTS(priv->sk_dev); + /* Then reset the hardware */ - /* Then poll uIP for new XMIT data */ + /* Then poll the network for new XMIT data */ (void)devif_poll(&priv->sk_dev, skel_txpoll); } @@ -625,7 +652,7 @@ static inline void skel_txtimeout_process(FAR struct skel_driver_s *priv) * OK on success * * Assumptions: - * Ethernet interrupts are disabled + * The network is locked. * ****************************************************************************/ @@ -662,7 +689,7 @@ static void skel_txtimeout_work(FAR void *arg) * ****************************************************************************/ -static void skel_txtimeout_expiry(int argc, uint32_t arg, ...) +static void skel_txtimeout_expiry(int argc, wdparm_t arg, ...) { FAR struct skel_driver_s *priv = (FAR struct skel_driver_s *)arg; @@ -713,16 +740,17 @@ static inline void skel_poll_process(FAR struct skel_driver_s *priv) * the TX poll if he are unable to accept another packet for transmission. */ - /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. - * might be bug here. Does this mean if there is a transmit in progress, - * we will missing TCP time state updates? + /* If so, update TCP timing states and poll the network for new XMIT data. + * Hmmm.. might be bug here. Does this mean if there is a transmit in + * progress, we will missing TCP time state updates? */ - (void)devif_timer(&priv->sk_dev, skel_txpoll, skeleton_POLLHSEC); + (void)devif_timer(&priv->sk_dev, skel_txpoll); /* Setup the watchdog poll timer again */ - (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1, priv); + (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1, + (wdparm_t)priv); } /**************************************************************************** @@ -738,7 +766,7 @@ static inline void skel_poll_process(FAR struct skel_driver_s *priv) * OK on success * * Assumptions: - * Ethernet interrupts are disabled + * The network is locked. * ****************************************************************************/ @@ -774,7 +802,7 @@ static void skel_poll_work(FAR void *arg) * ****************************************************************************/ -static void skel_poll_expiry(int argc, uint32_t arg, ...) +static void skel_poll_expiry(int argc, wdparm_t arg, ...) { FAR struct skel_driver_s *priv = (FAR struct skel_driver_s *)arg; @@ -850,7 +878,8 @@ static int skel_ifup(FAR struct net_driver_s *dev) /* Set and activate a timer process */ - (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1, (uint32_t)priv); + (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1, + (wdparm_t)priv); /* Enable the Ethernet interrupt */ @@ -882,7 +911,7 @@ static int skel_ifdown(FAR struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); up_disable_irq(CONFIG_skeleton_IRQ); /* Cancel the TX poll timer and TX timeout timers */ @@ -898,7 +927,7 @@ static int skel_ifdown(FAR struct net_driver_s *dev) /* Mark the device "down" */ priv->sk_bifup = false; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -927,7 +956,7 @@ static inline void skel_txavail_process(FAR struct skel_driver_s *priv) { /* Check if there is room in the hardware to hold another outgoing packet. */ - /* If so, then poll uIP for new XMIT data */ + /* If so, then poll the network for new XMIT data */ (void)devif_poll(&priv->sk_dev, skel_txpoll); } @@ -1007,12 +1036,12 @@ static int skel_txavail(FAR struct net_driver_s *dev) * level processing. */ - flags = irqsave(); + flags = enter_critical_section(); /* Perform the out-of-cycle poll now */ skel_txavail_process(priv); - irqrestore(flags); + leave_critical_section(flags); #endif return OK; @@ -1200,12 +1229,12 @@ int skel_initialize(int intf) priv->sk_dev.d_addmac = skel_addmac; /* Add multicast MAC address */ priv->sk_dev.d_rmmac = skel_rmmac; /* Remove multicast MAC address */ #endif - priv->sk_dev.d_private = (void*)g_skel; /* Used to recover private state from dev */ + priv->sk_dev.d_private = (FAR void *)g_skel; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmisstions */ - priv->sk_txpoll = wd_create(); /* Create periodic poll timer */ - priv->sk_txtimeout = wd_create(); /* Create TX timeout timer */ + priv->sk_txpoll = wd_create(); /* Create periodic poll timer */ + priv->sk_txtimeout = wd_create(); /* Create TX timeout timer */ /* Put the interface in the down state. This usually amounts to resetting * the device and/or calling skel_ifdown(). diff --git a/drivers/net/slip.c b/drivers/net/slip.c index bbabc1527e86c4bd8ddacff79030e65352f015c4..c02ebb0e935fcbae22fe69bfcd9cd67803c1f954 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -130,28 +130,10 @@ #define SLIP_WDDELAY (1*1000000) #define SLIP_POLLHSEC (1*2) -/* Statistics helper */ - -#ifdef CONFIG_NET_STATISTICS -# define SLIP_STAT(p,f) (p->stats.f)++ -#else -# define SLIP_STAT(p,f) -#endif - /**************************************************************************** * Private Types ****************************************************************************/ -/* Driver statistics */ - -#ifdef CONFIG_NET_STATISTICS -struct slip_statistics_s -{ - uint32_t transmitted; /* Number of packets transmitted */ - uint32_t received /* Number of packets received */ -}; -#endif - /* The slip_driver_s encapsulates all state information for a single hardware * interface */ @@ -166,12 +148,6 @@ struct slip_driver_s pid_t txpid; /* Transmitter thread ID */ sem_t waitsem; /* Mutually exclusive access to uIP */ - /* Driver statistics */ - -#ifdef CONFIG_NET_STATISTICS - struct slip_statistics_s stats; -#endif - /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ @@ -183,9 +159,9 @@ struct slip_driver_s * Private Data ****************************************************************************/ - /* We really should get rid of CONFIG_NET_SLIP_NINTERFACES and, instead, - * kmm_malloc() new interface instances as needed. - */ +/* We really should get rid of CONFIG_NET_SLIP_NINTERFACES and, instead, + * kmm_malloc() new interface instances as needed. + */ static struct slip_driver_s g_slip[CONFIG_NET_SLIP_NINTERFACES]; @@ -312,7 +288,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) /* Increment statistics */ nvdbg("Sending packet size %d\n", priv->dev.d_len); - SLIP_STAT(priv, transmitted); + NETDEV_TXPACKETS(&priv->dev); /* Send an initial END character to flush out any data that may have * accumulated in the receiver due to line noise @@ -393,6 +369,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) /* And send the END token */ slip_putc(priv, SLIP_END); + NETDEV_TXDONE(&priv->dev); priv->txnodelay = true; return OK; } @@ -457,8 +434,8 @@ static void slip_txtask(int argc, FAR char *argv[]) FAR struct slip_driver_s *priv; unsigned int index = *(argv[1]) - '0'; net_lock_t flags; - unsigned int msec_start; - unsigned int msec_now; + systime_t msec_start; + systime_t msec_now; unsigned int hsec; ndbg("index: %d\n", index); @@ -474,7 +451,7 @@ static void slip_txtask(int argc, FAR char *argv[]) /* Loop forever */ msec_start = clock_systimer() * MSEC_PER_TICK; - for (;;) + for (; ; ) { /* Wait for the timeout to expire (or until we are signaled by by */ @@ -513,7 +490,7 @@ static void slip_txtask(int argc, FAR char *argv[]) { /* Yes, perform the timer poll */ - (void)devif_timer(&priv->dev, slip_txpoll, hsec); + (void)devif_timer(&priv->dev, slip_txpoll); msec_start += hsec * (MSEC_PER_SEC / 2); } else @@ -579,7 +556,7 @@ static inline void slip_receive(FAR struct slip_driver_s *priv) */ nvdbg("Receiving packet\n"); - for (;;) + for (; ; ) { /* Get the next character in the stream. */ @@ -696,7 +673,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) /* Loop forever */ - for (;;) + for (; ; ) { /* Wait for the next character to be available on the input stream. */ @@ -736,7 +713,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) */ slip_receive(priv); - SLIP_STAT(priv, received); + NETDEV_RXPACKETS(&priv->dev); /* All packets are assumed to be IP packets (we don't have a choice.. * there is no Ethernet header containing the EtherType). So pass the @@ -746,6 +723,8 @@ static int slip_rxtask(int argc, FAR char *argv[]) if (priv->rxlen >= IPv4_HDRLEN) { + NETDEV_RXIPV4(&priv->dev); + /* Handle the IP input. Get exclusive access to uIP. */ slip_semtake(priv); @@ -770,7 +749,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) } else { - SLIP_STAT(priv, rxsmallpacket); + NETDEV_RXERRORS(&priv->dev); } } @@ -802,7 +781,7 @@ static int slip_ifup(FAR struct net_driver_s *dev) ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Mark the interface up */ diff --git a/drivers/net/telnet.c b/drivers/net/telnet.c new file mode 100644 index 0000000000000000000000000000000000000000..505a01cb942ea75c81f52835017cb9e756f3b5a9 --- /dev/null +++ b/drivers/net/telnet.c @@ -0,0 +1,956 @@ +/**************************************************************************** + * drivers/net/telnet.c + * + * Copyright (C) 2007, 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This is a leverage of similar logic from uIP which has a compatible BSD + * license: + * + * Author: Adam Dunkels + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * 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 of the Institute, 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 INSTITUTE 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 INSTITUTE 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_NETDEV_TELNET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_TELNET_RXBUFFER_SIZE +# define CONFIG_TELNET_RXBUFFER_SIZE 256 +#endif + +#ifndef CONFIG_TELNET_TXBUFFER_SIZE +# define CONFIG_TELNET_TXBUFFER_SIZE 256 +#endif + +/* Telnet protocol stuff ****************************************************/ + +#define ISO_nl 0x0a +#define ISO_cr 0x0d + +#define TELNET_IAC 255 +#define TELNET_WILL 251 +#define TELNET_WONT 252 +#define TELNET_DO 253 +#define TELNET_DONT 254 + +/* Device stuff *************************************************************/ + +#define TELNETD_DEVFMT "/dev/telnet%d" + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* The state of the telnet parser */ + +enum telnet_state_e +{ + STATE_NORMAL = 0, + STATE_IAC, + STATE_WILL, + STATE_WONT, + STATE_DO, + STATE_DONT +}; + +/* This structure describes the internal state of the driver */ + +struct telnet_dev_s +{ + sem_t td_exclsem; /* Enforces mutually exclusive access */ + uint8_t td_state; /* (See telnet_state_e) */ + uint8_t td_pending; /* Number of valid, pending bytes in the rxbuffer */ + uint8_t td_offset; /* Offset to the valid, pending bytes in the rxbuffer */ + uint8_t td_crefs; /* The number of open references to the session */ + int td_minor; /* Minor device number */ + FAR struct socket td_psock; /* A clone of the internal socket structure */ + char td_rxbuffer[CONFIG_TELNET_RXBUFFER_SIZE]; + char td_txbuffer[CONFIG_TELNET_TXBUFFER_SIZE]; +}; + +/* This structure contains global information visable to all telnet driver + * instances. + */ + +struct telnet_common_s +{ + sem_t tc_exclsem; /* Enforces exclusive access to 'minor' */ + uint16_t tc_minor; /* The next minor number to use */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Support functions */ + +#ifdef CONFIG_TELNET_DUMPBUFFER +static inline void telnet_dumpbuffer(FAR const char *msg, + FAR const char *buffer, unsigned int nbytes); +#else +# define telnet_dumpbuffer(msg,buffer,nbytes) +#endif +static void telnet_getchar(FAR struct telnet_dev_s *priv, uint8_t ch, + FAR char *dest, int *nread); +static ssize_t telnet_receive(FAR struct telnet_dev_s *priv, + FAR const char *src, size_t srclen, FAR char *dest, + size_t destlen); +static bool telnet_putchar(FAR struct telnet_dev_s *priv, uint8_t ch, + int *nwritten); +static void telnet_sendopt(FAR struct telnet_dev_s *priv, uint8_t option, + uint8_t value); + +/* Telnet character driver methods */ + +static int telnet_open(FAR struct file *filep); +static int telnet_close(FAR struct file *filep); +static ssize_t telnet_read(FAR struct file *, FAR char *, size_t); +static ssize_t telnet_write(FAR struct file *, FAR const char *, size_t); + +/* Telnet session creation */ + +static int telnet_session(FAR struct telnet_session_s *session); + +/* Telnet factory driver methods */ + +static ssize_t factory_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t factory_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int common_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_telnet_fops = +{ + telnet_open, /* open */ + telnet_close, /* close */ + telnet_read, /* read */ + telnet_write, /* write */ + 0, /* seek */ + common_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +static const struct file_operations g_factory_fops = +{ + 0, /* open */ + 0, /* close */ + factory_read, /* read */ + factory_write, /* write */ + 0, /* seek */ + common_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +/* Global information shared amongst telnet driver instanaces. */ + +static struct telnet_common_s g_telnet_common = +{ + SEM_INITIALIZER(1), + 0 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: telnet_dumpbuffer + * + * Description: + * Dump a buffer of data (debug only) + * + ****************************************************************************/ + +#ifdef CONFIG_TELNET_DUMPBUFFER +static inline void telnet_dumpbuffer(FAR const char *msg, + FAR const char *buffer, + unsigned int nbytes) +{ + /* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_NET have to be + * defined or the following does nothing. + */ + + nvdbgdumpbuffer(msg, (FAR const uint8_t*)buffer, nbytes); +} +#endif + +/**************************************************************************** + * Name: telnet_getchar + * + * Description: + * Get another character for the user received buffer from the RX buffer + * + ****************************************************************************/ + +static void telnet_getchar(FAR struct telnet_dev_s *priv, uint8_t ch, + FAR char *dest, int *nread) +{ + register int index; + + /* Ignore carriage returns */ + + if (ch != ISO_cr) + { + /* Add all other characters to the destination buffer */ + + index = *nread; + dest[index++] = ch; + *nread = index; + } +} + +/**************************************************************************** + * Name: telnet_receive + * + * Description: + * Process a received Telnet buffer + * + ****************************************************************************/ + +static ssize_t telnet_receive(FAR struct telnet_dev_s *priv, FAR const char *src, + size_t srclen, FAR char *dest, size_t destlen) +{ + int nread; + uint8_t ch; + + nllvdbg("srclen: %d destlen: %d\n", srclen, destlen); + + for (nread = 0; srclen > 0 && nread < destlen; srclen--) + { + ch = *src++; + nllvdbg("ch=%02x state=%d\n", ch, priv->td_state); + + switch (priv->td_state) + { + case STATE_IAC: + if (ch == TELNET_IAC) + { + telnet_getchar(priv, ch, dest, &nread); + priv->td_state = STATE_NORMAL; + } + else + { + switch (ch) + { + case TELNET_WILL: + priv->td_state = STATE_WILL; + break; + + case TELNET_WONT: + priv->td_state = STATE_WONT; + break; + + case TELNET_DO: + priv->td_state = STATE_DO; + break; + + case TELNET_DONT: + priv->td_state = STATE_DONT; + break; + + default: + priv->td_state = STATE_NORMAL; + break; + } + } + break; + + case STATE_WILL: + /* Reply with a DONT */ + + telnet_sendopt(priv, TELNET_DONT, ch); + priv->td_state = STATE_NORMAL; + break; + + case STATE_WONT: + /* Reply with a DONT */ + + telnet_sendopt(priv, TELNET_DONT, ch); + priv->td_state = STATE_NORMAL; + break; + + case STATE_DO: + /* Reply with a WONT */ + + telnet_sendopt(priv, TELNET_WONT, ch); + priv->td_state = STATE_NORMAL; + break; + + case STATE_DONT: + /* Reply with a WONT */ + + telnet_sendopt(priv, TELNET_WONT, ch); + priv->td_state = STATE_NORMAL; + break; + + case STATE_NORMAL: + if (ch == TELNET_IAC) + { + priv->td_state = STATE_IAC; + } + else + { + telnet_getchar(priv, ch, dest, &nread); + } + break; + } + } + + /* We get here if (1) all of the received bytes have been processed, or + * (2) if the user's buffer has become full. + */ + + if (srclen > 0) + { + /* Remember where we left off. These bytes will be returned the next + * time that telnet_read() is called. + */ + + priv->td_pending = srclen; + priv->td_offset = (src - priv->td_rxbuffer); + } + else + { + /* All of the received bytes were consumed */ + + priv->td_pending = 0; + priv->td_offset = 0; + } + + return nread; +} + +/**************************************************************************** + * Name: telnet_putchar + * + * Description: + * Put another character from the user buffer to the TX buffer. + * + ****************************************************************************/ + +static bool telnet_putchar(FAR struct telnet_dev_s *priv, uint8_t ch, + int *nread) +{ + register int index; + bool ret = false; + + /* Ignore carriage returns (we will put these in automatically as necesary) */ + + if (ch != ISO_cr) + { + /* Add all other characters to the destination buffer */ + + index = *nread; + priv->td_txbuffer[index++] = ch; + + /* Check for line feeds */ + + if (ch == ISO_nl) + { + /* Now add the carriage return */ + + priv->td_txbuffer[index++] = ISO_cr; + priv->td_txbuffer[index++] = '\0'; + + /* End of line */ + + ret = true; + } + + *nread = index; + } + + return ret; +} + +/**************************************************************************** + * Name: telnet_sendopt + * + * Description: + * Send the telnet option bytes + * + ****************************************************************************/ + +static void telnet_sendopt(FAR struct telnet_dev_s *priv, uint8_t option, + uint8_t value) +{ + uint8_t optbuf[4]; + optbuf[0] = TELNET_IAC; + optbuf[1] = option; + optbuf[2] = value; + optbuf[3] = 0; + + telnet_dumpbuffer("Send optbuf", optbuf, 4); + if (psock_send(&priv->td_psock, optbuf, 4, 0) < 0) + { + nlldbg("Failed to send TELNET_IAC\n"); + } +} + +/**************************************************************************** + * Name: telnet_open + ****************************************************************************/ + +static int telnet_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct telnet_dev_s *priv = inode->i_private; + int tmp; + int ret; + + nllvdbg("td_crefs: %d\n", priv->td_crefs); + + /* O_NONBLOCK is not supported */ + + if (filep->f_oflags & O_NONBLOCK) + { + ret = -ENOSYS; + goto errout; + } + + /* Get exclusive access to the device structures */ + + ret = sem_wait(&priv->td_exclsem); + if (ret < 0) + { + ret = -errno; + goto errout; + } + + /* Increment the count of references to the device. If this the first + * time that the driver has been opened for this device, then initialize + * the device. + */ + + tmp = priv->td_crefs + 1; + if (tmp > 255) + { + /* More than 255 opens; uint8_t would overflow to zero */ + + ret = -EMFILE; + goto errout_with_sem; + } + + /* Save the new open count on success */ + + priv->td_crefs = tmp; + ret = OK; + +errout_with_sem: + sem_post(&priv->td_exclsem); + +errout: + return ret; +} + +/**************************************************************************** + * Name: telnet_close + ****************************************************************************/ + +static int telnet_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct telnet_dev_s *priv = inode->i_private; + FAR char *devpath; + int ret; + + nllvdbg("td_crefs: %d\n", priv->td_crefs); + + /* Get exclusive access to the device structures */ + + ret = sem_wait(&priv->td_exclsem); + if (ret < 0) + { + ret = -errno; + goto errout; + } + + /* Decrement the references to the driver. If the reference count will + * decrement to 0, then uninitialize the driver. + */ + + if (priv->td_crefs > 1) + { + /* Just decrement the reference count and release the semaphore */ + + priv->td_crefs--; + sem_post(&priv->td_exclsem); + } + else + { + /* Re-create the path to the driver. */ + + sched_lock(); + ret = asprintf(&devpath, TELNETD_DEVFMT, priv->td_minor); + if (ret < 0) + { + nlldbg("ERROR: Failed to allocate the driver path\n"); + } + else + { + /* Un-register the character driver */ + + ret = unregister_driver(devpath); + if (ret < 0) + { + /* NOTE: a return value of -EBUSY is not an error, it simply + * means that the Telnet driver is busy now and cannot be + * registered now because there are other sessions using the + * connection. The driver will be properly unregistered when + * the final session terminates. + */ + + if (ret != -EBUSY) + { + nlldbg("Failed to unregister the driver %s: %d\n", + devpath, ret); + } + } + + free(devpath); + } + + /* Close the socket */ + + psock_close(&priv->td_psock); + + /* Release the driver memory. What if there are threads waiting on + * td_exclsem? They will never be awakened! How could this happen? + * crefs == 1 so there are no other open references to the driver. + * But this could have if someone were trying to re-open the driver + * after every other thread has closed it. That really should not + * happen in the intended usage model. + */ + + DEBUGASSERT(priv->td_exclsem.semcount == 0); + sem_destroy(&priv->td_exclsem); + free(priv); + sched_unlock(); + } + + ret = OK; + +errout: + return ret; +} + +/**************************************************************************** + * Name: telnet_read + ****************************************************************************/ + +static ssize_t telnet_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct telnet_dev_s *priv = inode->i_private; + ssize_t ret; + + nllvdbg("len: %d\n", len); + + /* First, handle the case where there are still valid bytes left in the + * I/O buffer from the last time that read was called. NOTE: Much of + * what we read may be protocol stuff and may not correspond to user + * data. Hence we need the loop and we need may need to call psock_recv() + * multiple times in order to get data that the client is interested in. + */ + + do + { + if (priv->td_pending > 0) + { + /* Process the buffered telnet data */ + + FAR const char *src = &priv->td_rxbuffer[priv->td_offset]; + ret = telnet_receive(priv, src, priv->td_pending, buffer, len); + } + + /* Read a buffer of data from the telnet client */ + + else + { + ret = psock_recv(&priv->td_psock, priv->td_rxbuffer, + CONFIG_TELNET_RXBUFFER_SIZE, 0); + + /* Did we receive anything? */ + + if (ret > 0) + { + /* Yes.. Process the newly received telnet data */ + + telnet_dumpbuffer("Received buffer", priv->td_rxbuffer, ret); + ret = telnet_receive(priv, priv->td_rxbuffer, ret, buffer, len); + } + + /* Otherwise the peer closed the connection (ret == 0) or an error + * occurred (ret < 0). + */ + + else + { + break; + } + } + } + while (ret == 0); + + /* Return: + * + * ret > 0: The number of characters copied into the user buffer by + * telnet_receive(). + * ret <= 0: Loss of connection or error events reported by recv(). + */ + + return ret; +} + +/**************************************************************************** + * Name: telnet_write + ****************************************************************************/ + +static ssize_t telnet_write(FAR struct file *filep, FAR const char *buffer, size_t len) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct telnet_dev_s *priv = inode->i_private; + FAR const char *src = buffer; + ssize_t nsent; + ssize_t ret; + int ncopied; + char ch; + bool eol; + + nllvdbg("len: %d\n", len); + + /* Process each character from the user buffer */ + + for (nsent = 0, ncopied = 0; nsent < len; nsent++) + { + /* Get the next character from the user buffer */ + + ch = *src++; + + /* Add the character to the TX buffer */ + + eol = telnet_putchar(priv, ch, &ncopied); + + /* Was that the end of a line? Or is the buffer too full to hold the + * next largest character sequence ("\r\n\0")? + */ + + if (eol || ncopied > CONFIG_TELNET_TXBUFFER_SIZE-3) + { + /* Yes... send the data now */ + + ret = psock_send(&priv->td_psock, priv->td_txbuffer, ncopied, 0); + if (ret < 0) + { + nlldbg("psock_send failed '%s': %d\n", priv->td_txbuffer, ret); + return ret; + } + + /* Reset the index to the beginning of the TX buffer. */ + + ncopied = 0; + } + } + + /* Send anything remaining in the TX buffer */ + + if (ncopied > 0) + { + ret = psock_send(&priv->td_psock, priv->td_txbuffer, ncopied, 0); + if (ret < 0) + { + nlldbg("psock_send failed '%s': %d\n", priv->td_txbuffer, ret); + return ret; + } + } + + /* Notice that we don't actually return the number of bytes sent, but + * rather, the number of bytes that the caller asked us to send. We may + * have sent more bytes (because of CR-LF expansion and because of NULL + * termination). But it confuses some logic if you report that you sent + * more than you were requested to. + */ + + return len; +} + +/**************************************************************************** + * Name: telnet_session + * + * Description: + * Create a character driver to "wrap" the telnet session. This function + * will select and return a unique path for the new telnet device. + * + * Parameters: + * session - On input, contains the socket descriptor that represents the + * new telnet connection. On output, it holds the path to the new Telnet driver. + * + * Return: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int telnet_session(FAR struct telnet_session_s *session) +{ + FAR struct telnet_dev_s *priv; + FAR struct socket *psock; + struct stat statbuf; + uint16_t start; + int ret; + + /* Allocate instance data for this driver */ + + priv = (FAR struct telnet_dev_s*)malloc(sizeof(struct telnet_dev_s)); + if (!priv) + { + nlldbg("Failed to allocate the driver data structure\n"); + return -ENOMEM; + } + + /* Initialize the allocated driver instance */ + + sem_init(&priv->td_exclsem, 0, 1); + + priv->td_state = STATE_NORMAL; + priv->td_crefs = 0; + priv->td_pending = 0; + priv->td_offset = 0; + + /* Clone the internal socket structure. We do this so that it will be + * independent of threads and of socket descriptors (the original socket + * instance resided in the daemon's task group`). + */ + + psock = sockfd_socket(session->ts_sd); + if (!psock) + { + nlldbg("Failed to convert sd=%d to a socket structure\n", session->ts_sd); + ret = -EINVAL; + goto errout_with_dev; + } + + ret = net_clone(psock, &priv->td_psock); + if (ret < 0) + { + nlldbg("net_clone failed: %d\n", ret); + goto errout_with_dev; + } + + /* Allocate a unique minor device number of the telnet drvier. + * Get exclusive access to the minor counter. + */ + + do + { + ret = sem_wait(&g_telnet_common.tc_exclsem); + if (ret < 0 && errno != -EINTR) + { + goto errout_with_clone; + } + } + while (ret < 0); + + /* Loop until the device name is verified to be unique. */ + + start = g_telnet_common.tc_minor; + do + { + /* Get the next candiate minor number */ + + priv->td_minor = g_telnet_common.tc_minor; + g_telnet_common.tc_minor++; + + snprintf(session->ts_devpath, TELNET_DEVPATH_MAX, TELNETD_DEVFMT, + priv->td_minor); + + ret = stat(session->ts_devpath, &statbuf); + DEBUGASSERT(ret >= 0 || errno == ENOENT); + } + while (ret >= 0 && start != g_telnet_common.tc_minor); + + if (ret >= 0) + { + nlldbg("ERROR: Too many sessions\n"); + ret = -ENFILE; + goto errout_with_semaphore; + } + + /* Register the driver */ + + ret = register_driver(session->ts_devpath, &g_telnet_fops, 0666, priv); + if (ret < 0) + { + nlldbg("ERROR: Failed to register the driver %s: %d\n", + session->ts_devpath, ret); + goto errout_with_semaphore; + } + + /* Close the original psoock (keeping the clone) */ + + psock_close(psock); + + /* Return the path to the new telnet driver */ + + sem_post(&g_telnet_common.tc_exclsem); + return OK; + +errout_with_semaphore: + sem_post(&g_telnet_common.tc_exclsem); + +errout_with_clone: + psock_close(&priv->td_psock); + +errout_with_dev: + free(priv); + return ret; +} + +/**************************************************************************** + * Name: factory_read + ****************************************************************************/ + +static ssize_t factory_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + return 0; /* Return EOF */ +} + +/**************************************************************************** + * Name: factory_write + ****************************************************************************/ + +static ssize_t factory_write(FAR struct file *filep, FAR const char *buffer, + size_t len) +{ + return len; /* Say that everything was written */ +} + +/**************************************************************************** + * Name: common_ioctl + ****************************************************************************/ + +static int common_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + int ret; + + switch (cmd) + { + /* Command: SIOCTELNET + * Description: Create a Telnet sessions. + * Argument: A pointer to a write-able instance of struct + * telnet_session_s. + * Dependencies: CONFIG_NETDEV_TELNET + */ + + case SIOCTELNET: + { + FAR struct telnet_session_s *session = + (FAR struct telnet_session_s *)((uintptr_t)arg); + + if (session == NULL) + { + ret = -EINVAL; + } + else + { + ret = telnet_session(session); + } + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: telnet_initialize + * + * Description: + * Create the Telnet factory at /dev/telnet. + * + * Parameters: + * None + * + * Return: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int telnet_initialize(void) +{ + return register_driver("/dev/telnet", &g_factory_fops, 0666, NULL); +} + +#endif /* CONFIG_NETDEV_TELNET */ diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 63470dfad0976d654cde858e6cbe5763b84780e5..1221b56ad890cd80f6b11229726ee59d649462d9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -96,7 +96,6 @@ */ #define TUN_WDDELAY (1*CLK_TCK) -#define TUN_POLLHSEC (1*2) /**************************************************************************** * Private Types @@ -182,7 +181,7 @@ static void tun_ipv6multicast(FAR struct tun_device_s *priv); #endif static int tun_dev_init(FAR struct tun_device_s *priv, - FAR struct file *filep, FAR const char* devfmt); + FAR struct file *filep, FAR const char *devfmt); static int tun_dev_uninit(FAR struct tun_device_s *priv); /* File interface */ @@ -296,7 +295,6 @@ static void tun_pollnotify(FAR struct tun_device_s *priv, pollevent_t eventset) if (eventset != 0) { fds->revents |= eventset; - //fvdbg("Report events: %02x\n", fds->revents); sem_post(fds->sem); } } @@ -326,6 +324,8 @@ static void tun_pollnotify(FAR struct tun_device_s *priv, pollevent_t eventset) static int tun_transmit(FAR struct tun_device_s *priv) { + NETDEV_TXPACKETS(&priv->dev); + /* Verify that the hardware is ready to send another packet. If we get * here, then we are committed to sending a packet; Higher level logic * must have assured that there is no transmission in progress. @@ -378,6 +378,7 @@ static int tun_txpoll(struct net_driver_s *dev) { /* Send the packet */ + priv->read_d_len = priv->dev.d_len; tun_transmit(priv); return 1; @@ -413,6 +414,8 @@ static void tun_receive(FAR struct tun_device_s *priv) * data in priv->dev.d_len */ + NETDEV_RXPACKETS(&priv->dev); + #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ @@ -421,68 +424,54 @@ static void tun_receive(FAR struct tun_device_s *priv) /* We only accept IP packets of the configured type and ARP packets */ -#ifdef CONFIG_NET_IPv4 - { - nllvdbg("IPv4 frame\n"); +#if defined(CONFIG_NET_IPv4) + nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); - /* Give the IPv4 packet to the network layer */ + /* Give the IPv4 packet to the network layer */ - ipv4_input(&priv->dev); + ipv4_input(&priv->dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ - if (priv->dev.d_len > 0) - { - priv->write_d_len = priv->dev.d_len; - tun_transmit(priv); - } - else - { - priv->write_d_len = 0; - tun_pollnotify(priv, POLLOUT); - } + if (priv->dev.d_len > 0) + { + priv->write_d_len = priv->dev.d_len; + tun_transmit(priv); } -#endif - -#if 0 -#ifdef CONFIG_NET_IPv6 - if (BUF->type == HTONS(ETHTYPE_IP6)) + else { - nllvdbg("Iv6 frame\n"); - - /* Give the IPv6 packet to the network layer */ - - ipv6_input(&priv->dev); + priv->write_d_len = 0; + tun_pollnotify(priv, POLLOUT); + } - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. - */ +#elif defined(CONFIG_NET_IPv6) + nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); - if (priv->dev.d_len > 0) - { - /* Update the Ethernet header with the correct MAC address */ + /* Give the IPv6 packet to the network layer */ -#ifdef CONFIG_NET_IPv4 - if (IFF_IS_IPv4(priv->dev.d_flags)) - { - arp_out(&priv->dev); - } - else -#endif -#ifdef CONFIG_NET_IPv6 - { - neighbor_out(&priv->dev); - } -#endif + ipv6_input(&priv->dev); - /* And send the packet */ + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ - tun_transmit(priv); - } + if (priv->dev.d_len > 0) + { + priv->write_d_len = priv->dev.d_len; + tun_transmit(priv); } -#endif + else + { + priv->write_d_len = 0; + tun_pollnotify(priv, POLLOUT); + } + +#else + NETDEV_RXDROPPED(&priv->dev); #endif } @@ -507,11 +496,12 @@ static void tun_txdone(FAR struct tun_device_s *priv) { /* Check for errors and update statistics */ + NETDEV_TXDONE(&priv->dev); + /* Then poll uIP for new XMIT data */ priv->dev.d_buf = priv->read_buf; (void)devif_poll(&priv->dev, tun_txpoll); - priv->read_d_len = priv->dev.d_len; } /**************************************************************************** @@ -537,14 +527,13 @@ static void tun_poll_process(FAR struct tun_device_s *priv) * the TX poll if he are unable to accept another packet for transmission. */ - /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. - * might be bug here. Does this mean if there is a transmit in progress, - * we will missing TCP time state updates? - */ + if (priv->read_d_len == 0) + { + /* If so, poll uIP for new XMIT data. */ - priv->dev.d_buf = priv->read_buf; - (void)devif_timer(&priv->dev, tun_txpoll, TUN_POLLHSEC); - priv->read_d_len = priv->dev.d_len; + priv->dev.d_buf = priv->read_buf; + (void)devif_timer(&priv->dev, tun_txpoll); + } /* Setup the watchdog poll timer again */ @@ -576,9 +565,13 @@ static void tun_poll_work(FAR void *arg) /* Perform the poll */ + tun_lock(priv); state = net_lock(); + tun_poll_process(priv); + net_unlock(state); + tun_unlock(priv); } #endif @@ -757,7 +750,6 @@ static int tun_txavail(struct net_driver_s *dev) priv->dev.d_buf = priv->read_buf; (void)devif_poll(&priv->dev, tun_txpoll); - priv->read_d_len = priv->dev.d_len; } net_unlock(state); @@ -787,8 +779,6 @@ static int tun_txavail(struct net_driver_s *dev) #if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) static int tun_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) { - //FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private; - /* Add the MAC address to the hardware multicast routing table */ return OK; @@ -816,8 +806,6 @@ static int tun_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) #ifdef CONFIG_NET_IGMP static int tun_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) { - //FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private; - /* Add the MAC address to the hardware multicast routing table */ return OK; @@ -862,7 +850,7 @@ static void tun_ipv6multicast(FAR struct tun_device_s *priv) ****************************************************************************/ static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep, - FAR const char* devfmt) + FAR const char *devfmt) { int ret; @@ -876,7 +864,7 @@ static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep, priv->dev.d_addmac = tun_addmac; /* Add multicast MAC address */ priv->dev.d_rmmac = tun_rmmac; /* Remove multicast MAC address */ #endif - priv->dev.d_private = (void*)priv; /* Used to recover private state from dev */ + priv->dev.d_private = (FAR void *)priv; /* Used to recover private state from dev */ /* Initialize the wait semaphore */ @@ -1110,7 +1098,7 @@ int tun_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) FAR struct tun_device_s *priv = filep->f_priv; pollevent_t eventset; int ret = OK; - + if (!priv) { return -EINVAL; @@ -1176,8 +1164,8 @@ errout: static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { - FAR struct inode *inode = filep->f_inode; - FAR struct tun_driver_s *tun = inode->i_private; + FAR struct inode *inode = filep->f_inode; + FAR struct tun_driver_s *tun = inode->i_private; FAR struct tun_device_s *priv = filep->f_priv; int ret = OK; @@ -1185,9 +1173,9 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { uint8_t free_tuns; int intf; - FAR struct ifreq *ifr = (FAR struct ifreq*)arg; + FAR struct ifreq *ifr = (FAR struct ifreq *)arg; - if (!ifr || ifr->ifr_flags != IFF_TUN) + if (!ifr || (ifr->ifr_flags & IFF_MASK) != IFF_TUN) { return -EINVAL; } @@ -1218,7 +1206,6 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg) priv = filep->f_priv; strncpy(ifr->ifr_name, priv->dev.d_ifname, IFNAMSIZ); - lldbg("--- %s\n", priv->dev.d_ifname); tundev_unlock(tun); diff --git a/drivers/net/vnet.c b/drivers/net/vnet.c index cba5f5aa6397b46ac5404ef3cf3dd0839ad29413..eec509ec87dda166984abc63e1b00bdda3ec2f6c 100644 --- a/drivers/net/vnet.c +++ b/drivers/net/vnet.c @@ -81,7 +81,6 @@ /* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ #define VNET_WDDELAY (1*CLK_TCK) -#define VNET_POLLHSEC (1*2) /* TX timeout = 1 minute */ @@ -103,12 +102,11 @@ struct vnet_driver_s { bool sk_bifup; /* true:ifup false:ifdown */ WDOG_ID sk_txpoll; /* TX poll timer */ - //WDOG_ID sk_txtimeout; /* TX timeout timer */ + struct rgmp_vnet *vnet; - /* This holds the information visible to uIP/NuttX */ + /* This holds the information visible to the NuttX */ - struct rgmp_vnet *vnet; - struct net_driver_s sk_dev; /* Interface understood by uIP */ + struct net_driver_s sk_dev; /* Interface understood by the network */ }; /**************************************************************************** @@ -178,17 +176,11 @@ static int vnet_transmit(FAR struct vnet_driver_s *vnet) * must have assured that there is not transmission in progress. */ - /* Increment statistics */ - /* Send the packet: address=vnet->sk_dev.d_buf, length=vnet->sk_dev.d_len */ err = vnet_xmit(vnet->vnet, (char *)vnet->sk_dev.d_buf, vnet->sk_dev.d_len); if (err) { - /* Setup the TX timeout watchdog (perhaps restarting the timer) */ - - //(void)wd_start(vnet->sk_txtimeout, VNET_TXTIMEOUT, vnet_txtimeout, 1, (uint32_t)vnet); - /* When vnet_xmit fail, it means TX buffer is full. Watchdog * is of no use here because no TX done INT will happen. So * we reset the TX buffer directly. @@ -213,8 +205,9 @@ static int vnet_transmit(FAR struct vnet_driver_s *vnet) * Function: vnet_txpoll * * Description: - * The transmitter is available, check if uIP has any outgoing packets ready - * to send. This is a callback from devif_poll(). devif_poll() may be called: + * The transmitter is available, check if the network has any outgoing + * packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: * * 1. When the preceding TX packet send is complete, * 2. When the preceding TX packet send timesout and the interface is reset @@ -309,9 +302,9 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len) do { - /* Check for errors and update statistics */ - - /* Check if the packet is a valid size for the uIP buffer configuration */ + /* Check if the packet is a valid size for the network buffer + * configuration. + */ if (len > CONFIG_NET_ETH_MTU || len < 14) { @@ -418,8 +411,9 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len) { arp_arpin(&vnet->sk_dev); - /* If the above function invocation resulted in data that should be - * sent out on the network, the field d_len will set to a value > 0. + /* If the above function invocation resulted in data that should + * be sent out on the network, the field d_len will set to a + * value > 0. */ if (vnet->sk_dev.d_len > 0) @@ -451,15 +445,7 @@ void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len) static void vnet_txdone(FAR struct vnet_driver_s *vnet) { - /* Check for errors and update statistics */ - - /* If no further xmits are pending, then cancel the TX timeout and - * disable further Tx interrupts. - */ - - //wd_cancel(vnet->sk_txtimeout); - - /* Then poll uIP for new XMIT data */ + /* Poll the network for new XMIT data */ (void)devif_poll(&vnet->sk_dev, vnet_txpoll); } @@ -487,11 +473,7 @@ static void vnet_txtimeout(int argc, uint32_t arg, ...) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)arg; - /* Increment statistics and dump debug info */ - - /* Then reset the hardware */ - - /* Then poll uIP for new XMIT data */ + /* Poll the network for new XMIT data */ (void)devif_poll(&vnet->sk_dev, vnet_txpoll); } @@ -530,16 +512,17 @@ static void vnet_polltimer(int argc, uint32_t arg, ...) return; } - /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. - * might be bug here. Does this mean if there is a transmit in progress, - * we will missing TCP time state updates? + /* If so, update TCP timing states and poll the network for new XMIT data. + * Hmmm.. might be bug here. Does this mean if there is a transmit in + * progress, we will missing TCP time state updates? */ - (void)devif_timer(&vnet->sk_dev, vnet_txpoll, VNET_POLLHSEC); + (void)devif_timer(&vnet->sk_dev, vnet_txpoll); /* Setup the watchdog poll timer again */ - (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, arg); + (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, + (wdparm_t)arg); } /**************************************************************************** @@ -565,13 +548,14 @@ static int vnet_ifup(struct net_driver_s *dev) ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, - (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 ); + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */ /* Set and activate a timer process */ - (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, (uint32_t)vnet); + (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, + (wdparm_t)vnet); vnet->sk_bifup = true; return OK; @@ -600,12 +584,11 @@ static int vnet_ifdown(struct net_driver_s *dev) /* Disable the Ethernet interrupt */ - flags = irqsave(); + flags = enter_critical_section(); /* Cancel the TX poll timer and TX timeout timers */ wd_cancel(vnet->sk_txpoll); - //wd_cancel(vnet->sk_txtimeout); /* Put the EMAC is its reset, non-operational state. This should be * a known configuration that will guarantee the vnet_ifup() always @@ -615,7 +598,7 @@ static int vnet_ifdown(struct net_driver_s *dev) /* Mark the device "down" */ vnet->sk_bifup = false; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -647,7 +630,7 @@ static int vnet_txavail(struct net_driver_s *dev) * level processing. */ - flags = irqsave(); + flags = enter_critical_section(); /* Ignore the notification if the interface is not yet up */ @@ -663,13 +646,13 @@ static int vnet_txavail(struct net_driver_s *dev) goto out; } - /* If so, then poll uIP for new XMIT data */ + /* If so, then poll the network for new XMIT data */ (void)devif_poll(&vnet->sk_dev, vnet_txpoll); } out: - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -774,15 +757,14 @@ int vnet_init(struct rgmp_vnet *vnet) priv->sk_dev.d_addmac = vnet_addmac; /* Add multicast MAC address */ priv->sk_dev.d_rmmac = vnet_rmmac; /* Remove multicast MAC address */ #endif - priv->sk_dev.d_private = (void*)priv; /* Used to recover private state from dev */ + priv->sk_dev.d_private = (FAR void *)priv; /* Used to recover private state from dev */ /* Create a watchdog for timing polling for and timing of transmisstions */ - priv->sk_txpoll = wd_create(); /* Create periodic poll timer */ - //priv->sk_txtimeout = wd_create(); /* Create TX timeout timer */ + priv->sk_txpoll = wd_create(); /* Create periodic poll timer */ - priv->vnet = vnet; - vnet->priv = priv; + priv->vnet = vnet; + vnet->priv = priv; /* Register the device with the OS */ diff --git a/drivers/pipes/fifo.c b/drivers/pipes/fifo.c index 7148edc3cc45645705b46218bffed3cafeb28fdb..85905cb1114a974cc5754d3d9e3e655c0a79a4fa 100644 --- a/drivers/pipes/fifo.c +++ b/drivers/pipes/fifo.c @@ -121,7 +121,7 @@ static const struct file_operations fifo_fops = int mkfifo(FAR const char *pathname, mode_t mode) { - struct pipe_dev_s *dev; + FAR struct pipe_dev_s *dev; int ret; /* Allocate and initialize a new device structure instance */ @@ -132,7 +132,7 @@ int mkfifo(FAR const char *pathname, mode_t mode) return -ENOMEM; } - ret = register_driver(pathname, &fifo_fops, mode, (void*)dev); + ret = register_driver(pathname, &fifo_fops, mode, (FAR void *)dev); if (ret != 0) { pipecommon_freedev(dev); diff --git a/drivers/pipes/pipe.c b/drivers/pipes/pipe.c index 530c9871a217867134a21c746f570527bb6e1428..b4c6acd72c4dbd0a649f0362f824d2e1d5f7784f 100644 --- a/drivers/pipes/pipe.c +++ b/drivers/pipes/pipe.c @@ -234,7 +234,7 @@ int pipe(int fd[2]) /* Register the pipe device */ - ret = register_driver(devname, &pipe_fops, 0666, (void*)dev); + ret = register_driver(devname, &pipe_fops, 0666, (FAR void *)dev); if (ret != 0) { (void)sem_post(&g_pipesem); diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c index e2f33aceecb66c2b050eefc94440429990deb5b7..346bb5dc692fcffbb852919bd123b04cb7893793 100644 --- a/drivers/pipes/pipe_common.c +++ b/drivers/pipes/pipe_common.c @@ -55,7 +55,7 @@ #include #include -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG # include #endif @@ -161,7 +161,7 @@ static void pipecommon_pollnotify(FAR struct pipe_dev_s *dev, pollevent_t events FAR struct pipe_dev_s *pipecommon_allocdev(void) { - struct pipe_dev_s *dev; + FAR struct pipe_dev_s *dev; /* Allocate a private structure to manage the pipe */ @@ -197,12 +197,12 @@ void pipecommon_freedev(FAR struct pipe_dev_s *dev) int pipecommon_open(FAR struct file *filep) { - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; - int sval; - int ret; + FAR struct inode *inode = filep->f_inode; + FAR struct pipe_dev_s *dev = inode->i_private; + int sval; + int ret; - DEBUGASSERT(dev); + DEBUGASSERT(dev != NULL); /* Make sure that we have exclusive access to the device structure. The * sem_wait() call should fail only if we are awakened by a signal. @@ -223,7 +223,7 @@ int pipecommon_open(FAR struct file *filep) if (dev->d_refs == 0 && dev->d_buffer == NULL) { - dev->d_buffer = (uint8_t*)kmm_malloc(CONFIG_DEV_PIPE_SIZE); + dev->d_buffer = (FAR uint8_t *)kmm_malloc(CONFIG_DEV_PIPE_SIZE); if (!dev->d_buffer) { (void)sem_post(&dev->d_bfsem); @@ -371,7 +371,7 @@ int pipecommon_close(FAR struct file *filep) } } - /* What is the buffer management policy? Do we free the buffe when the + /* What is the buffer management policy? Do we free the buffer when the * last client closes the pipe policy 0, or when the buffer becomes empty. * In the latter case, the buffer data will remain valid and can be * obtained when the pipe is re-opened. @@ -418,7 +418,7 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len) struct inode *inode = filep->f_inode; struct pipe_dev_s *dev = inode->i_private; #ifdef CONFIG_DEV_PIPEDUMP - FAR uint8_t *start = (uint8_t*)buffer; + FAR uint8_t *start = (FAR uint8_t *)buffer; #endif ssize_t nread = 0; int sval; @@ -514,7 +514,7 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t int sval; DEBUGASSERT(dev); - pipe_dumpbuffer("To PIPE:", (uint8_t*)buffer, len); + pipe_dumpbuffer("To PIPE:", (FAR uint8_t *)buffer, len); if (len == 0) { @@ -545,7 +545,7 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t /* Loop until all of the bytes have been written */ last = 0; - for (;;) + for (; ; ) { /* Calculate the write index AFTER the next byte is written */ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 46456b60f5893bfae49f27340d97617785f39e16..4084a5284b759a694a4db4b6745bdaf3aad18e2f 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -2,22 +2,40 @@ # For a description of the syntax of this configuration file, # see the file kconfig-language.txt in the NuttX tools repository. # -config BATTERY - bool "Battery support" + +config BATTERY_CHARGER + bool "Battery Charger support" + default n + +config BQ2425X + bool "BQ2425X Battery charger support" + default n + select I2C + select I2C_BQ2425X + depends on BATTERY_CHARGER + ---help--- + The BQ24250/BQ24251 are battery charger for lithium-ion batteries. + +config BATTERY_GAUGE + bool "Battery Fuel Gauge support" default n config MAX1704X - bool "MAX1704X Battery charger support" + bool "MAX1704X Battery fuel gauge support" default n select I2C select I2C_MAX1704X - depends on BATTERY + depends on BATTERY_GAUGE ---help--- The MAX17040/MAX17041 are ultra-compact, low-cost, host-side fuel-gauge systems for lithium-ion (Li+) batteries in handheld and portable equipment. The MAX17040 is configured to operate with a single lithium cell and the MAX17041 is configured for a dual-cell 2S pack. +config I2C_BQ2425X + bool + default y if BQ2425X + config I2C_MAX1704X bool default y if MAX1704X diff --git a/drivers/power/Make.defs b/drivers/power/Make.defs index e3452120dde455b563bae0a0acca1d4d746b5c9d..40ab591dff09e79d529b8d5db1c9606014f21fde 100644 --- a/drivers/power/Make.defs +++ b/drivers/power/Make.defs @@ -41,7 +41,8 @@ POWER_CFLAGS = ifeq ($(CONFIG_PM),y) -CSRCS += pm_activity.c pm_changestate.c pm_checkstate.c pm_initialize.c pm_register.c pm_update.c +CSRCS += pm_activity.c pm_changestate.c pm_checkstate.c pm_initialize.c +CSRCS += pm_register.c pm_update.c # Include power management in the build @@ -51,17 +52,43 @@ POWER_CFLAGS := ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$ endif -# Add battery drivers +# Add battery charger drivers -ifeq ($(CONFIG_BATTERY),y) +ifeq ($(CONFIG_BATTERY_CHARGER),y) -CSRCS += battery.c +CSRCS += battery_charger.c -# Add I2C-based battery drivers +# Add I2C-based battery charger drivers ifeq ($(CONFIG_I2C),y) -# Add the MAX1704x I2C-based battery driver +# Add the BQ2425x I2C-based battery charger driver + +ifeq ($(CONFIG_I2C_BQ2425X),y) +CSRCS += bq2425x.c +endif + +endif + +# Include battery suport in the build + +POWER_DEPPATH := --dep-path power +POWER_VPATH := :power +POWER_CFLAGS := ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)power} + +endif + +# Add battery gauge drivers + +ifeq ($(CONFIG_BATTERY_GAUGE),y) + +CSRCS += battery_gauge.c + +# Add I2C-based battery gauge drivers + +ifeq ($(CONFIG_I2C),y) + +# Add the MAX1704x I2C-based battery guage driver ifeq ($(CONFIG_I2C_MAX1704X),y) CSRCS += max1704x.c diff --git a/drivers/power/battery_charger.c b/drivers/power/battery_charger.c new file mode 100644 index 0000000000000000000000000000000000000000..056e16e98c844046426c75fdb67ba7e065823b39 --- /dev/null +++ b/drivers/power/battery_charger.c @@ -0,0 +1,276 @@ +/**************************************************************************** + * drivers/power/battery_charger.c + * Upper-half, character driver for batteries charger. + * + * Copyright (C) 2015 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + */ + +#if defined(CONFIG_BATTERY_CHARGER) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int bat_charger_open(FAR struct file *filep); +static int bat_charger_close(FAR struct file *filep); +static ssize_t bat_charger_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t bat_charger_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen); +static int bat_charger_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_batteryops = +{ + bat_charger_open, + bat_charger_close, + bat_charger_read, + bat_charger_write, + 0, + bat_charger_ioctl +#ifndef CONFIG_DISABLE_POLL + , 0 +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: bat_charger_open + * + * Description: + * This function is called whenever the battery device is opened. + * + ****************************************************************************/ + +static int bat_charger_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: bat_charger_close + * + * Description: + * This routine is called when the battery device is closed. + * + ****************************************************************************/ + +static int bat_charger_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: bat_charger_read + ****************************************************************************/ + +static ssize_t bat_charger_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + /* Return nothing read */ + + return 0; +} + +/**************************************************************************** + * Name: bat_charger_write + ****************************************************************************/ + +static ssize_t bat_charger_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + /* Return nothing written */ + + return 0; +} + +/**************************************************************************** + * Name: bat_charger_ioctl + ****************************************************************************/ + +static int bat_charger_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct battery_charger_dev_s *dev = inode->i_private; + int ret; + + /* Inforce mutually exclusive access to the battery driver */ + + ret = sem_wait(&dev->batsem); + if (ret < 0) + { + return -errno; /* Probably EINTR */ + } + + /* Procss the IOCTL command */ + + ret = -EINVAL; /* Assume a bad argument */ + switch (cmd) + { + case BATIOC_STATE: + { + FAR int *ptr = (FAR int *)((uintptr_t)arg); + if (ptr) + { + ret = dev->ops->state(dev, ptr); + } + } + break; + + case BATIOC_HEALTH: + { + FAR int *ptr = (FAR int *)((uintptr_t)arg); + if (ptr) + { + ret = dev->ops->health(dev, ptr); + } + } + break; + + case BATIOC_ONLINE: + { + FAR bool *ptr = (FAR bool *)((uintptr_t)arg); + if (ptr) + { + ret = dev->ops->online(dev, ptr); + } + } + break; + + case BATIOC_VOLTAGE: + { + int volts; + FAR int *voltsp = (FAR int *)((uintptr_t)arg); + if (voltsp) + { + volts = *voltsp; + ret = dev->ops->voltage(dev, volts); + } + } + break; + + case BATIOC_CURRENT: + { + int amps; + FAR int *ampsp = (FAR int *)((uintptr_t)arg); + if (ampsp) + { + amps = *ampsp; + ret = dev->ops->current(dev, amps); + } + } + break; + + default: + dbg("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + sem_post(&dev->batsem); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: battery_charger_register + * + * Description: + * Register a lower half battery driver with the common, upper-half + * battery driver. + * + * Input parameters: + * devpath - The location in the pseudo-filesystem to create the driver. + * Recommended standard is "/dev/bat0", "/dev/bat1", etc. + * dev - An instance of the battery state structure . + * + * Returned value: + * Zero on success or a negated errno value on failure. + * + ****************************************************************************/ + +int battery_charger_register(FAR const char *devpath, + FAR struct battery_charger_dev_s *dev) +{ + int ret; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_batteryops, 0555, dev); + if (ret < 0) + { + dbg("Failed to register driver: %d\n", ret); + } + + return ret; +} +#endif /* CONFIG_BATTERY_CHARGER */ diff --git a/drivers/power/battery.c b/drivers/power/battery_gauge.c similarity index 82% rename from drivers/power/battery.c rename to drivers/power/battery_gauge.c index b26fe6c6b99205d8a3434898fdd9f0cf20ac3617..cf6a962e2b6bfc02d83b4c38b371d193f41c558a 100644 --- a/drivers/power/battery.c +++ b/drivers/power/battery_gauge.c @@ -1,6 +1,6 @@ /**************************************************************************** - * drivers/power/battery.c - * Upper-half, character driver for batteries. + * drivers/power/battery_gauge_gauge.c + * Upper-half, character driver for battery fuel gauge. * * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,7 +46,8 @@ #include #include -#include +#include +#include /* This driver requires: * @@ -69,11 +70,14 @@ /* Character driver methods */ -static int bat_open(FAR struct file *filep); -static int bat_close(FAR struct file *filep); -static ssize_t bat_read(FAR struct file *, FAR char *, size_t nbytes); -static ssize_t bat_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); -static int bat_ioctl(FAR struct file *filep,int cmd,unsigned long arg); +static int bat_gauge_open(FAR struct file *filep); +static int bat_gauge_close(FAR struct file *filep); +static ssize_t bat_gauge_read(FAR struct file *filep, FAR char *buflen, + size_t buflen); +static ssize_t bat_gauge_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int bat_gauge_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); /**************************************************************************** * Private Data @@ -81,12 +85,12 @@ static int bat_ioctl(FAR struct file *filep,int cmd,unsigned long arg); static const struct file_operations g_batteryops = { - bat_open, - bat_close, - bat_read, - bat_write, + bat_gauge_open, + bat_gauge_close, + bat_gauge_read, + bat_gauge_write, 0, - bat_ioctl + bat_gauge_ioctl #ifndef CONFIG_DISABLE_POLL , 0 #endif @@ -96,36 +100,37 @@ static const struct file_operations g_batteryops = * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: bat_open + * Name: bat_gauge_open * * Description: * This function is called whenever the battery device is opened. * ****************************************************************************/ -static int bat_open(FAR struct file *filep) +static int bat_gauge_open(FAR struct file *filep) { return OK; } /**************************************************************************** - * Name: bat_close + * Name: bat_gauge_close * * Description: * This routine is called when the battery device is closed. * ****************************************************************************/ -static int bat_close(FAR struct file *filep) +static int bat_gauge_close(FAR struct file *filep) { return OK; } /**************************************************************************** - * Name: bat_read + * Name: bat_gauge_read ****************************************************************************/ -static ssize_t bat_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +static ssize_t bat_gauge_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) { /* Return nothing read */ @@ -133,10 +138,10 @@ static ssize_t bat_read(FAR struct file *filep, FAR char *buffer, size_t buflen) } /**************************************************************************** - * Name: bat_write + * Name: bat_gauge_write ****************************************************************************/ -static ssize_t bat_write(FAR struct file *filep, FAR const char *buffer, +static ssize_t bat_gauge_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) { /* Return nothing written */ @@ -145,13 +150,13 @@ static ssize_t bat_write(FAR struct file *filep, FAR const char *buffer, } /**************************************************************************** - * Name: bat_ioctl + * Name: bat_gauge_ioctl ****************************************************************************/ -static int bat_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +static int bat_gauge_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; - FAR struct battery_dev_s *dev = inode->i_private; + FAR struct battery_gauge_dev_s *dev = inode->i_private; int ret; /* Inforce mutually exclusive access to the battery driver */ @@ -222,7 +227,7 @@ static int bat_ioctl(FAR struct file *filep, int cmd, unsigned long arg) ****************************************************************************/ /**************************************************************************** - * Name: battery_register + * Name: battery_gauge_register * * Description: * Register a lower half battery driver with the common, upper-half @@ -238,7 +243,8 @@ static int bat_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -int battery_register(FAR const char *devpath, FAR struct battery_dev_s *dev) +int battery_gauge_register(FAR const char *devpath, + FAR struct battery_gauge_dev_s *dev) { int ret; diff --git a/drivers/power/bq2425x.c b/drivers/power/bq2425x.c new file mode 100644 index 0000000000000000000000000000000000000000..073c3ce379f6774378abb2e98188bc5ae2bde34f --- /dev/null +++ b/drivers/power/bq2425x.c @@ -0,0 +1,781 @@ +/**************************************************************************** + * drivers/power/bq2425x.c + * Lower half driver for BQ2425x battery charger + * + * Copyright (C) 2015 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/* The BQ24250/BQ24251 are Li-Ion Battery Charger with Power-Path Management. + * It can be configured to Input Current Limit up to 2A. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "bq2425x.h" + +/* This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + * CONFIG_I2C - I2C support + * CONFIG_I2C_BQ2425X - And the driver must be explictly selected. + */ + +#if defined(CONFIG_BATTERY_CHARGER) && defined(CONFIG_I2C) && \ + defined(CONFIG_I2C_BQ2425X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Debug ********************************************************************/ + +#ifdef CONFIG_DEBUG_BQ2425X +# define batdbg dbg +#else +# ifdef CONFIG_CPP_HAVE_VARARGS +# define batdbg(x...) +# else +# define batdbg (void) +# endif +#endif + +/**************************************************************************** + * Private + ****************************************************************************/ + +struct bq2425x_dev_s +{ + /* The common part of the battery driver visible to the upper-half driver */ + + FAR const struct battery_charger_operations_s *ops; /* Battery operations */ + sem_t batsem; /* Enforce mutually exclusive access */ + + /* Data fields specific to the lower half BQ2425x driver follow */ + + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + uint32_t frequency; /* I2C frequency */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* I2C support */ + +static int bq2425x_getreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval); +static int bq2425x_putreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, + uint8_t regval); + +static inline int bq2425x_getreport(FAR struct bq2425x_dev_s *priv, + uint8_t *report); +static inline int bq2425x_reset(FAR struct bq2425x_dev_s *priv); +static inline int bq2425x_watchdog(FAR struct bq2425x_dev_s *priv, bool enable); +static inline int bq2425x_setvolt(FAR struct bq2425x_dev_s *priv, int volts); +static inline int bq2425x_setcurr(FAR struct bq2425x_dev_s *priv, int current); + +/* Battery driver lower half methods */ + +static int bq2425x_state(struct battery_charger_dev_s *dev, int *status); +static int bq2425x_health(struct battery_charger_dev_s *dev, int *health); +static int bq2425x_online(struct battery_charger_dev_s *dev, bool *status); +static int bq2425x_voltage(struct battery_charger_dev_s *dev, int value); +static int bq2425x_current(struct battery_charger_dev_s *dev, int value); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct battery_charger_operations_s g_bq2425xops = +{ + bq2425x_state, + bq2425x_health, + bq2425x_online, + bq2425x_voltage, + bq2425x_current +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bq2425x_getreg8 + * + * Description: + * Read a 8-bit value from a BQ2425x register pair. + * + * START ACK ACK + * REPEATED-START ACK Data0 ACK Data1 NO-ACK STOP + * + ****************************************************************************/ + +static int bq2425x_getreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval) +{ + struct i2c_config_s config; + uint8_t val; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + ret = i2c_write(priv->i2c, &config, ®addr, 1); + if (ret < 0) + { + batdbg("i2c_write failed: %d\n", ret); + return ret; + } + + /* Restart and read 8-bits from the register */ + + ret = i2c_read(priv->i2c, &config, &val, 1); + if (ret < 0) + { + batdbg("i2c_read failed: %d\n", ret); + return ret; + } + + /* Copy 8-bit value to be returned */ + + *regval = val; + return OK; +} + +/**************************************************************************** + * Name: bq2425x_putreg8 + * + * Description: + * Write a 8-bit value to a BQ2425x register pair. + * + * START ACK ACK Data0 ACK Data1 ACK STOP + * + ****************************************************************************/ + +static int bq2425x_putreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr, + uint8_t regval) +{ + struct i2c_config_s config; + uint8_t buffer[2]; + + /* Set up the I2C configuration */ + + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; + + batdbg("addr: %02x regval: %08x\n", regaddr, regval); + + /* Set up a 3 byte message to send */ + + buffer[0] = regaddr; + buffer[1] = regval; + + /* Write the register address followed by the data (no RESTART) */ + + return i2c_write(priv->i2c, &config, buffer, 2); +} + +/**************************************************************************** + * Name: bq2425x_getreport + * + * Description: + * Read the BQ2425X Register #1 (status and fault) + * + ****************************************************************************/ + +static inline int bq2425x_getreport(FAR struct bq2425x_dev_s *priv, + uint8_t *report) +{ + uint8_t regval = 0; + int ret; + + ret = bq2425x_getreg8(priv, BQ2425X_REG_1, ®val); + if (ret == OK) + { + *report = regval; + } + + return ret; +} + +/**************************************************************************** + * Name: bq2425x_reset + * + * Description: + * Reset the BQ2425x + * + ****************************************************************************/ + +static inline int bq2425x_reset(FAR struct bq2425x_dev_s *priv) +{ + int ret; + uint8_t regval; + + /* Read current register value */ + + ret = bq2425x_getreg8(priv, BQ2425X_REG_2, ®val); + if (ret < 0) + { + batdbg("Error reading from BQ2425X! Error = %d\n", ret); + return ret; + } + + /* Send reset command */ + + regval |= BQ2425X_RESET; + ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + /* Wait a little bit to clear registers */ + + usleep(500); + + /* There is a BUG in BQ2425X the RESET bit is always read as 1 */ + + regval &= ~(BQ2425X_RESET); + ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_watchdog + * + * Description: + * Enable/Disable the BQ2425x watchdog + * + ****************************************************************************/ + +static inline int bq2425x_watchdog(FAR struct bq2425x_dev_s *priv, bool enable) +{ + int ret; + uint8_t regval; + + ret = bq2425x_getreg8(priv, BQ2425X_REG_1, ®val); + if (ret < 0) + { + batdbg("Error reading from BQ2425X! Error = %d\n", ret); + return ret; + } + + if (enable) + { + regval |= BQ2425X_WD_EN; + } + else + { + regval &= ~(BQ2425X_WD_EN); + } + + ret = bq2425x_putreg8(priv, BQ2425X_REG_1, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_state + * + * Description: + * Return the current battery state + * + ****************************************************************************/ + +static int bq2425x_state(struct battery_charger_dev_s *dev, int *status) +{ + FAR struct bq2425x_dev_s *priv = (FAR struct bq2425x_dev_s *)dev; + uint8_t regval = 0; + int ret; + + ret = bq2425x_getreport(priv, ®val); + if (ret < 0) + { + *status = BATTERY_UNKNOWN; + return ret; + } + + regval &= BQ2425X_STAT_MASK; + + /* Is there some fault in the battery? */ + + if (regval == BQ2425X_STAT_FAULT) + { + *status = BATTERY_FAULT; + } + + /* Is the charging done? */ + + else if (regval == BQ2425X_STAT_CHG_DONE) + { + *status = BATTERY_FULL; + } + + /* Is the charging in progress? */ + + else if (regval == BQ2425X_STAT_CHG_PROGRESS) + { + *status = BATTERY_CHARGING; + } + + /* Is the charging ready? */ + + else if (regval == BQ2425X_STAT_READY) + { + *status = BATTERY_IDLE; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_health + * + * Description: + * Return the current battery health state + * + * Note: if more than one fault happened the user needs to call this ioctl + * again to read a new fault, repeat until receive a BATTERY_HEALTH_GOOD. + * + ****************************************************************************/ + +static int bq2425x_health(struct battery_charger_dev_s *dev, int *health) +{ + FAR struct bq2425x_dev_s *priv = (FAR struct bq2425x_dev_s *)dev; + uint8_t regval = 0; + int ret; + + ret = bq2425x_getreport(priv, ®val); + if (ret < 0) + { + *health = BATTERY_HEALTH_UNKNOWN; + return ret; + } + + regval &= BQ2425X_FAULT_MASK; + + switch (regval) + { + case BQ2425X_FAULT_NORMAL: + *health = BATTERY_HEALTH_GOOD; + break; + + case BQ2425X_FAULT_SLEEP: + case BQ2425X_FAULT_INP_OVP: + case BQ2425X_FAULT_INP_UVLO: + case BQ2425X_FAULT_ISET_SHORT: + case BQ2425X_FAULT_INP_LDO_LOW: + *health = BATTERY_HEALTH_UNSPEC_FAIL; + break; + + case BQ2425X_FAULT_BAT_OVP: + *health = BATTERY_HEALTH_OVERVOLTAGE; + break; + + case BQ2425X_FAULT_BAT_TEMP: + case BQ2425X_FAULT_THERM_SHUT: + *health = BATTERY_HEALTH_OVERHEAT; + break; + + case BQ2425X_FAULT_TIMER: + *health = BATTERY_HEALTH_SAFE_TMR_EXP; + break; + + case BQ2425X_FAULT_NO_BATTERY: + *health = BATTERY_HEALTH_DISCONNECTED; + break; + + default: + *health = BATTERY_HEALTH_UNKNOWN; + break; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_online + * + * Description: + * Return true if the battery is online + * + ****************************************************************************/ + +static int bq2425x_online(struct battery_charger_dev_s *dev, bool *status) +{ + /* There is no concept of online/offline in this driver */ + + *status = true; + return OK; +} + +/**************************************************************************** + * Name: bq2425x_powersupply + * + * Description: + * Set the Power Supply Current Limit. + * + ****************************************************************************/ + +static inline int bq2425x_powersupply(FAR struct bq2425x_dev_s *priv, int current) +{ + uint8_t regval; + int ret, idx; + + switch (current) + { + case 100: + idx = BQ2425X_INP_CURR_LIM_100MA; + break; + + case 150: + idx = BQ2425X_INP_CURR_LIM_150MA; + break; + + case 500: + idx = BQ2425X_INP_CURR_LIM_500MA; + break; + + case 900: + idx = BQ2425X_INP_CURR_LIM_900MA; + break; + + case 1500: + idx = BQ2425X_INP_CURR_LIM_1500MA; + break; + + case 2000: + idx = BQ2425X_INP_CURR_LIM_2000MA; + break; + + default: + batdbg("Current not supported, setting default to 100mA.!\n"); + idx = BQ2425X_INP_CURR_LIM_100MA; + break; + } + + /* Read current register */ + + ret = bq2425x_getreg8(priv, BQ2425X_REG_2, ®val); + if (ret < 0) + { + batdbg("Error reading from BQ2425X! Error = %d\n", ret); + return ret; + } + + /* Clear previous current and set new value */ + + regval &= ~(BQ2425X_INP_CURR_LIM_MASK); + regval |= idx; + + /* Also clear Reset bit to avoid the resetting BUG */ + + regval &= ~(BQ2425X_RESET); + + ret = bq2425x_putreg8(priv, BQ2425X_REG_2, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_setvolt + * + * Description: + * Set the voltage level to charge the battery. Voltage value in mV. + * + ****************************************************************************/ + +static inline int bq2425x_setvolt(FAR struct bq2425x_dev_s *priv, int volts) +{ + uint8_t regval; + int ret, idx; + + /* Verify if voltage is in the acceptable range */ + + if (volts < BQ2425X_VOLT_MIN || volts > BQ2425X_VOLT_MAX) + { + batdbg("Voltage %d mV is out of range.\n", volts); + return -EINVAL; + } + + ret = bq2425x_getreg8(priv, BQ2425X_REG_3, ®val); + if (ret < 0) + { + batdbg("Error reading from BQ2425X! Error = %d\n", ret); + return ret; + } + + /* Voltage starts at 3500mV and increases in steps of 20mV */ + + idx = volts - BQ2425X_VOLT_MIN; + idx = idx / 20; + + /* Clear previous voltage */ + + regval &= ~(BQ2425X_BAT_VOLT_MASK); + regval |= (idx << BQ2425X_BAT_VOLT_SHIFT); + + ret = bq2425x_putreg8(priv, BQ2425X_REG_3, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_setcurr + * + * Description: + * Set the current to charge the battery. Current value in mA. + * + ****************************************************************************/ + +static inline int bq2425x_setcurr(FAR struct bq2425x_dev_s *priv, int current) +{ + uint8_t regval; + int ret, idx; + + /* Verify if voltage is in the acceptable range */ + + if (current < BQ2425X_CURR_MIN || current > BQ2425X_CURR_MAX) + { + batdbg("Current %d mA is out of range.\n", volts); + return -EINVAL; + } + + ret = bq2425x_getreg8(priv, BQ2425X_REG_4, ®val); + if (ret < 0) + { + batdbg("Error reading from BQ2425X! Error = %d\n", ret); + return ret; + } + + /* Current starts at 500mV and increases in steps of 50mA */ + + idx = current - BQ2425X_CURR_MIN; + idx = idx / 50; + + /* Clear previous current and set new value */ + + regval &= ~(BQ2425X_CHG_CURRENT_MASK); + regval |= (idx << BQ2425X_CHG_CURRENT_SHIFT); + + ret = bq2425x_putreg8(priv, BQ2425X_REG_4, regval); + if (ret < 0) + { + batdbg("Error writing to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + + +/**************************************************************************** + * Name: bq2425x_voltage + * + * Description: + * Set battery charger voltage + * + ****************************************************************************/ + +static int bq2425x_voltage(struct battery_charger_dev_s *dev, int value) +{ + FAR struct bq2425x_dev_s *priv = (FAR struct bq2425x_dev_s *)dev; + int ret; + + /* Set voltage to battery charger */ + + ret = bq2425x_setvolt(priv, value); + if (ret < 0) + { + batdbg("Error setting voltage to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: bq2425x_current + * + * Description: + * Set the battery charger current rate for charging + * + ****************************************************************************/ + +static int bq2425x_current(struct battery_charger_dev_s *dev, int value) +{ + FAR struct bq2425x_dev_s *priv = (FAR struct bq2425x_dev_s *)dev; + int ret; + + /* Set current to battery charger */ + + ret = bq2425x_setcurr(priv, value); + if (ret < 0) + { + batdbg("Error setting current to BQ2425X! Error = %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bq2425x_initialize + * + * Description: + * Initialize the BQ2425x battery driver and return an instance of the + * lower_half interface that may be used with battery_charger_register(); + * + * This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery driver support + * CONFIG_I2C - I2C support + * CONFIG_I2C_BQ2425X - And the driver must be explictly selected. + * + * Input Parameters: + * i2c - An instance of the I2C interface to use to communicate with + * the BQ2425x + * addr - The I2C address of the BQ2425x (Better be 0x36). + * frequency - The I2C frequency + * + * Returned Value: + * A pointer to the initializeed lower-half driver instance. A NULL pointer + * is returned on a failure to initialize the BQ2425x lower half. + * + ****************************************************************************/ + +FAR struct battery_charger_dev_s * + bq2425x_initialize(FAR struct i2c_master_s *i2c, uint8_t addr, + uint32_t frequency) +{ + FAR struct bq2425x_dev_s *priv; + int ret; + + /* Initialize the BQ2425x device structure */ + + priv = (FAR struct bq2425x_dev_s *)kmm_zalloc(sizeof(struct bq2425x_dev_s)); + if (priv) + { + /* Initialize the BQ2425x device structure */ + + sem_init(&priv->batsem, 0, 1); + priv->ops = &g_bq2425xops; + priv->i2c = i2c; + priv->addr = addr; + priv->frequency = frequency; + + /* Reset the BQ2425x */ + + ret = bq2425x_reset(priv); + if (ret < 0) + { + batdbg("Failed to reset the BQ2425x: %d\n", ret); + kmm_free(priv); + return NULL; + } + + /* Disable watchdog otherwise BQ2425x returns to StandAlone mode */ + + ret = bq2425x_watchdog(priv, false); + if (ret < 0) + { + batdbg("Failed to disable BQ2425x watchdog: %d\n", ret); + kmm_free(priv); + return NULL; + } + + /* Define that our power supply can offer 2000mA to the charger */ + + ret = bq2425x_powersupply(priv, 2000); + if (ret < 0) + { + batdbg("Failed to set BQ2425x power supply current: %d\n", ret); + kmm_free(priv); + return NULL; + } + } + + return (FAR struct battery_charger_dev_s *)priv; +} + +#endif /* CONFIG_BATTERY && CONFIG_I2C && CONFIG_I2C_BQ2425X */ diff --git a/drivers/power/bq2425x.h b/drivers/power/bq2425x.h new file mode 100644 index 0000000000000000000000000000000000000000..3dd57f68a52ac964712201105251aa6df49d4877 --- /dev/null +++ b/drivers/power/bq2425x.h @@ -0,0 +1,272 @@ +/**************************************************************************** + * drivers/power/bq2425x.h + * Lower half driver for BQ2425x battery charger + * + * Copyright (C) 2015 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 __DRIVERS_POWER_BQ2425X_H +#define __DRIVERS_POWER_BQ2425X_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Auxiliary Definitions */ + +#define BQ2425X_VOLT_MIN 3500 +#define BQ2425X_VOLT_MAX 4440 + +#define BQ2425X_CURR_MIN 500 +#define BQ2425X_CURR_MAX 2000 + +/* BQ2425x Register Definitions ********************************************/ + +#define BQ2425X_REG_1 0x00 +#define BQ2425X_REG_2 0x01 +#define BQ2425X_REG_3 0x02 +#define BQ2425X_REG_4 0x03 +#define BQ2425X_REG_5 0x04 +#define BQ2425X_REG_6 0x05 +#define BQ2425X_REG_7 0x06 + +/* REG 1 */ + +#define BQ2425X_WD_FAULT (1 << 7) /* If 1 means WD timeout if WD is enabled */ +#define BQ2425X_WD_EN (1 << 6) /* Set 1 will enable and reset timeout */ +#define BQ2425X_STAT_SHIFT 4 /* Battery charger status */ +#define BQ2425X_STAT_MASK (3 << BQ2425X_STAT_SHIFT) +# define BQ2425X_STAT_READY (0 << BQ2425X_STAT_SHIFT) +# define BQ2425X_STAT_CHG_PROGRESS (1 << BQ2425X_STAT_SHIFT) +# define BQ2425X_STAT_CHG_DONE (2 << BQ2425X_STAT_SHIFT) +# define BQ2425X_STAT_FAULT (3 << BQ2425X_STAT_SHIFT) +#define BQ2425X_FAULT_SHIFT 0 /* Battery Fault report */ +#define BQ2425X_FAULT_MASK (15 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_NORMAL (0 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_INP_OVP (1 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_INP_UVLO (2 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_SLEEP (3 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_BAT_TEMP (4 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_BAT_OVP (5 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_THERM_SHUT (6 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_TIMER (7 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_NO_BATTERY (8 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_ISET_SHORT (9 << BQ2425X_FAULT_SHIFT) +# define BQ2425X_FAULT_INP_LDO_LOW (10 << BQ2425X_FAULT_SHIFT) + +/* REG 2 */ + +#define BQ2425X_RESET (1 << 7) /* Write 1 to Reset all register to default values */ +#define BQ2425X_INP_CURR_LIM_SHIFT 4 /* Input Current Limit */ +#define BQ2425X_INP_CURR_LIM_MASK (7 << BQ2425X_INP_CURR_LIM_SHIFT) +# define BQ2425X_INP_CURR_LIM_100MA (0 << BQ2425X_INP_CURR_LIM_SHIFT) /* USB2.0 host with 100mA current limit */ +# define BQ2425X_INP_CURR_LIM_150MA (1 << BQ2425X_INP_CURR_LIM_SHIFT) /* USB3.0 host with 150mA current limit */ +# define BQ2425X_INP_CURR_LIM_500MA (2 << BQ2425X_INP_CURR_LIM_SHIFT) /* USB2.0 host with 500mA current limit */ +# define BQ2425X_INP_CURR_LIM_900MA (3 << BQ2425X_INP_CURR_LIM_SHIFT) /* USB3.0 host with 900mA current limit */ +# define BQ2425X_INP_CURR_LIM_1500MA (4 << BQ2425X_INP_CURR_LIM_SHIFT) /* Charger with 1500mA current limit */ +# define BQ2425X_INP_CURR_LIM_2000MA (5 << BQ2425X_INP_CURR_LIM_SHIFT) /* Charger with 2000mA current limit */ +# define BQ2425X_INP_CURR_EXT_ILIM (6 << BQ2425X_INP_CURR_LIM_SHIFT) /* External ILIM current limit */ +# define BQ2425X_INP_CURR_NO_LIMIT (7 << BQ2425X_INP_CURR_LIM_SHIFT) /* No input current limit with internal clamp at 3A */ +#define BQ2425X_EN_STAT (1 << 3) /* Enable/Disable STAT pin */ +#define BQ2425X_EN_TERM (1 << 2) /* Enable/Disable charge termination */ +#define BQ2425X_CE (1 << 1) /* Enable/Disable the Charger, inverted logic, 0 enables */ +#define BQ2425X_HZ_MODE (1 << 0) /* Sets the charger IC into low power standby mode, but keep BAT FET ON */ + +/* REG 3 */ + +#define BQ2425X_BAT_VOLT_SHIFT 2 +#define BQ2425X_BAT_VOLT_MASK (0x3F << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3500MV (0 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3520MV (1 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3540MV (2 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3560MV (3 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3580MV (4 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3600MV (5 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3620MV (6 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3640MV (7 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3660MV (8 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3680MV (9 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3700MV (10 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3720MV (11 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3740MV (12 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3760MV (13 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3780MV (14 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3800MV (15 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3820MV (16 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3840MV (17 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3860MV (18 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3880MV (19 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3900MV (20 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3920MV (21 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3940MV (22 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3960MV (23 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_3980MV (24 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4000MV (25 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4020MV (26 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4040MV (27 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4060MV (28 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4080MV (29 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4100MV (30 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4120MV (31 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4140MV (32 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4160MV (33 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4180MV (34 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4200MV (35 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4220MV (36 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4240MV (37 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4260MV (38 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4280MV (39 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4300MV (40 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4320MV (41 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4340MV (42 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4360MV (43 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4380MV (44 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4400MV (45 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4420MV (46 << BQ2425X_BAT_VOLT_SHIFT) +# define BQ2425X_BAT_VOLT_4440MV (47 << BQ2425X_BAT_VOLT_SHIFT) +#define BQ2425X_USB_DET_EN_SHIFT 0 +#define BQ2425X_USB_DET_EN_MASK (3 << BQ2425X_USB_DET_EN_SHIFT) +# define BQ2425X_DCP_EN2_0_EN1_0 (0 << BQ2425X_USB_DET_EN_SHIFT) +# define BQ2425X_CDP_EN2_0_EN1_1 (1 << BQ2425X_USB_DET_EN_SHIFT) +# define BQ2425X_SDP_EN2_1_EN1_0 (2 << BQ2425X_USB_DET_EN_SHIFT) +# define BQ2425X_APPLE_EN2_1_EN1_1 (3 << BQ2425X_USB_DET_EN_SHIFT) + +/* REG 4 */ + +#define BQ2425X_CHG_CURRENT_SHIFT 2 +#define BQ2425X_CHG_CURRENT_MASK (0x1F << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_500MA (0 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_550MA (1 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_600MA (2 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_650MA (3 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_700MA (4 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_750MA (5 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_800MA (6 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_850MA (7 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_900MA (8 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_950MA (9 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1000MA (10 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1050MA (11 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1100MA (12 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1150MA (13 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1200MA (14 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1250MA (15 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1300MA (16 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1350MA (17 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1400MA (18 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1450MA (19 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1500MA (20 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1550MA (21 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1600MA (22 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1650MA (23 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1700MA (24 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1750MA (25 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1800MA (26 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1850MA (27 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1900MA (28 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_1950MA (29 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_CURRENT_2000MA (30 << BQ2425X_CHG_CURRENT_SHIFT) +# define BQ2425X_CHG_EXT_ISET_MODE (31 << BQ2425X_CHG_CURRENT_SHIFT) +#define BQ2425X_CHG_CURR_TERM_SHIFT 0 +#define BQ2425X_CHG_CURR_TERM_MASK (7 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_50MA (0 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_75MA (1 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_100MA (2 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_125MA (3 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_150MA (4 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_175MA (5 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_200MA (6 << BQ2425X_CHG_CURR_TERM_SHIFT) +# define BQ2425X_CHG_CURR_TERM_225MA (7 << BQ2425X_CHG_CURR_TERM_SHIFT) + +/* REG 5 */ + +#define BQ2425X_LOOP_STATUS_SHIFT 6 /* Show if there is some active loop that slow down safety timer */ +#define BQ2425X_LOOP_STATUS_MASK (3 << BQ2425X_LOOP_STATUS_SHIFT) +# define BQ2425X_NO_LOOP (0 << BQ2425X_LOOP_STATUS_SHIFT) +# define BQ2425X_VIN_DPM_LOOP (1 << BQ2425X_LOOP_STATUS_SHIFT) +# define BQ2425X_INP_CURR_LIM_LOOP (2 << BQ2425X_LOOP_STATUS_SHIFT) +# define BQ2425X_THERM_REG_LOOP (3 << BQ2425X_LOOP_STATUS_SHIFT) +#define BQ2425X_LOW_CHG (1 << 5) /* 0 = REG 4 defines current; 1 = Low curr 330mA */ +#define BQ2425X_DPDM_EN (1 << 4) /* Force D+/D- detection */ +#define BQ2425X_CE_STATUS (1 << 3) /* 0 = CE low ; 1 = CE high */ +#define BQ2425X_VIN_DPM_SHIFT 0 /* Sets the input VDPM level */ +#define BQ2425X_VIN_DPM_MASK (7 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4200MV (0 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4280MV (1 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4360MV (2 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4440MV (3 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4520MV (4 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4600MV (5 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4680MV (5 << BQ2425X_VIN_DPM_SHIFT) +# define BQ2425X_VIN_DPM_4760MV (5 << BQ2425X_VIN_DPM_SHIFT) + +/* REG 6 */ + +#define BQ2425X_2XTMR_EN (1 << 7) /* Timer slowed 2x when in thermal reg., Vin_dpm or DPPM */ +#define BQ2425X_TIMER_SHIFT 6 /* Safety timer time limit */ +#define BQ2425X_TIMER_MASK (3 << BQ2425X_TIMER_SHIFT) +# define BQ2425X_TIMER_0p74H (0 << BQ2425X_TIMER_SHIFT) /* 0.75 hour fast charge */ +# define BQ2425X_TIMER_6H (1 << BQ2425X_TIMER_SHIFT) /* 6 hour fast charge (default 01) */ +# define BQ2425X_TIMER_9H (2 << BQ2425X_TIMER_SHIFT) /* 9 hour fast charge */ +# define BQ2425X_TIMER_DISABLED (3 << BQ2425X_TIMER_SHIFT) /* Disable safety timers */ +#define BQ2425X_SYSOFF (1 << 4) /* 0 = SYSOFF disabled ; 1 = SYSOFF enabled */ +#define BQ2425X_TS_EN (1 << 3) /* 0 = TS function disabled ; 1 = TS function enabled */ +#define BQ2425X_TS_STATUS_SHIFT 0 /* TS Fault Mode */ +#define BQ2425X_TS_STATUS_MASK (7 << BQ2425X_TS_STATUS_SHIFT) +# define BQ2425X_TS_NORMAL (0 << BQ2425X_TS_STATUS_SHIFT) /* Normal, No TS fault */ +# define BQ2425X_TS_TEMP_HOT (1 << BQ2425X_TS_STATUS_SHIFT) /* TS_temp > T_hot */ +# define BQ2425X_TS_TEMP_WARM (2 << BQ2425X_TS_STATUS_SHIFT) /* T_warm < TS_temp < T_hot */ +# define BQ2425X_TS_TEMP_COOL (3 << BQ2425X_TS_STATUS_SHIFT) /* T_cold < TS_temp < T_cool*/ +# define BQ2425X_TS_TEMP_COLD (4 << BQ2425X_TS_STATUS_SHIFT) /* TS_temp < T_cold */ +# define BQ2425X_TS_TEMP_VERY_COLD (5 << BQ2425X_TS_STATUS_SHIFT) /* T_freeze < TS_temp < T_cold */ +# define BQ2425X_TS_TEMP_FREEZE (6 << BQ2425X_TS_STATUS_SHIFT) /* TS_temp < T_freeze */ +# define BQ2425X_TS_OPEN_DISABLED (7 << BQ2425X_TS_STATUS_SHIFT) /* TS open (TS disabled) */ + +/* REG 7 */ + +#define BQ2425X_VOLT_OVP_SHIFT 5 /* OVP voltage */ +#define BQ2425X_VOLT_OVP_MASK (7 << BQ2425X_VOLT_OVP_SHIFT) +# define BQ2425X_VOLT_OVP_6p0V (0 << BQ2425X_VOLT_OVP_SHIFT) /* 6.0V */ +# define BQ2425X_VOLT_OVP_6p5V (1 << BQ2425X_VOLT_OVP_SHIFT) /* 6.5V */ +# define BQ2425X_VOLT_OVP_7p0V (2 << BQ2425X_VOLT_OVP_SHIFT) /* 7.0V */ +# define BQ2425X_VOLT_OVP_8p0V (3 << BQ2425X_VOLT_OVP_SHIFT) /* 8.0V */ +# define BQ2425X_VOLT_OVP_9p0V (4 << BQ2425X_VOLT_OVP_SHIFT) /* 9.0V */ +# define BQ2425X_VOLT_OVP_9p5V (5 << BQ2425X_VOLT_OVP_SHIFT) /* 9.5V */ +# define BQ2425X_VOLT_OVP_10p0V (6 << BQ2425X_VOLT_OVP_SHIFT) /* 10.0V */ +# define BQ2425X_VOLT_OVP_10p5V (7 << BQ2425X_VOLT_OVP_SHIFT) /* 10.5V */ +#define BQ2425X_CLR_VDP (1 << 4) /* 0 = Keep D+ voltage ; 1 = Turn off D+ voltage */ +#define BQ2425X_FORCE_BAT_DET (1 << 3) /* Enter the battery detection routine */ +#define BQ2425X_FORCE_PTM (1 << 2) /* PTM mode enable */ + /* bit 1: reserved */ + /* bit 0: reserved */ + +#endif /* __DRIVERS_POWER_BQ2425X_H */ diff --git a/drivers/power/max1704x.c b/drivers/power/max1704x.c index 2df676fa6172a24fb188bb8b33e6539f5fa12d27..7fa3f850604e7e84cddd8d73d84d0c84e7d57a08 100644 --- a/drivers/power/max1704x.c +++ b/drivers/power/max1704x.c @@ -1,8 +1,8 @@ /**************************************************************************** * drivers/power/max1704x.c - * Lower half driver for MAX1704x battery charger + * Lower half driver for MAX1704x battery fuel gauge * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -54,12 +54,12 @@ #include #include -#include -#include +#include +#include /* This driver requires: * - * CONFIG_BATTERY - Upper half battery driver support + * CONFIG_BATTERY - Upper half battery gauge driver support * CONFIG_I2C - I2C support * CONFIG_I2C_MAX1704X - And the driver must be explictly selected. */ @@ -177,14 +177,14 @@ struct max1704x_dev_s { /* The common part of the battery driver visible to the upper-half driver */ - FAR const struct battery_operations_s *ops; /* Battery operations */ - sem_t batsem; /* Enforce mutually exclusive access */ + FAR const struct battery_gauge_operations_s *ops; /* Battery operations */ + sem_t batsem; /* Enforce mutually exclusive access */ /* Data fields specific to the lower half MAX1704x driver follow */ - FAR struct i2c_dev_s *i2c; /* I2C interface */ - uint8_t addr; /* I2C address */ - uint32_t frequency; /* I2C frequency */ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + uint32_t frequency; /* I2C frequency */ }; /**************************************************************************** @@ -208,16 +208,16 @@ static inline int max1704x_reset(FAR struct max1704x_dev_s *priv); /* Battery driver lower half methods */ -static int max1704x_state(struct battery_dev_s *dev, int *status); -static int max1704x_online(struct battery_dev_s *dev, bool *status); -static int max1704x_voltage(struct battery_dev_s *dev, b16_t *value); -static int max1704x_capacity(struct battery_dev_s *dev, b16_t *value); +static int max1704x_state(struct battery_gauge_dev_s *dev, int *status); +static int max1704x_online(struct battery_gauge_dev_s *dev, bool *status); +static int max1704x_voltage(struct battery_gauge_dev_s *dev, b16_t *value); +static int max1704x_capacity(struct battery_gauge_dev_s *dev, b16_t *value); /**************************************************************************** * Private Data ****************************************************************************/ -static const struct battery_operations_s g_max1704xops = +static const struct battery_gauge_operations_s g_max1704xops = { max1704x_state, max1704x_online, @@ -243,28 +243,31 @@ static const struct battery_operations_s g_max1704xops = static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, FAR uint16_t *regval) { + struct i2c_config_s config; uint8_t buffer[2]; int ret; - /* Set the I2C address and address size */ + /* Set up the configuration and perform the write-read operation */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; /* Write the register address */ - ret = I2C_WRITE(priv->i2c, ®addr, 1); + ret = i2c_write(priv->i2c, &config, ®addr, 1); if (ret < 0) { - batdbg("I2C_WRITE failed: %d\n", ret); + batdbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 16-bits from the register */ - ret = I2C_READ(priv->i2c, buffer, 2); + ret = i2c_read(priv->i2c, &config, buffer, 2); if (ret < 0) { - batdbg("I2C_READ failed: %d\n", ret); + batdbg("i2c_read failed: %d\n", ret); return ret; } @@ -286,6 +289,7 @@ static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, static int max1704x_putreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, uint16_t regval) { + struct i2c_config_s config; uint8_t buffer[3]; batdbg("addr: %02x regval: %08x\n", regaddr, regval); @@ -296,13 +300,15 @@ static int max1704x_putreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr, buffer[1] = (uint8_t)(regval >> 8); buffer[2] = (uint8_t)(regval & 0xff); - /* Set the I2C address and address size */ + /* Set up the configuration and perform the write-read operation */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; /* Write the register address followed by the data (no RESTART) */ - return I2C_WRITE(priv->i2c, buffer, 3); + return i2c_write(priv->i2c, &config, buffer, 3); } /**************************************************************************** @@ -410,7 +416,7 @@ static inline int max1704x_reset(FAR struct max1704x_dev_s *priv) * ****************************************************************************/ -static int max1704x_state(struct battery_dev_s *dev, int *status) +static int max1704x_state(struct battery_gauge_dev_s *dev, int *status) { FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev; b16_t soc = 0; @@ -454,7 +460,7 @@ static int max1704x_state(struct battery_dev_s *dev, int *status) * ****************************************************************************/ -static int max1704x_online(struct battery_dev_s *dev, bool *status) +static int max1704x_online(struct battery_gauge_dev_s *dev, bool *status) { /* There is no concept of online/offline in this driver */ @@ -470,7 +476,7 @@ static int max1704x_online(struct battery_dev_s *dev, bool *status) * ****************************************************************************/ -static int max1704x_voltage(struct battery_dev_s *dev, b16_t *value) +static int max1704x_voltage(struct battery_gauge_dev_s *dev, b16_t *value) { FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev; return max1704x_getvcell(priv, value); @@ -484,7 +490,7 @@ static int max1704x_voltage(struct battery_dev_s *dev, b16_t *value) * ****************************************************************************/ -static int max1704x_capacity(struct battery_dev_s *dev, b16_t *value) +static int max1704x_capacity(struct battery_gauge_dev_s *dev, b16_t *value) { FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev; return max1704x_getsoc(priv, value); @@ -520,8 +526,9 @@ static int max1704x_capacity(struct battery_dev_s *dev, b16_t *value) * ****************************************************************************/ -FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c, - uint8_t addr, uint32_t frequency) +FAR struct battery_gauge_dev_s *max1704x_initialize(FAR struct i2c_master_s *i2c, + uint8_t addr, + uint32_t frequency) { FAR struct max1704x_dev_s *priv; #if 0 @@ -541,10 +548,6 @@ FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c, priv->addr = addr; priv->frequency = frequency; - /* Set the I2C frequency (ignoring the returned, actual frequency) */ - - (void)I2C_SETFREQUENCY(i2c, priv->frequency); - /* Reset the MAX1704x (mostly just to make sure that we can talk to it) */ #if 0 @@ -557,7 +560,7 @@ FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c, } #endif } - return (FAR struct battery_dev_s *)priv; + return (FAR struct battery_gauge_dev_s *)priv; } #endif /* CONFIG_BATTERY && CONFIG_I2C && CONFIG_I2C_MAX1704X */ diff --git a/drivers/power/pm_internal.h b/drivers/power/pm.h similarity index 97% rename from drivers/power/pm_internal.h rename to drivers/power/pm.h index 6499c65eaf669ff2681489cad5df4b91dfa1e483..9df1ec5c0ccb3fd0966b7988c101a922d819c162 100644 --- a/drivers/power/pm_internal.h +++ b/drivers/power/pm.h @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/power/pm_internal.h + * drivers/power/pm * * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __DRIVERS_POWER_PM_INTERNAL_H -#define __DRIVERS_POWER_PM_INTERNAL_H +#ifndef __DRIVERS_POWER_PM_H +#define __DRIVERS_POWER_PM_H /**************************************************************************** * Included Files @@ -45,8 +45,9 @@ #include #include -#include +#include #include +#include #ifdef CONFIG_PM @@ -136,7 +137,7 @@ struct pm_global_s /* stime - The time (in ticks) at the start of the current time slice */ - uint32_t stime; + systime_t stime; /* This semaphore manages mutually exclusive access to the power management * registry. It must be initialized to the value 1. @@ -207,4 +208,4 @@ EXTERN void pm_update(int16_t accum); #endif #endif /* CONFIG_PM */ -#endif /* #define __DRIVERS_POWER_PM_INTERNAL_H */ +#endif /* #define __DRIVERS_POWER_PM_H */ diff --git a/drivers/power/pm_activity.c b/drivers/power/pm_activity.c index f6dceeea373b19d432cbdbad7aa4479155f47d2b..8394418000022a9ac75cad347b2b119a6b1d8f12 100644 --- a/drivers/power/pm_activity.c +++ b/drivers/power/pm_activity.c @@ -41,9 +41,9 @@ #include #include -#include +#include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -103,7 +103,7 @@ void pm_activity(int priority) { - uint32_t now; + systime_t now; uint32_t accum; irqstate_t flags; @@ -115,7 +115,7 @@ void pm_activity(int priority) { /* Add the priority to the accumulated counts in a critical section. */ - flags = irqsave(); + flags = enter_critical_section(); accum = (uint32_t)g_pmglobals.accum + priority; /* Make sure that we do not overflow the underlying uint16_t representation */ @@ -159,8 +159,9 @@ void pm_activity(int priority) (void)pm_update(tmp); } - irqrestore(flags); + leave_critical_section(flags); } } -#endif /* CONFIG_PM */ \ No newline at end of file +#endif /* CONFIG_PM */ + diff --git a/drivers/power/pm_changestate.c b/drivers/power/pm_changestate.c index f64760f55bf403e20524b2bd59a0ab0f940b10ba..271858710dd8334cd293e8eab768855be5639c2c 100644 --- a/drivers/power/pm_changestate.c +++ b/drivers/power/pm_changestate.c @@ -40,9 +40,9 @@ #include #include -#include +#include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -194,7 +194,7 @@ int pm_changestate(enum pm_state_e newstate) * re-enabled. */ - flags = irqsave(); + flags = enter_critical_section(); /* First, prepare the drivers for the state change. In this phase, * drivers may refuse the state state change. @@ -220,7 +220,7 @@ int pm_changestate(enum pm_state_e newstate) /* Restore the interrupt state */ - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/drivers/power/pm_checkstate.c b/drivers/power/pm_checkstate.c index 9b0e1045e714075f73934f7ef4c45ef7c5edc9de..7ec0f83b63d328b8fba6d8ce7731512adb137f29 100644 --- a/drivers/power/pm_checkstate.c +++ b/drivers/power/pm_checkstate.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/power/pm_checkstate.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,9 +41,9 @@ #include #include -#include +#include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -108,7 +108,7 @@ enum pm_state_e pm_checkstate(void) { - uint32_t now; + systime_t now; irqstate_t flags; /* Check for the end of the current time slice. This must be performed @@ -116,7 +116,7 @@ enum pm_state_e pm_checkstate(void) * logic in pm_activity(). */ - flags = irqsave(); + flags = enter_critical_section(); /* Check the elapsed time. In periods of low activity, time slicing is * controlled by IDLE loop polling; in periods of higher activity, time @@ -129,25 +129,26 @@ enum pm_state_e pm_checkstate(void) now = clock_systimer(); if (now - g_pmglobals.stime >= TIME_SLICE_TICKS) { - int16_t accum; + int16_t accum; - /* Sample the count, reset the time and count, and assess the PM - * state. This is an atomic operation because interrupts are - * still disabled. - */ + /* Sample the count, reset the time and count, and assess the PM + * state. This is an atomic operation because interrupts are + * still disabled. + */ - accum = g_pmglobals.accum; - g_pmglobals.stime = now; - g_pmglobals.accum = 0; + accum = g_pmglobals.accum; + g_pmglobals.stime = now; + g_pmglobals.accum = 0; - /* Reassessing the PM state may require some computation. However, - * the work will actually be performed on a worker thread at a user- - * controlled priority. - */ + /* Reassessing the PM state may require some computation. However, + * the work will actually be performed on a worker thread at a user- + * controlled priority. + */ - (void)pm_update(accum); + (void)pm_update(accum); } - irqrestore(flags); + + leave_critical_section(flags); /* Return the recommended state. Assuming that we are called from the * IDLE thread at the lowest priority level, any updates scheduled on the diff --git a/drivers/power/pm_initialize.c b/drivers/power/pm_initialize.c index b4f74587790a313ed1129fd3765fa8e9941062f8..298448974f6362024b343117eec1bf41fd0b5e22 100644 --- a/drivers/power/pm_initialize.c +++ b/drivers/power/pm_initialize.c @@ -43,7 +43,7 @@ #include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -109,4 +109,5 @@ void pm_initialize(void) sem_init(&g_pmglobals.regsem, 0, 1); } -#endif /* CONFIG_PM */ \ No newline at end of file +#endif /* CONFIG_PM */ + diff --git a/drivers/power/pm_register.c b/drivers/power/pm_register.c index 19f94cb0263857e836c523022487b60b6ee27ccc..f8776acee2b83c2561a8248751112a49978324d1 100644 --- a/drivers/power/pm_register.c +++ b/drivers/power/pm_register.c @@ -44,7 +44,7 @@ #include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -109,4 +109,5 @@ int pm_register(FAR struct pm_callback_s *callbacks) return ret; } -#endif /* CONFIG_PM */ \ No newline at end of file +#endif /* CONFIG_PM */ + diff --git a/drivers/power/pm_update.c b/drivers/power/pm_update.c index e705883f5b3ed077a95b208d1f6ca8e8e5528d76..1d5a64bfff33a9d038d91ad0208bbde821bbe9cc 100644 --- a/drivers/power/pm_update.c +++ b/drivers/power/pm_update.c @@ -44,7 +44,7 @@ #include #include -#include "pm_internal.h" +#include "pm.h" #ifdef CONFIG_PM @@ -328,7 +328,8 @@ void pm_update(int16_t accum) /* The work will be performed on the worker thread */ DEBUGASSERT(g_pmglobals.work.worker == NULL); - (void)work_queue(HPWORK, &g_pmglobals.work, pm_worker, (FAR void*)((intptr_t)accum), 0); + (void)work_queue(HPWORK, &g_pmglobals.work, pm_worker, + (FAR void *)((intptr_t)accum), 0); } #endif /* CONFIG_PM */ diff --git a/drivers/pwm.c b/drivers/pwm.c index 3151a578625c818a4d32d9766b5804eb9c6e3c9d..b07e44ae2cf4c56a1256e555927dacde68f036ab 100644 --- a/drivers/pwm.c +++ b/drivers/pwm.c @@ -60,7 +60,7 @@ #include #include -#include +#include #ifdef CONFIG_PWM @@ -107,11 +107,17 @@ struct pwm_upperhalf_s * Private Function Prototypes ****************************************************************************/ +static void pwm_dump(FAR const char *msg, + FAR const struct pwm_info_s *info, + bool started); static int pwm_open(FAR struct file *filep); static int pwm_close(FAR struct file *filep); -static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen); -static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); -static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags); +static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int pwm_start(FAR struct pwm_upperhalf_s *upper, + unsigned int oflags); static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg); /**************************************************************************** @@ -135,13 +141,43 @@ static const struct file_operations g_pwmops = * Private Functions ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** + * Name: pwm_dump + ****************************************************************************/ + +static void pwm_dump(FAR const char *msg, FAR const struct pwm_info_s *info, + bool started) +{ +#ifdef CONFIG_PWM_MULTICHAN + int i; +#endif + + pwmvdbg("%s: frequency: %d", msg, info->frequency); + +#ifdef CONFIG_PWM_MULTICHAN + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + pwmvdbg(" channel: %d duty: %08x", + info->channels[i].channel, info->channels[i].duty); + } +#else + pwmvdbg(" duty: %08x", info->duty); +#endif + +#ifdef CONFIG_PWM_PULSECOUNT + pwmvdbg(" count: %d\n", info->count); +#endif + + pwmvdbg(" started: %d\n", started); +} + +/**************************************************************************** * Name: pwm_open * * Description: * This function is called whenever the PWM device is opened. * - ************************************************************************************/ + ****************************************************************************/ static int pwm_open(FAR struct file *filep) { @@ -205,13 +241,13 @@ errout: return ret; } -/************************************************************************************ +/**************************************************************************** * Name: pwm_close * * Description: * This function is called when the PWM device is closed. * - ************************************************************************************/ + ****************************************************************************/ static int pwm_close(FAR struct file *filep) { @@ -262,41 +298,43 @@ errout: return ret; } -/************************************************************************************ +/**************************************************************************** * Name: pwm_read * * Description: * A dummy read method. This is provided only to satisfy the VFS layer. * - ************************************************************************************/ + ****************************************************************************/ -static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) { /* Return zero -- usually meaning end-of-file */ return 0; } -/************************************************************************************ +/**************************************************************************** * Name: pwm_write * * Description: * A dummy write method. This is provided only to satisfy the VFS layer. * - ************************************************************************************/ + ****************************************************************************/ -static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) { return 0; } -/************************************************************************************ +/**************************************************************************** * Name: pwm_start * * Description: * Handle the PWMIOC_START ioctl command * - ************************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_PWM_PULSECOUNT static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) @@ -313,7 +351,7 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) { /* Disable interrupts to avoid race conditions */ - flags = irqsave(); + flags = enter_critical_section(); /* Indicate that if will be waiting for the pulse count to complete. * Note that we will only wait if a non-zero pulse count is specified @@ -360,7 +398,7 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) upper->waiting = false; } - irqrestore(flags); + leave_critical_section(flags); } return ret; @@ -397,13 +435,13 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) } #endif -/************************************************************************************ +/**************************************************************************** * Name: pwm_ioctl * * Description: * The standard ioctl method. This is where ALL of the PWM work is done. * - ************************************************************************************/ + ****************************************************************************/ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { @@ -438,16 +476,10 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case PWMIOC_SETCHARACTERISTICS: { - FAR const struct pwm_info_s *info = (FAR const struct pwm_info_s*)((uintptr_t)arg); + FAR const struct pwm_info_s *info = (FAR const struct pwm_info_s *)((uintptr_t)arg); DEBUGASSERT(info != NULL && lower->ops->start != NULL); -#ifdef CONFIG_PWM_PULSECOUNT - pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x count: %d started: %d\n", - info->frequency, info->duty, info->count, upper->started); -#else - pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x started: %d\n", - info->frequency, info->duty, upper->started); -#endif + pwm_dump("PWMIOC_SETCHARACTERISTICS", info, upper->started); /* Save the pulse train characteristics */ @@ -475,18 +507,12 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case PWMIOC_GETCHARACTERISTICS: { - FAR struct pwm_info_s *info = (FAR struct pwm_info_s*)((uintptr_t)arg); + FAR struct pwm_info_s *info = (FAR struct pwm_info_s *)((uintptr_t)arg); DEBUGASSERT(info != NULL); memcpy(info, &upper->info, sizeof(struct pwm_info_s)); -#ifdef CONFIG_PWM_PULSECOUNT - pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x count: %d\n", - info->frequency, info->duty, info->count); -#else - pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x\n", - info->frequency, info->duty); -#endif + pwm_dump("PWMIOC_GETCHARACTERISTICS", info, upper->started); } break; @@ -498,14 +524,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case PWMIOC_START: { -#ifdef CONFIG_PWM_PULSECOUNT - pwmvdbg("PWMIOC_START frequency: %d duty: %08x count: %d started: %d\n", - upper->info.frequency, upper->info.duty, upper->info.count, - upper->started); -#else - pwmvdbg("PWMIOC_START frequency: %d duty: %08x started: %d\n", - upper->info.frequency, upper->info.duty, upper->started); -#endif + pwm_dump("PWMIOC_START", &upper->info, upper->started); DEBUGASSERT(lower->ops->start != NULL); /* Start the pulse train */ @@ -531,7 +550,7 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_PWM_PULSECOUNT if (upper->waiting) { - upper->waiting = FALSE; + upper->waiting = false; } #endif } diff --git a/drivers/ramdisk.c b/drivers/ramdisk.c index 39fbc8d807c45244bdab02803bbd0e2ab22b0924..09382dadd679f0cbba163587a61595c02bce548f 100644 --- a/drivers/ramdisk.c +++ b/drivers/ramdisk.c @@ -441,10 +441,10 @@ static int rd_unlink(FAR struct inode *inode) ****************************************************************************/ #ifdef CONFIG_FS_WRITABLE -int ramdisk_register(int minor, uint8_t *buffer, uint32_t nsectors, +int ramdisk_register(int minor, FAR uint8_t *buffer, uint32_t nsectors, uint16_t sectsize, uint8_t rdflags) #else -int romdisk_register(int minor, uint8_t *buffer, uint32_t nsectors, +int romdisk_register(int minor, FAR const uint8_t *buffer, uint32_t nsectors, uint16_t sectsize) #endif { diff --git a/drivers/rwbuffer.c b/drivers/rwbuffer.c index fd2f73c77ae08ec259ae29871d91d644256c31ab..764a6ebbc1aaf04b6e560b0f21e2ab524791866c 100644 --- a/drivers/rwbuffer.c +++ b/drivers/rwbuffer.c @@ -75,11 +75,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -96,7 +96,7 @@ static void rwb_semtake(sem_t *sem) while (sem_wait(sem) != 0) { - /* The only case that an error should occr here is if + /* The only case that an error should occur here is if * the wait was awakened by a signal. */ @@ -117,8 +117,8 @@ static void rwb_semtake(sem_t *sem) static inline bool rwb_overlap(off_t blockstart1, size_t nblocks1, off_t blockstart2, size_t nblocks2) { - off_t blockend1 = blockstart1 + nblocks1; - off_t blockend2 = blockstart2 + nblocks2; + off_t blockend1 = blockstart1 + nblocks1 - 1; + off_t blockend2 = blockstart2 + nblocks2 - 1; /* If the buffer 1 is wholly outside of buffer 2, return false */ @@ -257,7 +257,7 @@ static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb, /* Flush the write buffer */ - ret = rwb->wrflush(rwb, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks); + ret = rwb->wrflush(rwb->dev, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks); if (ret < 0) { fdbg("ERROR: Error writing multiple from cache: %d\n", -ret); @@ -561,7 +561,7 @@ int rwb_invalidate_readahead(FAR struct rwbuffer_s *rwb, rhbend = rwb->rhblockstart + rwb->rhnblocks; invend = startblock + blockcount; - if (rhbend <= startblock || rwb->rhblockstart >= invend ) + if (rhbend <= startblock || rwb->rhblockstart >= invend) { ret = OK; } @@ -640,7 +640,7 @@ int rwb_initialize(FAR struct rwbuffer_s *rwb) /* Setup so that rwb_uninitialize can handle a failure */ #ifdef CONFIG_DRVR_WRITEBUFFER - DEBUGASSERT(rwb->wrflush!= NULL); + DEBUGASSERT(rwb->wrflush != NULL); rwb->wrbuffer = NULL; #endif #ifdef CONFIG_DRVR_READAHEAD @@ -747,10 +747,10 @@ void rwb_uninitialize(FAR struct rwbuffer_s *rwb) * Name: rwb_read ****************************************************************************/ -int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, - FAR uint8_t *rdbuffer) +ssize_t rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, + size_t nblocks, FAR uint8_t *rdbuffer) { - uint32_t remaining; + size_t remaining; int ret = OK; fvdbg("startblock=%ld nblocks=%ld rdbuffer=%p\n", @@ -785,7 +785,7 @@ int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, /* Loop until we have read all of the requested blocks */ rwb_semtake(&rwb->rhsem); - for (remaining = nblocks; remaining > 0;) + for (remaining = nblocks; remaining > 0; ) { /* Is there anything in the read-ahead buffer? */ @@ -822,7 +822,7 @@ int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, if (ret < 0) { fdbg("ERROR: Failed to fill the read-ahead buffer: %d\n", ret); - return ret; + return (ssize_t)ret; } } } @@ -842,19 +842,19 @@ int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks, * the user buffer. */ - ret = rwb->rhreload(rwb->dev, startblock, nblocks, rdbuffer); + ret = rwb->rhreload(rwb->dev, rdbuffer, startblock, nblocks); } #endif - return ret; + return (ssize_t)ret; } /**************************************************************************** * Name: rwb_write ****************************************************************************/ -int rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock, - size_t nblocks, FAR const uint8_t *wrbuffer) +ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock, + size_t nblocks, FAR const uint8_t *wrbuffer) { int ret = OK; @@ -917,10 +917,9 @@ int rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock, ret = rwb->wrflush(rwb->dev, wrbuffer, startblock, nblocks); } - #endif - return ret; + return (ssize_t)ret; } /**************************************************************************** diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 19bdedae26df978f8db42e24971d2646e1adb567..c73e1abae06a96584f1b21b98b80f478caab7f85 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -7,6 +7,7 @@ config AS5048B bool "AMS AS5048B Magnetic Rotary Encoder support" default n select I2C + select QENCODER ---help--- Enable driver support for the AMS AS5048B magnetic rotary encoder. @@ -22,6 +23,68 @@ config LIS331DL default n select I2C +config LIS331DL_I2C_FREQUENCY + int "LIS331DL I2C frequency" + default 100000 + range 1 100000 + depends on LIS331DL + +config SN_LSM9DS1 + bool "STMicro LSM9DS1 support" + default n + depends on I2C + ---help--- + Enable driver support for the STMicro LSM9DS1. + +config LSM9DS1_I2C_FREQUENCY + int "LSM9DS1 I2C frequency" + default 400000 + range 1 400000 + depends on SN_LSM9DS1 + +config MB7040 + bool "MaxBotix MB7040 Sonar support" + default n + select I2C + ---help--- + Enable driver support for the MaxBotix MB7040 sonar. + +config MB7040_I2C_FREQUENCY + int "MB7040 I2C frequency" + default 400000 + range 1 400000 + depends on MB7040 + +config MCP9844 + bool "MCP9844 Temperature Sensor" + default n + select I2C + ---help--- + Enable driver support for the MCP9844 I2C Temperature sensor. + +config MCP9844_I2C_FREQUENCY + int "MCP9844 I2C frequency" + default 400000 + range 1 400000 + depends on MCP9844 + +config MS58XX + bool "MEAS MS58XX Altimeter support" + default n + select I2C + ---help--- + Enable driver support for MEAS MS58XX altimeters. + +config MS58XX_I2C_FREQUENCY + int "MS58XX I2C frequency" + default 400000 + range 1 400000 + depends on MS58XX + +config MS58XX_VDD + int "MEAS MS58XX VDD" + default 30 + config MPL115A bool "Freescale MPL115A Barometer Sensor support" default n @@ -72,6 +135,20 @@ config ADXL345_REGDEBUG endif # SENSORS_ADXL345 +config MAX31855 + bool "Maxim MAX31855 Driver" + default n + select SPI + ---help--- + Enables support for the MAX31855 driver + +config MAX6675 + bool "Maxim MAX6675 Driver" + default n + select SPI + ---help--- + Enables support for the MAX6675 driver + config I2C_LM75 bool default y if LM75 @@ -86,6 +163,12 @@ config LM75 This should also work with compatible temperature sensors such as the TI TMP100/101. +config LM75_I2C_FREQUENCY + int "LM75 I2C frequency" + default 100000 + range 1 100000 + depends on I2C_LM75 + config LM92 bool "TI LM92 Temperature Sensor support" default n @@ -93,6 +176,16 @@ config LM92 ---help--- Enable driver support for the TI LM92 Temperature Sensor. +config LM92_I2C_FREQUENCY + int "LM92 I2C frequency" + default 400000 + range 1 400000 + depends on LM92 + config QENCODER bool "Qencoder" default n + +config ZEROCROSS + bool "Zero Cross Sensor" + default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index 0d86e8e9f7a6e2e40bd6057a9b59a39cf283d8b7..ca0912d09527d1f9a5f7e0dd8439e1ed746f0091 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/sensors/Make.defs # -# Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2015-2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -53,6 +53,10 @@ ifeq ($(CONFIG_LIS331DL),y) CSRCS += lis331dl.c endif +ifeq ($(CONFIG_SN_LSM9DS1),y) + CSRCS += lsm9ds1.c +endif + ifeq ($(CONFIG_ADXL345_I2C),y) CSRCS += adxl345_i2c.c endif @@ -69,6 +73,18 @@ ifeq ($(CONFIG_LM92),y) CSRCS += lm92.c endif +ifeq ($(CONFIG_MB7040),y) + CSRCS += mb7040.c +endif + +ifeq ($(CONFIG_MCP9844),y) + CSRCS += mcp9844.c +endif + +ifeq ($(CONFIG_MS58XX),y) + CSRCS += ms58xx.c +endif + endif # CONFIG_I2C # These drivers depend on SPI support @@ -78,6 +94,14 @@ ifeq ($(CONFIG_ADXL345_SPI),y) CSRCS += adxl345_spi.c endif +ifeq ($(CONFIG_MAX31855),y) + CSRCS += max31855.c +endif + +ifeq ($(CONFIG_MAX6675),y) + CSRCS += max6675.c +endif + ifeq ($(CONFIG_MPL115A),y) CSRCS += mpl115a.c endif @@ -89,6 +113,12 @@ ifeq ($(CONFIG_QENCODER),y) CSRCS += qencoder.c endif +# Zero Cross upper half + +ifeq ($(CONFIG_ZEROCROSS),y) + CSRCS += zerocross.c +endif + # Include sensor driver build support DEPPATH += --dep-path sensors diff --git a/drivers/sensors/adxl345.h b/drivers/sensors/adxl345.h index 9a87e9e131f543d03eab88f48587c5e8bff93f72..e91fc6b07448c22dd8848f4ee59eb39bac461832 100644 --- a/drivers/sensors/adxl345.h +++ b/drivers/sensors/adxl345.h @@ -120,7 +120,7 @@ struct adxl345_dev_s #ifdef CONFIG_ADXL345_SPI FAR struct spi_dev_s *spi; /* Saved SPI driver instance */ #else - FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */ + FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */ #endif uint8_t status; /* See ADXL345_STAT_* definitions */ diff --git a/drivers/sensors/adxl345_base.c b/drivers/sensors/adxl345_base.c index d761702a3394ab6e9dffee554c4285d8997d5b86..4cf667807d82d57a0a3d4b87b4b9f897a2327f3b 100644 --- a/drivers/sensors/adxl345_base.c +++ b/drivers/sensors/adxl345_base.c @@ -384,7 +384,7 @@ static void adxl345_reset(FAR struct adxl345_dev_s *priv) ADXL345_HANDLE adxl345_instantiate(FAR struct spi_dev_s *dev, FAR struct adxl345_config_s *config) #else -ADXL345_HANDLE adxl345_instantiate(FAR struct i2c_dev_s *dev, +ADXL345_HANDLE adxl345_instantiate(FAR struct i2c_master_s *dev, FAR struct adxl345_config_s *config) #endif { @@ -409,29 +409,8 @@ ADXL345_HANDLE adxl345_instantiate(FAR struct i2c_dev_s *dev, #ifdef CONFIG_ADXL345_SPI priv->spi = dev; - /* If this SPI bus is not shared, then we can config it now. - * If it is shared, then other device could change our config, - * then just configure before sending data. - */ - -#ifdef CONFIG_SPI_OWNBUS - /* Configure SPI for the ADXL345 */ - - SPI_SETMODE(priv->spi, SPIDEV_MODE3); - SPI_SETBITS(priv->spi, 8); - SPI_SETFREQUENCY(priv->spi, ADXL345_SPI_MAXFREQUENCY); -#endif - #else priv->i2c = dev; - - /* Set the I2C address and frequency. REVISIT: This logic would be - * insufficient if we share the I2C bus with any other devices that also - * modify the address and frequency. - */ - - I2C_SETADDRESS(dev, config->address, 7); - I2C_SETFREQUENCY(dev, config->frequency); #endif /* Read and verify the ADXL345 device ID */ diff --git a/drivers/sensors/adxl345_i2c.c b/drivers/sensors/adxl345_i2c.c index fb2c786135354f07c79aebe0f577334b3bd705df..a2dfd819610cbfc1e063ae0e271a3bbe9e4a1b13 100644 --- a/drivers/sensors/adxl345_i2c.c +++ b/drivers/sensors/adxl345_i2c.c @@ -46,6 +46,7 @@ #include #include +#include #include #include "adxl345.h" @@ -75,19 +76,21 @@ uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* Setup 8-bit ADXL345 address write message */ - msg[0].addr = priv->config->address; /* 7-bit address */ - msg[0].flags = 0; /* Write transaction, beginning with START */ - msg[0].buffer = ®addr; /* Transfer from this address */ - msg[0].length = 1; /* Send one byte following the address - * (no STOP) */ + msg[0].frequency = priv->config->frequency; /* I2C frequency */ + msg[0].addr = priv->config->address; /* 7-bit address */ + msg[0].flags = 0; /* Write transaction, beginning with START */ + msg[0].buffer = ®addr; /* Transfer from this address */ + msg[0].length = 1; /* Send one byte following the address + * (no STOP) */ /* Set up the 8-bit ADXL345 data read message */ - msg[1].addr = priv->config->address; /* 7-bit address */ - msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ - msg[1].buffer = ®val; /* Transfer to this address */ - msg[1].length = 1; /* Receive one byte following the address - * (then STOP) */ + msg[1].frequency = priv->config->frequency; /* I2C frequency */ + msg[1].addr = priv->config->address; /* 7-bit address */ + msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ + msg[1].buffer = ®val; /* Transfer to this address */ + msg[1].length = 1; /* Receive one byte following the address + * (then STOP) */ /* Perform the transfer */ @@ -139,11 +142,12 @@ void adxl345_putreg8(FAR struct adxl345_dev_s *priv, /* Setup 8-bit ADXL345 address write message */ - msg.addr = priv->config->address; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = txbuffer; /* Transfer from this address */ - msg.length = 2; /* Send two byte following the address - * (then STOP) */ + msg.frequency = priv->config->frequency; /* I2C frequency */ + msg.addr = priv->config->address; /* 7-bit address */ + msg.flags = 0; /* Write transaction, beginning with START */ + msg.buffer = txbuffer; /* Transfer from this address */ + msg.length = 2; /* Send two byte following the address + * (then STOP) */ /* Perform the transfer */ @@ -179,19 +183,21 @@ uint16_t adxl345_getreg16(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* Setup 8-bit ADXL345 address write message */ - msg[0].addr = priv->config->address; /* 7-bit address */ - msg[0].flags = 0; /* Write transaction, beginning with START */ - msg[0].buffer = ®addr; /* Transfer from this address */ - msg[0].length = 1; /* Send one byte following the address - * (no STOP) */ + msg[0].frequency = priv->config->frequency; /* I2C frequency */ + msg[0].addr = priv->config->address; /* 7-bit address */ + msg[0].flags = 0; /* Write transaction, beginning with START */ + msg[0].buffer = ®addr; /* Transfer from this address */ + msg[0].length = 1; /* Send one byte following the address + * (no STOP) */ /* Set up the 8-bit ADXL345 data read message */ - msg[1].addr = priv->config->address; /* 7-bit address */ - msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ - msg[1].buffer = rxbuffer; /* Transfer to this address */ - msg[1].length = 2; /* Receive two bytes following the address - * (then STOP) */ + msg[1].frequency = priv->config->frequency; /* I2C frequency */ + msg[1].addr = priv->config->address; /* 7-bit address */ + msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ + msg[1].buffer = rxbuffer; /* Transfer to this address */ + msg[1].length = 2; /* Receive two bytes following the address + * (then STOP) */ /* Perform the transfer */ diff --git a/drivers/sensors/adxl345_spi.c b/drivers/sensors/adxl345_spi.c index 2f3b4894fbc1807c7a7af8a30cad6316f42b3e64..1e837132af17807c44448dc1e9ea983f261bd196 100644 --- a/drivers/sensors/adxl345_spi.c +++ b/drivers/sensors/adxl345_spi.c @@ -46,6 +46,7 @@ #include #include +#include #include #include "adxl345.h" @@ -63,16 +64,15 @@ * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void adxl345_configspi(FAR struct spi_dev_s *spi) { /* Configure SPI for the ADXL345 */ SPI_SETMODE(spi, SPIDEV_MODE3); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, ADXL345_SPI_MAXFREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, ADXL345_SPI_MAXFREQUENCY); } -#endif /**************************************************************************** * Public Functions @@ -92,15 +92,13 @@ uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* If SPI bus is shared then lock and configure it */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, true); adxl345_configspi(priv->spi); -#endif /* Select the ADXL345 */ SPI_SELECT(priv->spi, SPIDEV_ACCELEROMETER, true); - + /* Send register to read and get the next byte */ (void)SPI_SEND(priv->spi, regaddr); @@ -112,9 +110,7 @@ uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* Unlock bus */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, false); -#endif #ifdef CONFIG_ADXL345_REGDEBUG dbg("%02x->%02x\n", regaddr, regval); @@ -139,15 +135,13 @@ void adxl345_putreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr, /* If SPI bus is shared then lock and configure it */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, true); adxl345_configspi(priv->spi); -#endif /* Select the ADXL345 */ SPI_SELECT(priv->spi, SPIDEV_ACCELEROMETER, true); - + /* Send register address and set the value */ (void)SPI_SEND(priv->spi, regaddr); @@ -158,9 +152,8 @@ void adxl345_putreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr, SPI_SELECT(priv->spi, SPIDEV_ACCELEROMETER, false); /* Unlock bus */ -#ifndef CONFIG_SPI_OWNBUS + (void)SPI_LOCK(priv->spi, false); -#endif } /**************************************************************************** @@ -177,15 +170,13 @@ uint16_t adxl345_getreg16(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* If SPI bus is shared then lock and configure it */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, true); adxl345_configspi(priv->spi); -#endif /* Select the ADXL345 */ SPI_SELECT(priv->spi, SPIDEV_ACCELEROMETER, true); - + /* Send register to read and get the next 2 bytes */ (void)SPI_SEND(priv->spi, regaddr); @@ -197,9 +188,7 @@ uint16_t adxl345_getreg16(FAR struct adxl345_dev_s *priv, uint8_t regaddr) /* Unlock bus */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, false); -#endif #ifdef CONFIG_ADXL345_REGDEBUG dbg("%02x->%04x\n", regaddr, regval); diff --git a/drivers/sensors/as5048b.c b/drivers/sensors/as5048b.c index ffa96a47f210e2fdab9185f35c00b742c973ded7..96b3d4d19fdcb73362846256d2b2a70e62b6d993 100644 --- a/drivers/sensors/as5048b.c +++ b/drivers/sensors/as5048b.c @@ -2,8 +2,11 @@ * drivers/sensors/as5048b.c * Character driver for the AMS AS5048B Magnetic Rotary Encoder * - * Copyright (C) 2015 Alexandru Duru. All rights reserved. - * Author: Alexandru Duru + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,10 +49,10 @@ #include #include -#include +#include #include -#if defined(CONFIG_I2C) && defined(CONFIG_AS5048B) +#if defined(CONFIG_I2C) && defined(CONFIG_QENCODER) && defined(CONFIG_AS5048B) /**************************************************************************** * Private Types @@ -57,8 +60,9 @@ struct as5048b_dev_s { - FAR struct i2c_dev_s *i2c; /* I2C interface */ - uint8_t addr; /* I2C address */ + struct qe_lowerhalf_s lower; /* AS5048B quadrature encoder lower half */ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ }; /**************************************************************************** @@ -66,13 +70,13 @@ struct as5048b_dev_s ****************************************************************************/ /* I2C Helpers */ -static int as5048b_readb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, +static int as5048b_readu8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, FAR uint8_t *regval); -static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, +static int as5048b_readu16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, uint8_t regaddrlo, FAR uint16_t *regval); -static int as5048b_writeb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, +static int as5048b_writeu8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, uint8_t regval); -static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, +static int as5048b_writeu16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, uint8_t regaddrlo, uint16_t regval); static int as5048b_readzero(FAR struct as5048b_dev_s *priv, FAR uint16_t *zero); @@ -85,33 +89,25 @@ static int as5048b_readang(FAR struct as5048b_dev_s *priv, FAR uint16_t *ang); /* Character Driver Methods */ -static int as5048b_open(FAR struct file *filep); -static int as5048b_close(FAR struct file *filep); -static ssize_t as5048b_read(FAR struct file *filep, FAR char *buffer, - size_t buflen); -static ssize_t as5048b_write(FAR struct file *filep, FAR const char *buffer, - size_t buflen); -static int as5048b_ioctl(FAR struct file *filep, int cmd, - unsigned long arg); +static int as5048b_setup(FAR struct qe_lowerhalf_s *lower); +static int as5048b_shutdown(FAR struct qe_lowerhalf_s *lower); +static int as5048b_position(FAR struct qe_lowerhalf_s *lower, + FAR int32_t *pos); +static int as5048b_reset(FAR struct qe_lowerhalf_s *lower); +static int as5048b_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, + unsigned long arg); /**************************************************************************** * Private Data ****************************************************************************/ -static const struct file_operations g_as5048bfops = +static const struct qe_ops_s g_qeops = { - as5048b_open, - as5048b_close, - as5048b_read, - as5048b_write, - NULL, + as5048b_setup, + as5048b_shutdown, + as5048b_position, + as5048b_reset, as5048b_ioctl -#ifndef CONFIG_DISABLE_POLL - , NULL -#endif -#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS - , NULL -#endif }; /**************************************************************************** @@ -119,52 +115,56 @@ static const struct file_operations g_as5048bfops = ****************************************************************************/ /**************************************************************************** - * Name: as5048b_readb8 + * Name: as5048b_readu8 * * Description: * Read from an 8-bit register * ****************************************************************************/ -static int as5048b_readb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, +static int as5048b_readu8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, FAR uint8_t *regval) { - uint8_t buffer; int ret; + struct i2c_config_s config; + + /* Set up the I2C configuration */ + + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; /* Write the register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - ret = I2C_WRITE(priv->i2c, ®addr, sizeof(regaddr)); + ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr)); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 8 bits from the register */ - ret = I2C_READ(priv->i2c, &buffer, sizeof(buffer)); + ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval)); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } - *regval = buffer; sndbg("addr: %02x value: %02x ret: %d\n", regaddr, *regval, ret); return ret; } /**************************************************************************** - * Name: as5048b_readb16 + * Name: as5048b_readu16 * * Description: * Read from two 8-bit registers * ****************************************************************************/ -static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, +static int as5048b_readu16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, uint8_t regaddrlo, FAR uint16_t *regval) { uint8_t hi, lo; @@ -172,19 +172,19 @@ static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, /* Read the high 8 bits of the 13-bit value */ - ret = as5048b_readb8(priv, regaddrhi, &hi); + ret = as5048b_readu8(priv, regaddrhi, &hi); if (ret < 0) { - sndbg("as5048b_readb8 failed: %d\n", ret); + sndbg("as5048b_readu8 failed: %d\n", ret); return ret; } /* Read the low 5 bits of the 13-bit value */ - ret = as5048b_readb8(priv, regaddrlo, &lo); + ret = as5048b_readu8(priv, regaddrlo, &lo); if (ret < 0) { - sndbg("as5048b_readb8 failed: %d\n", ret); + sndbg("as5048b_readu8 failed: %d\n", ret); return ret; } @@ -195,21 +195,28 @@ static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, } /**************************************************************************** - * Name: as5048b_writeb8 + * Name: as5048b_writeu8 * * Description: * Write from an 8-bit register * ****************************************************************************/ -static int as5048b_writeb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, +static int as5048b_writeu8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, uint8_t regval) { + struct i2c_config_s config; uint8_t buffer[2]; - int ret; + int ret; sndbg("addr: %02x value: %02x\n", regaddr, regval); + /* Set up the I2C configuration */ + + config.frequency = priv->frequency; + config.address = priv->addr; + config.addrlen = 7; + /* Set up a 2-byte message to send */ buffer[0] = regaddr; @@ -217,25 +224,24 @@ static int as5048b_writeb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, /* Write the register address followed by the data (no RESTART) */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - ret = I2C_WRITE(priv->i2c, buffer, sizeof(buffer)); + ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer)); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); } return ret; } /**************************************************************************** - * Name: as5048b_writeb16 + * Name: as5048b_writeu16 * * Description: * Write to two 8-bit registers * ****************************************************************************/ -static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, +static int as5048b_writeu16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, uint8_t regaddrlo, uint16_t regval) { int ret; @@ -245,19 +251,19 @@ static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, /* Write the high 8 bits of the 13-bit value */ - ret = as5048b_writeb8(priv, regaddrhi, (uint8_t)(regval >> 6)); + ret = as5048b_writeu8(priv, regaddrhi, (uint8_t)(regval >> 6)); if (ret < 0) { - sndbg("as5048b_writeb8 failed: %d\n", ret); + sndbg("as5048b_writeu8 failed: %d\n", ret); return ret; } /* Write the low 5 bits of the 13-bit value */ - ret = as5048b_writeb8(priv, regaddrhi, (uint8_t)regval); + ret = as5048b_writeu8(priv, regaddrhi, (uint8_t)regval); if (ret < 0) { - sndbg("as5048b_writeb8 failed: %d\n", ret); + sndbg("as5048b_writeu8 failed: %d\n", ret); } return ret; @@ -274,18 +280,15 @@ static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, static int as5048b_readzero(FAR struct as5048b_dev_s *priv, FAR uint16_t *zero) { - uint16_t buffer; int ret; - ret = as5048b_readb16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, - &buffer); + ret = as5048b_readu16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, zero); if (ret < 0) { - sndbg("as5048b_readb16 failed: %d\n", ret); + sndbg("as5048b_readu16 failed: %d\n", ret); return ret; } - *zero = buffer; sndbg("zero: %04x ret: %d\n", *zero, ret); return ret; } @@ -304,10 +307,10 @@ static int as5048b_writezero(FAR struct as5048b_dev_s *priv, uint16_t zero) sndbg("zero: %04x\n", zero); - ret = as5048b_writeb16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, zero); + ret = as5048b_writeu16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, zero); if (ret < 0) { - sndbg("as5048b_writeb16 failed: %d\n", ret); + sndbg("as5048b_writeu16 failed: %d\n", ret); } return ret; @@ -323,17 +326,15 @@ static int as5048b_writezero(FAR struct as5048b_dev_s *priv, uint16_t zero) static int as5048b_readagc(FAR struct as5048b_dev_s *priv, FAR uint8_t *agc) { - uint8_t buffer; int ret; - ret = as5048b_readb8(priv, AS5048B_AGC_REG, &buffer); + ret = as5048b_readu8(priv, AS5048B_AGC_REG, agc); if (ret < 0) { - sndbg("as5048b_readb8 failed: %d\n", ret); + sndbg("as5048b_readu8 failed: %d\n", ret); return ret; } - *agc = buffer; sndbg("agc: %02x ret: %d\n", *agc, ret); return ret; } @@ -348,17 +349,15 @@ static int as5048b_readagc(FAR struct as5048b_dev_s *priv, FAR uint8_t *agc) static int as5048b_readdiag(FAR struct as5048b_dev_s *priv, FAR uint8_t *diag) { - uint8_t buffer; int ret; - ret = as5048b_readb8(priv, AS5048B_DIAG_REG, &buffer); + ret = as5048b_readu8(priv, AS5048B_DIAG_REG, diag); if (ret < 0) { - sndbg("as5048b_readb8 failed: %d\n", ret); + sndbg("as5048b_readu8 failed: %d\n", ret); return ret; } - *diag = buffer; sndbg("diag: %02x ret: %d\n", *diag, ret); return ret; } @@ -373,17 +372,15 @@ static int as5048b_readdiag(FAR struct as5048b_dev_s *priv, FAR uint8_t *diag) static int as5048b_readmag(FAR struct as5048b_dev_s *priv, FAR uint16_t *mag) { - uint16_t buffer; int ret; - ret = as5048b_readb16(priv, AS5048B_MAGHI_REG, AS5048B_MAGLO_REG, &buffer); + ret = as5048b_readu16(priv, AS5048B_MAGHI_REG, AS5048B_MAGLO_REG, mag); if (ret < 0) { - sndbg("as5048b_readb16 failed: %d\n", ret); + sndbg("as5048b_readu16 failed: %d\n", ret); return ret; } - *mag = buffer; sndbg("mag: %04x ret: %d\n", *mag, ret); return ret; } @@ -398,135 +395,142 @@ static int as5048b_readmag(FAR struct as5048b_dev_s *priv, FAR uint16_t *mag) static int as5048b_readang(FAR struct as5048b_dev_s *priv, FAR uint16_t *ang) { - uint16_t buffer; int ret; - ret = as5048b_readb16(priv, AS5048B_ANGHI_REG, AS5048B_ANGLO_REG, &buffer); + ret = as5048b_readu16(priv, AS5048B_ANGHI_REG, AS5048B_ANGLO_REG, ang); if (ret < 0) { - sndbg("as5048b_readb16 failed: %d\n", ret); + sndbg("as5048b_readu16 failed: %d\n", ret); return ret; } - *ang = buffer; sndbg("ang: %04x ret: %d\n", *ang, ret); return ret; } /**************************************************************************** - * Name: as5048b_open + * Name: as5048b_setup * * Description: - * This function is called whenever the device is opened + * This method is called when the driver is opened * ****************************************************************************/ -static int as5048b_open(FAR struct file *filep) +static int as5048b_setup(FAR struct qe_lowerhalf_s *lower) { return OK; } /**************************************************************************** - * Name: as5048b_close + * Name: as5048b_shutdown * * Description: - * This function is called whenever the device is closed + * This method is called when the driver is closed * ****************************************************************************/ -static int as5048b_close(FAR struct file *filep) +static int as5048b_shutdown(FAR struct qe_lowerhalf_s *lower) { return OK; } /**************************************************************************** - * Name: as5048b_read + * Name: as5048b_position + * + * Description: + * Return the current position measurement + * ****************************************************************************/ -static ssize_t as5048b_read(FAR struct file *filep, FAR char *buffer, - size_t buflen) +static int as5048b_position(FAR struct qe_lowerhalf_s *lower, + FAR int32_t *pos) { - FAR struct inode *inode = filep->f_inode; - FAR struct as5048b_dev_s *priv = inode->i_private; - FAR uint16_t *ptr; - ssize_t nsamples; - ssize_t i; - int ret; - - /* How many samples were requested? */ - - ptr = (FAR uint16_t *)buffer; - nsamples = buflen / sizeof(*ptr); - - sndbg("buflen: %u nsamples: %d\n", buflen, nsamples); - - /* Get the requested number of samples */ + FAR struct as5048b_dev_s *priv = (FAR struct as5048b_dev_s *)lower; + uint16_t ang; + int ret; - for (i = 0; i < nsamples; i++) + ret = as5048b_readang(priv, &ang); + if (ret < 0) { - uint16_t ang = 0; - - /* Read the next uint16_t angle value */ - - ret = as5048b_readang(priv, &ang); - if (ret < 0) - { - sndbg("as5048b_readang failed: %d\n", ret); - return (ssize_t)ret; - } - - /* Save the angle value in the user buffer */ - - *ptr++ = ang; + sndbg("as5048b_readang failed: %d\n", ret); + return ret; } - return nsamples * sizeof(*ptr); + *pos = (int32_t)ang; + return ret; } /**************************************************************************** - * Name: as5048b_write + * Name: as5048b_reset + * + * Description: + * Reset the position measurement to zero + * ****************************************************************************/ -static ssize_t as5048b_write(FAR struct file *filep, FAR const char *buffer, - size_t buflen) +static int as5048b_reset(FAR struct qe_lowerhalf_s *lower) { - return -ENOSYS; + FAR struct as5048b_dev_s *priv = (FAR struct as5048b_dev_s *)lower; + uint16_t ang; + int ret; + + ret = as5048b_writezero(priv, 0); + if (ret < 0) + { + sndbg("as5048b_writezero failed: %d\n", ret); + return ret; + } + + ret = as5048b_readang(priv, &ang); + if (ret < 0) + { + sndbg("as5048b_readang failed: %d\n", ret); + return ret; + } + + ret = as5048b_writezero(priv, ang); + if (ret < 0) + { + sndbg("as5048b_writezero failed: %d\n", ret); + } + + return ret; } /**************************************************************************** * Name: as5048b_ioctl ****************************************************************************/ -static int as5048b_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +static int as5048b_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, + unsigned long arg) { - FAR struct inode *inode = filep->f_inode; - FAR struct as5048b_dev_s *priv = inode->i_private; - int ret = OK; + FAR struct as5048b_dev_s *priv = (FAR struct as5048b_dev_s *)lower; + int ret = OK; switch (cmd) { - /* Read from the zero position registers. Arg: uint16_t* pointer. */ + /* Read from the zero position registers. Arg: int32_t* pointer. */ - case SNIOC_READZERO: + case QEIOC_ZEROPOSITION: { - FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); - ret = as5048b_readzero(priv, ptr); + FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg); + uint16_t zero; + DEBUGASSERT(ptr != NULL); + ret = as5048b_readzero(priv, &zero); + if (ret == OK) + { + *ptr = (int32_t)zero; + } sndbg("zero: %04x ret: %d\n", *ptr, ret); } break; - /* Write to the zero position registers. Arg: uint16_t value. */ - - case SNIOC_WRITEZERO: - ret = as5048b_writezero(priv, (uint16_t)arg); - sndbg("zero: %04x ret: %d\n", *(uint16_t *)arg, ret); - break; - /* Read from the automatic gain control register. Arg: uint8_t* pointer. */ - case SNIOC_READAGC: + case QEIOC_AUTOGAINCTL: { FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = as5048b_readagc(priv, ptr); sndbg("agc: %02x ret: %d\n", *ptr, ret); } @@ -534,26 +538,33 @@ static int as5048b_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Read from the diagnostics register. Arg: uint8_t* pointer. */ - case SNIOC_READDIAG: + case QEIOC_DIAGNOSTICS: { FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = as5048b_readdiag(priv, ptr); sndbg("diag: %02x ret: %d\n", *ptr, ret); } break; - /* Read from the magnitude registers. Arg: uint16_t* pointer. */ + /* Read from the magnitude registers. Arg: int32_t* pointer. */ - case SNIOC_READMAG: + case QEIOC_MAGNITUDE: { - FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); - ret = as5048b_readmag(priv, ptr); + FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg); + uint16_t mag; + DEBUGASSERT(ptr != NULL); + ret = as5048b_readmag(priv, &mag); + if (ret == OK) + { + *ptr = (int32_t)mag; + } sndbg("mag: %04x ret: %d\n", *ptr, ret); } break; default: - sndbg("Unrecognized cmd: %d\n", cmd); + sndbg("Unrecognized cmd: %d arg: %ld\n", cmd, arg); ret = -ENOTTY; break; } @@ -566,28 +577,27 @@ static int as5048b_ioctl(FAR struct file *filep, int cmd, unsigned long arg) ****************************************************************************/ /**************************************************************************** - * Name: as5048b_register + * Name: as5048b_initialize * * Description: - * Register the AS5048B character device as 'devpath'. + * Initialize the AS5048B device. * * Input Parameters: - * devpath - The full path to the driver to register, - * for example "/dev/angle0". - * i2c - An instance of the I2C interface to use to communicate - * with the AS5048B. - * addr - The I2C address of the AS5048B. + * i2c - An I2C driver instance. + * addr - The I2C address of the AS5048B. * * Returned Value: - * Zero (OK) on success; a negated errno value on failure. + * A new lower half quadrature encoder interface for the AS5048B on success; + * NULL on failure. * ****************************************************************************/ -int as5048b_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, - uint8_t addr) +FAR struct qe_lowerhalf_s *as5048b_initialize(FAR struct i2c_master_s *i2c, + uint8_t addr) { FAR struct as5048b_dev_s *priv; - int ret; + + DEBUGASSERT(i2c != NULL); /* Initialize the device's structure */ @@ -595,22 +605,14 @@ int as5048b_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, if (priv == NULL) { sndbg("Failed to allocate instance\n"); - return -ENOMEM; + return NULL; } - priv->i2c = i2c; - priv->addr = addr; + priv->lower.ops = &g_qeops; + priv->i2c = i2c; + priv->addr = addr; - /* Register the character driver */ - - ret = register_driver(devpath, &g_as5048bfops, 0666, priv); - if (ret < 0) - { - sndbg("Failed to register driver: %d\n", ret); - kmm_free(priv); - } - - return ret; + return &priv->lower; } -#endif /* CONFIG_I2C && CONFIG_AS5048B */ +#endif /* CONFIG_I2C && CONFIG_QENCODER && CONFIG_AS5048B */ diff --git a/drivers/sensors/bmp180.c b/drivers/sensors/bmp180.c index 32b1d4bc5e1f4ce9fe67f92d348234551ba7ee17..2124066fe95bf73d61180caa80e4480fd0796ddc 100644 --- a/drivers/sensors/bmp180.c +++ b/drivers/sensors/bmp180.c @@ -3,10 +3,12 @@ * drivers/sensors/bmp180.c * Character driver for the Freescale BMP1801 Barometer Sensor * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. * Copyright (C) 2015 Alan Carvalho de Assis * Author: Alan Carvalho de Assis * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -49,7 +51,7 @@ #include #include -#include +#include #include #if defined(CONFIG_I2C) && defined(CONFIG_BMP180) @@ -110,10 +112,10 @@ struct bmp180_dev_s { - FAR struct i2c_dev_s *i2c; /* I2C interface */ - uint8_t addr; /* BMP180 I2C address */ - int freq; /* BMP180 Frequency <= 3.4MHz */ - int16_t bmp180_cal_ac1; /* Calibration coefficients */ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* BMP180 I2C address */ + int freq; /* BMP180 Frequency <= 3.4MHz */ + int16_t bmp180_cal_ac1; /* Calibration coefficients */ int16_t bmp180_cal_ac2; int16_t bmp180_cal_ac3; uint16_t bmp180_cal_ac4; @@ -124,8 +126,8 @@ struct bmp180_dev_s int16_t bmp180_cal_mb; int16_t bmp180_cal_mc; int16_t bmp180_cal_md; - int32_t bmp180_utemp; /* Uncompensated temperature read from BMP180 */ - int32_t bmp180_upress; /* Uncompensated pressure read from BMP180 */ + int32_t bmp180_utemp; /* Uncompensated temperature read from BMP180 */ + int32_t bmp180_upress; /* Uncompensated pressure read from BMP180 */ }; /**************************************************************************** @@ -144,7 +146,8 @@ static int bmp180_getpressure(FAR struct bmp180_dev_s *priv); static int bmp180_open(FAR struct file *filep); static int bmp180_close(FAR struct file *filep); -static ssize_t bmp180_read(FAR struct file *, FAR char *, size_t); +static ssize_t bmp180_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); static ssize_t bmp180_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); @@ -180,24 +183,31 @@ static const struct file_operations g_bmp180fops = static uint8_t bmp180_getreg8(FAR struct bmp180_dev_s *priv, uint8_t regaddr) { - int ret; + struct i2c_config_s config; uint8_t regval = 0; + int ret; - /* Restart the register */ + /* Set up the I2C configuration */ - ret = I2C_WRITE(priv->i2c, ®addr, 1); + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + ret = i2c_write(priv->i2c, &config, ®addr, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } - /* Restart the register */ + /* Read the register value */ - ret = I2C_READ(priv->i2c, ®val, 1); + ret = i2c_read(priv->i2c, &config, ®val, 1); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } @@ -214,25 +224,32 @@ static uint8_t bmp180_getreg8(FAR struct bmp180_dev_s *priv, uint8_t regaddr) static uint16_t bmp180_getreg16(FAR struct bmp180_dev_s *priv, uint8_t regaddr) { - int ret; + struct i2c_config_s config; uint16_t msb, lsb; uint16_t regval = 0; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; /* Register to read */ - ret = I2C_WRITE(priv->i2c, ®addr, 1); + ret = i2c_write(priv->i2c, &config, ®addr, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Read register */ - ret = I2C_READ(priv->i2c, (uint8_t *)®val, 2); + ret = i2c_read(priv->i2c, &config, (uint8_t *)®val, 2); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } @@ -257,18 +274,25 @@ static uint16_t bmp180_getreg16(FAR struct bmp180_dev_s *priv, uint8_t regaddr) static void bmp180_putreg8(FAR struct bmp180_dev_s *priv, uint8_t regaddr, uint8_t regval) { - int ret; + struct i2c_config_s config; uint8_t data[2]; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; data[0] = regaddr; data[1] = regval; - /* Restart the register */ + /* Write the register address and value */ - ret = I2C_WRITE(priv->i2c, (uint8_t *) &data, 2); + ret = i2c_write(priv->i2c, &config, (uint8_t *) &data, 2); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return; } @@ -523,7 +547,7 @@ static ssize_t bmp180_read(FAR struct file *filep, FAR char *buffer, return -1; } - if ( buflen != 4) + if (buflen != 4) { sndbg("You can't read something other than 32 bits (4 bytes)\n"); return -1; @@ -568,7 +592,7 @@ static ssize_t bmp180_write(FAR struct file *filep, FAR const char *buffer, * ****************************************************************************/ -int bmp180_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c) +int bmp180_register(FAR const char *devpath, FAR struct i2c_master_s *i2c) { FAR struct bmp180_dev_s *priv; int ret; @@ -586,11 +610,6 @@ int bmp180_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c) priv->addr = BMP180_ADDR; priv->freq = BMP180_FREQ; - /* Configure I2C before using it */ - - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - I2C_SETFREQUENCY(priv->i2c, priv->freq); - /* Check Device ID */ ret = bmp180_checkid(priv); diff --git a/drivers/sensors/lis331dl.c b/drivers/sensors/lis331dl.c index ec44a72868b38bf464a2db7dab345c6e94d4996f..f94a3b2ec2c63ceb38316574f7d34d58205ebbb5 100644 --- a/drivers/sensors/lis331dl.c +++ b/drivers/sensors/lis331dl.c @@ -46,11 +46,19 @@ #include #include +#include #include +#if defined(CONFIG_I2C) && defined(CONFIG_LIS331DL) + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + +#ifndef CONFIG_LIS331DL_I2C_FREQUENCY +# define CONFIG_LIS331DL_I2C_FREQUENCY 100000 +#endif + /* LIS331DL Internal Registers **********************************************/ #define ST_LIS331DL_WHOAMI 0x0F /* who am I register */ @@ -90,7 +98,7 @@ struct lis331dl_dev_s { - struct i2c_dev_s *i2c; + struct i2c_master_s *i2c; uint8_t address; struct lis331dl_vector_s a; uint8_t cr1; @@ -103,7 +111,10 @@ struct lis331dl_dev_s ****************************************************************************/ /**************************************************************************** - * LIS331DL Access with range check + * Name: lis331dl_access + * + * Description: + * LIS331DL Access with range check * * Input Parameters: * dev LIS331 DL Private Structure @@ -120,16 +131,16 @@ struct lis331dl_dev_s static int lis331dl_access(FAR struct lis331dl_dev_s *dev, uint8_t subaddr, FAR uint8_t *buf, int length) { - uint16_t flags = 0; + uint16_t flags; int retval; if (length > 0) { - flags = I2C_M_READ; + flags = I2C_M_READ; } else { - flags = I2C_M_NORESTART; + flags = I2C_M_NORESTART; length = -length; } @@ -179,16 +190,18 @@ static int lis331dl_access(FAR struct lis331dl_dev_s *dev, uint8_t subaddr, struct i2c_msg_s msgv[2] = { { - .addr = dev->address, - .flags = 0, - .buffer = &subaddr, - .length = 1 + .frequency = CONFIG_LIS331DL_I2C_FREQUENCY, + .addr = dev->address, + .flags = 0, + .buffer = &subaddr, + .length = 1 }, { - .addr = dev->address, - .flags = flags, - .buffer = buf, - .length = length + .frequency = CONFIG_LIS331DL_I2C_FREQUENCY, + .addr = dev->address, + .flags = flags, + .buffer = buf, + .length = length } }; @@ -200,6 +213,10 @@ static int lis331dl_access(FAR struct lis331dl_dev_s *dev, uint8_t subaddr, return retval; } +/**************************************************************************** + * Name: lis331dl_readregs + ****************************************************************************/ + static int lis331dl_readregs(FAR struct lis331dl_dev_s *dev) { if (lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, 3) != 3) @@ -214,7 +231,11 @@ static int lis331dl_readregs(FAR struct lis331dl_dev_s *dev) * Public Functions ****************************************************************************/ -FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_dev_s *i2c, +/**************************************************************************** + * Name: lis331dl_init + ****************************************************************************/ + +FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_master_s *i2c, uint16_t address) { FAR struct lis331dl_dev_s * dev; @@ -246,7 +267,7 @@ FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_dev_s *i2c, { /* Copy LIS331DL registers to our private structure and power-up device */ - if (lis331dl_readregs(dev)==OK && lis331dl_powerup(dev) == OK) + if (lis331dl_readregs(dev) == OK && lis331dl_powerup(dev) == OK) { /* Normal exit point */ @@ -275,6 +296,10 @@ FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_dev_s *i2c, return NULL; } +/**************************************************************************** + * Name: lis331dl_deinit + ****************************************************************************/ + int lis331dl_deinit(FAR struct lis331dl_dev_s * dev) { ASSERT(dev); @@ -285,6 +310,10 @@ int lis331dl_deinit(FAR struct lis331dl_dev_s * dev) return OK; } +/**************************************************************************** + * Name: lis331dl_powerup + ****************************************************************************/ + int lis331dl_powerup(FAR struct lis331dl_dev_s * dev) { dev->cr1 = ST_LIS331DL_CR1_PD | @@ -300,6 +329,10 @@ int lis331dl_powerup(FAR struct lis331dl_dev_s * dev) return ERROR; } +/**************************************************************************** + * Name: lis331dl_powerdown + ****************************************************************************/ + int lis331dl_powerdown(FAR struct lis331dl_dev_s * dev) { dev->cr1 = ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN; @@ -314,6 +347,10 @@ int lis331dl_powerdown(FAR struct lis331dl_dev_s * dev) return ERROR; } +/**************************************************************************** + * Name: lis331dl_setconversion + ****************************************************************************/ + int lis331dl_setconversion(FAR struct lis331dl_dev_s * dev, bool full, bool fast) { dev->cr1 = ST_LIS331DL_CR1_PD | @@ -328,6 +365,10 @@ int lis331dl_setconversion(FAR struct lis331dl_dev_s * dev, bool full, bool fast return ERROR; } +/**************************************************************************** + * Name: lis331dl_getprecision + ****************************************************************************/ + int lis331dl_getprecision(FAR struct lis331dl_dev_s * dev) { if (dev->cr1 & ST_LIS331DL_CR1_FS) @@ -338,6 +379,10 @@ int lis331dl_getprecision(FAR struct lis331dl_dev_s * dev) return 2300/127; /* typ. 2.3g full scale */ } +/**************************************************************************** + * Name: lis331dl_getsamplerate + ****************************************************************************/ + int lis331dl_getsamplerate(FAR struct lis331dl_dev_s * dev) { if (dev->cr1 & ST_LIS331DL_CR1_DR) @@ -348,6 +393,10 @@ int lis331dl_getsamplerate(FAR struct lis331dl_dev_s * dev) return 100; } +/**************************************************************************** + * Name: lis331dl_getreadings + ****************************************************************************/ + FAR const struct lis331dl_vector_s * lis331dl_getreadings(FAR struct lis331dl_dev_s * dev) { @@ -373,3 +422,5 @@ lis331dl_getreadings(FAR struct lis331dl_dev_s * dev) return NULL; } + +#endif /* CONFIG_I2C && CONFIG_LIS331DL */ diff --git a/drivers/sensors/lm75.c b/drivers/sensors/lm75.c index 5277fada40297834390d7b001156a25efea7994e..f3fad7397216bd2fcce82d646d6802eb55dd5024 100644 --- a/drivers/sensors/lm75.c +++ b/drivers/sensors/lm75.c @@ -2,7 +2,7 @@ * drivers/sensors/lm75.c * Character driver for the STMicro LM-75 Temperature Sensor * - * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ #include #include -#include +#include #include #if defined(CONFIG_I2C) && defined(CONFIG_I2C_LM75) @@ -56,6 +56,10 @@ * Pre-processor Definitions ****************************************************************************/ +#ifndef CONFIG_LM75_I2C_FREQUENCY +# define CONFIG_LM75_I2C_FREQUENCY 100000 +#endif + /* Centigrade to Fahrenheit conversion: F = 9*C/5 + 32 */ #define B16_9DIV5 (9 * 65536 / 5) @@ -67,9 +71,9 @@ struct lm75_dev_s { - FAR struct i2c_dev_s *i2c; /* I2C interface */ - uint8_t addr; /* I2C address */ - bool fahrenheit; /* true: temperature will be reported in fahrenheit */ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + bool fahrenheit; /* true: temperature will be reported in fahrenheit */ }; /**************************************************************************** @@ -77,20 +81,26 @@ struct lm75_dev_s ****************************************************************************/ /* I2C Helpers */ -static int lm75_readb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, - FAR b16_t *regvalue); -static int lm75_writeb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, - b16_t regval); -static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp); -static int lm75_readconf(FAR struct lm75_dev_s *priv, FAR uint8_t *conf); -static int lm75_writeconf(FAR struct lm75_dev_s *priv, uint8_t conf); +static int lm75_i2c_write(FAR struct lm75_dev_s *priv, + FAR const uint8_t *buffer, int buflen); +static int lm75_i2c_read(FAR struct lm75_dev_s *priv, + FAR uint8_t *buffer, int buflen); +static int lm75_readb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, + FAR b16_t *regvalue); +static int lm75_writeb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, + b16_t regval); +static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp); +static int lm75_readconf(FAR struct lm75_dev_s *priv, FAR uint8_t *conf); +static int lm75_writeconf(FAR struct lm75_dev_s *priv, uint8_t conf); /* Character driver methods */ static int lm75_open(FAR struct file *filep); static int lm75_close(FAR struct file *filep); -static ssize_t lm75_read(FAR struct file *, FAR char *, size_t); -static ssize_t lm75_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); +static ssize_t lm75_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t lm75_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); static int lm75_ioctl(FAR struct file *filep,int cmd,unsigned long arg); /**************************************************************************** @@ -103,16 +113,69 @@ static const struct file_operations g_lm75fops = lm75_close, lm75_read, lm75_write, - 0, + NULL, lm75_ioctl #ifndef CONFIG_DISABLE_POLL - , 0 + , NULL #endif }; /**************************************************************************** * Private Functions ****************************************************************************/ + +/**************************************************************************** + * Name: lm75_i2c_write + * + * Description: + * Write to the I2C device. + * + ****************************************************************************/ + +static int lm75_i2c_write(FAR struct lm75_dev_s *priv, + FAR const uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_LM75_I2C_FREQUENCY, + msg.addr = priv->addr; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + +/**************************************************************************** + * Name: lm75_i2c_read + * + * Description: + * Read from the I2C device. + * + ****************************************************************************/ + +static int lm75_i2c_read(FAR struct lm75_dev_s *priv, + FAR uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_LM75_I2C_FREQUENCY, + msg.addr = priv->addr, + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + /**************************************************************************** * Name: lm75_readb16 * @@ -129,20 +192,19 @@ static int lm75_readb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, /* Write the register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - ret = I2C_WRITE(priv->i2c, ®addr, 1); + ret = lm75_i2c_write(priv, ®addr, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 16-bits from the register (discarding 7) */ - ret = I2C_READ(priv->i2c, buffer, 2); + ret = lm75_i2c_read(priv, buffer, 2); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } @@ -182,8 +244,7 @@ static int lm75_writeb16(FAR struct lm75_dev_s *priv, uint8_t regaddr, /* Write the register address followed by the data (no RESTART) */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - return I2C_WRITE(priv->i2c, buffer, 3); + return lm75_i2c_write(priv, buffer, 3); } /**************************************************************************** @@ -239,19 +300,18 @@ static int lm75_readconf(FAR struct lm75_dev_s *priv, FAR uint8_t *conf) /* Write the configuration register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - buffer = LM75_CONF_REG; - ret = I2C_WRITE(priv->i2c, &buffer, 1); + + ret = lm75_i2c_write(priv, &buffer, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 8-bits from the register */ - ret = I2C_READ(priv->i2c, conf, 1); + ret = lm75_i2c_read(priv, conf, 1); sndbg("conf: %02x ret: %d\n", *conf, ret); return ret; } @@ -277,8 +337,7 @@ static int lm75_writeconf(FAR struct lm75_dev_s *priv, uint8_t conf) /* Write the register address followed by the data (no RESTART) */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - return I2C_WRITE(priv->i2c, buffer, 2); + return lm75_i2c_write(priv, buffer, 2); } /**************************************************************************** @@ -338,7 +397,7 @@ static ssize_t lm75_read(FAR struct file *filep, FAR char *buffer, size_t buflen ret = lm75_readtemp(priv, &temp); if (ret < 0) { - sndbg("lm75_readtemp failed: %d\n",ret); + sndbg("lm75_readtemp failed: %d\n", ret); return (ssize_t)ret; } @@ -377,6 +436,7 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READCONF: { FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm75_readconf(priv, ptr); sndbg("conf: %02x ret: %d\n", *ptr, ret); } @@ -386,7 +446,7 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_WRITECONF: ret = lm75_writeconf(priv, (uint8_t)arg); - sndbg("conf: %02x ret: %d\n", *(uint8_t*)arg, ret); + sndbg("conf: %02x ret: %d\n", *(FAR uint8_t *)arg, ret); break; /* Shutdown the LM75, Arg: None */ @@ -438,6 +498,7 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTHYS: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm75_readb16(priv, LM75_THYS_REG, ptr); sndbg("THYS: %08x ret: %d\n", *ptr, ret); } @@ -455,6 +516,7 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTOS: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm75_readb16(priv, LM75_TOS_REG, ptr); sndbg("TOS: %08x ret: %d\n", *ptr, ret); } @@ -462,7 +524,7 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Write TOS (Over-temp Shutdown Threshold) Register. Arg: b16_t value */ - case SNIOC_WRITRETOS: + case SNIOC_WRITETOS: ret = lm75_writeb16(priv, LM75_TOS_REG, (b16_t)arg); sndbg("TOS: %08x ret: %d\n", (b16_t)arg, ret); break; @@ -498,15 +560,23 @@ static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -int lm75_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, uint8_t addr) +int lm75_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, uint8_t addr) { FAR struct lm75_dev_s *priv; int ret; + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + DEBUGASSERT(addr == CONFIG_LM75_ADDR0 || addr == CONFIG_LM75_ADDR1 || + addr == CONFIG_LM75_ADDR2 || addr == CONFIG_LM75_ADDR3 || + addr == CONFIG_LM75_ADDR4 || addr == CONFIG_LM75_ADDR5 || + addr == CONFIG_LM75_ADDR6 || addr == CONFIG_LM75_ADDR7); + /* Initialize the LM-75 device structure */ priv = (FAR struct lm75_dev_s *)kmm_malloc(sizeof(struct lm75_dev_s)); - if (!priv) + if (priv == NULL) { sndbg("Failed to allocate instance\n"); return -ENOMEM; diff --git a/drivers/sensors/lm92.c b/drivers/sensors/lm92.c index 8d75e017713ff25b2b96c3aebdef96451c691534..73f4d54634ebc61322af6d7a98966d042cf27f3b 100644 --- a/drivers/sensors/lm92.c +++ b/drivers/sensors/lm92.c @@ -3,9 +3,9 @@ * Character driver for the TI LM92 Temperature Sensor * * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. - * Copyright (C) 2015 Alexandru Duru. All rights reserved. - * Author: Gregory Nutt - * Alexandru Duru + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Paul Alexander Patience * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,7 +49,7 @@ #include #include -#include +#include #include #if defined(CONFIG_I2C) && defined(CONFIG_LM92) @@ -58,6 +58,10 @@ * Pre-processor Definitions ****************************************************************************/ +#ifndef CONFIG_LM92_I2C_FREQUENCY +# define CONFIG_LM92_I2C_FREQUENCY 400000 +#endif + /* Centigrade to Fahrenheit conversion: F = 9*C/5 + 32 */ #define B16_9DIV5 (9 * 65536 / 5) @@ -69,9 +73,9 @@ struct lm92_dev_s { - FAR struct i2c_dev_s *i2c; /* I2C interface */ - uint8_t addr; /* I2C address */ - bool fahrenheit; /* true: temperature will be reported in Fahrenheit */ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + bool fahrenheit; /* true: temperature will be reported in Fahrenheit */ }; /**************************************************************************** @@ -79,13 +83,17 @@ struct lm92_dev_s ****************************************************************************/ /* I2C Helpers */ -static int lm92_readb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, - FAR b16_t *regvalue); -static int lm92_writeb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, - b16_t regval); -static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp); -static int lm92_readconf(FAR struct lm92_dev_s *priv, FAR uint8_t *conf); -static int lm92_writeconf(FAR struct lm92_dev_s *priv, uint8_t conf); +static int lm92_i2c_write(FAR struct lm92_dev_s *priv, + FAR const uint8_t *buffer, int buflen); +static int lm92_i2c_read(FAR struct lm92_dev_s *priv, + FAR uint8_t *buffer, int buflen); +static int lm92_readb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + FAR b16_t *regvalue); +static int lm92_writeb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + b16_t regval); +static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp); +static int lm92_readconf(FAR struct lm92_dev_s *priv, FAR uint8_t *conf); +static int lm92_writeconf(FAR struct lm92_dev_s *priv, uint8_t conf); /* Character driver methods */ @@ -107,16 +115,69 @@ static const struct file_operations g_lm92fops = lm92_close, lm92_read, lm92_write, - 0, + NULL, lm92_ioctl #ifndef CONFIG_DISABLE_POLL - , 0 + , NULL #endif }; /**************************************************************************** * Private Functions ****************************************************************************/ + +/**************************************************************************** + * Name: lm92_i2c_write + * + * Description: + * Write to the I2C device. + * + ****************************************************************************/ + +static int lm92_i2c_write(FAR struct lm92_dev_s *priv, + FAR const uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_LM92_I2C_FREQUENCY, + msg.addr = priv->addr; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + +/**************************************************************************** + * Name: lm92_i2c_read + * + * Description: + * Read from the I2C device. + * + ****************************************************************************/ + +static int lm92_i2c_read(FAR struct lm92_dev_s *priv, + FAR uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_LM92_I2C_FREQUENCY, + msg.addr = priv->addr, + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + /**************************************************************************** * Name: lm92_readb16 * @@ -134,20 +195,19 @@ static int lm92_readb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, /* Write the register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - ret = I2C_WRITE(priv->i2c, ®addr, 1); + ret = lm92_i2c_write(priv, ®addr, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 16 bits from the register (discarding 3) */ - ret = I2C_READ(priv->i2c, buffer, 2); + ret = lm92_i2c_read(priv, buffer, 2); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } @@ -187,8 +247,7 @@ static int lm92_writeb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, /* Write the register address followed by the data (no RESTART) */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - return I2C_WRITE(priv->i2c, buffer, 3); + return lm92_i2c_write(priv, buffer, 3); } /**************************************************************************** @@ -244,19 +303,18 @@ static int lm92_readconf(FAR struct lm92_dev_s *priv, FAR uint8_t *conf) /* Write the configuration register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - buffer = LM92_CONF_REG; - ret = I2C_WRITE(priv->i2c, &buffer, 1); + + ret = lm92_i2c_write(priv, &buffer, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 8 bits from the register */ - ret = I2C_READ(priv->i2c, conf, 1); + ret = lm92_i2c_read(priv, conf, 1); sndbg("conf: %02x ret: %d\n", *conf, ret); return ret; } @@ -282,8 +340,7 @@ static int lm92_writeconf(FAR struct lm92_dev_s *priv, uint8_t conf) /* Write the register address followed by the data (no RESTART) */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - return I2C_WRITE(priv->i2c, buffer, 2); + return lm92_i2c_write(priv, buffer, 2); } /**************************************************************************** @@ -302,22 +359,21 @@ static int lm92_readid(FAR struct lm92_dev_s *priv, FAR uint16_t *id) /* Write the identification register address */ - I2C_SETADDRESS(priv->i2c, priv->addr, 7); - regaddr = LM92_ID_REG; - ret = I2C_WRITE(priv->i2c, ®addr, 1); + + ret = lm92_i2c_write(priv, ®addr, 1); if (ret < 0) { - sndbg("I2C_WRITE failed: %d\n", ret); + sndbg("i2c_write failed: %d\n", ret); return ret; } /* Restart and read 16 bits from the register */ - ret = I2C_READ(priv->i2c, buffer, 2); + ret = lm92_i2c_read(priv, buffer, 2); if (ret < 0) { - sndbg("I2C_READ failed: %d\n", ret); + sndbg("i2c_read failed: %d\n", ret); return ret; } @@ -384,7 +440,7 @@ static ssize_t lm92_read(FAR struct file *filep, FAR char *buffer, ret = lm92_readtemp(priv, &temp); if (ret < 0) { - sndbg("lm92_readtemp failed: %d\n",ret); + sndbg("lm92_readtemp failed: %d\n", ret); return (ssize_t)ret; } @@ -423,6 +479,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READCONF: { FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readconf(priv, ptr); sndbg("conf: %02x ret: %d\n", *ptr, ret); } @@ -484,6 +541,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTHYS: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readb16(priv, LM92_THYS_REG, ptr); sndbg("THYS: %08x ret: %d\n", *ptr, ret); } @@ -501,6 +559,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTCRIT: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readb16(priv, LM92_TCRIT_REG, ptr); sndbg("TCRIT: %08x ret: %d\n", *ptr, ret); } @@ -518,6 +577,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTLOW: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readb16(priv, LM92_TLOW_REG, ptr); sndbg("TLOW: %08x ret: %d\n", *ptr, ret); } @@ -535,6 +595,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READTHIGH: { FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readb16(priv, LM92_THIGH_REG, ptr); sndbg("THIGH: %08x ret: %d\n", *ptr, ret); } @@ -552,6 +613,7 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_READID: { FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); ret = lm92_readid(priv, ptr); sndbg("id: %04x ret: %d\n", *ptr, ret); } @@ -589,16 +651,22 @@ static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -int lm92_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, +int lm92_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, uint8_t addr) { FAR struct lm92_dev_s *priv; int ret; + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + DEBUGASSERT(addr == CONFIG_LM92_ADDR0 || addr == CONFIG_LM92_ADDR1 || + addr == CONFIG_LM92_ADDR2 || addr == CONFIG_LM92_ADDR3); + /* Initialize the LM92 device structure */ priv = (FAR struct lm92_dev_s *)kmm_malloc(sizeof(struct lm92_dev_s)); - if (!priv) + if (priv == NULL) { sndbg("Failed to allocate instance\n"); return -ENOMEM; diff --git a/drivers/sensors/lsm9ds1.c b/drivers/sensors/lsm9ds1.c new file mode 100644 index 0000000000000000000000000000000000000000..10f902aeaadb90ddfd7e9b6d010971d923b8b894 --- /dev/null +++ b/drivers/sensors/lsm9ds1.c @@ -0,0 +1,1574 @@ +/**************************************************************************** + * drivers/sensors/lsm9ds1.c + * + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SN_LSM9DS1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_LSM9DS1_I2C_FREQUENCY +# define CONFIG_LSM9DS1_I2C_FREQUENCY 400000 +#endif + +/* Register Addresses *******************************************************/ +/* Accelerometer and gyroscope registers */ + +#define LSM9DS1_ACT_THS 0x04 /* Inactivity threshold */ +#define LSM9DS1_ACT_DUR 0x05 /* Inactivity duration */ +#define LSM9DS1_INT_GEN_CFG_XL 0x06 /* Accelerometer interrupt configuration */ +#define LSM9DS1_INT_GEN_THS_X_XL 0x07 /* Accelerometer X interrupt threshold */ +#define LSM9DS1_INT_GEN_THS_Y_XL 0x08 /* Accelerometer Y interrupt threshold */ +#define LSM9DS1_INT_GEN_THS_Z_XL 0x09 /* Accelerometer Z interrupt threshold */ +#define LSM9DS1_INT_GEN_DUR_XL 0x0a /* Accelerometer interrupt duration */ +#define LSM9DS1_REFERENCE_G 0x0b /* Gyroscope reference value for high-pass filter */ +#define LSM9DS1_INT1_CTRL 0x0c /* INT1_A/G pin control */ +#define LSM9DS1_INT2_CTRL 0x0d /* INT2_A/G pin control */ +#define LSM9DS1_WHO_AM_I 0x0f /* Accelerometer and gyroscope device identification */ +#define LSM9DS1_CTRL_REG1_G 0x10 /* Gyroscope control register 1 */ +#define LSM9DS1_CTRL_REG2_G 0x11 /* Gyroscope control register 2 */ +#define LSM9DS1_CTRL_REG3_G 0x12 /* Gyroscope control register 3 */ +#define LSM9DS1_ORIENT_CFG_G 0x13 /* Gyroscope sign and orientation */ +#define LSM9DS1_INT_GEN_SRC_G 0x14 /* Gyroscope interrupt source */ +#define LSM9DS1_OUT_TEMP_L 0x15 /* Temperature low byte */ +#define LSM9DS1_OUT_TEMP_H 0x16 /* Temperature high byte */ +#define LSM9DS1_STATUS_REG 0x17 /* Status register */ +#define LSM9DS1_OUT_X_L_G 0x18 /* Gyroscope pitch (X) low byte */ +#define LSM9DS1_OUT_X_H_G 0x19 /* Gyroscope pitch (X) high byte */ +#define LSM9DS1_OUT_Y_L_G 0x1a /* Gyroscope roll (Y) low byte */ +#define LSM9DS1_OUT_Y_H_G 0x1b /* Gyroscope roll (Y) high byte */ +#define LSM9DS1_OUT_Z_L_G 0x1c /* Gyroscope yaw (Z) low byte */ +#define LSM9DS1_OUT_Z_H_G 0x1d /* Gyroscope yaw (Z) high byte */ +#define LSM9DS1_CTRL_REG4 0x1e /* Control register 4 */ +#define LSM9DS1_CTRL_REG5_XL 0x1f /* Accelerometer control register 5 */ +#define LSM9DS1_CTRL_REG6_XL 0x20 /* Accelerometer control register 6 */ +#define LSM9DS1_CTRL_REG7_XL 0x21 /* Accelerometer control register 7 */ +#define LSM9DS1_CTRL_REG8 0x22 /* Control register 8 */ +#define LSM9DS1_CTRL_REG9 0x23 /* Control register 9 */ +#define LSM9DS1_CTRL_REG10 0x24 /* Control register 10 */ +#define LSM9DS1_INT_GEN_SRC_XL 0x26 /* Accelerometer interrupt source */ +#define LSM9DS1_STATUS_REG2 0x27 /* Status register 2 */ +#define LSM9DS1_OUT_X_L_XL 0x28 /* Accelerometer X low byte */ +#define LSM9DS1_OUT_X_H_XL 0x29 /* Accelerometer X high byte */ +#define LSM9DS1_OUT_Y_L_XL 0x2a /* Accelerometer Y low byte */ +#define LSM9DS1_OUT_Y_H_XL 0x2b /* Accelerometer Y high byte */ +#define LSM9DS1_OUT_Z_L_XL 0x2c /* Accelerometer Z low byte */ +#define LSM9DS1_OUT_Z_H_XL 0x2d /* Accelerometer Z high byte */ +#define LSM9DS1_FIFO_CTRL 0x2e /* FIFO control register */ +#define LSM9DS1_FIFO_SRC 0x2f /* FIFO status control register */ +#define LSM9DS1_INT_GEN_CFG_G 0x30 /* Gyroscope interrupt configuration */ +#define LSM9DS1_INT_GEN_THS_XH_G 0x31 /* Gyroscope pitch (X) interrupt threshold high byte */ +#define LSM9DS1_INT_GEN_THS_XL_G 0x32 /* Gyroscope pitch (X) interrupt threshold low byte */ +#define LSM9DS1_INT_GEN_THS_YH_G 0x33 /* Gyroscope roll (Y) interrupt threshold high byte */ +#define LSM9DS1_INT_GEN_THS_YL_G 0x34 /* Gyroscope roll (Y) interrupt threshold low byte */ +#define LSM9DS1_INT_GEN_THS_ZH_G 0x35 /* Gyroscope yaw (Z) interrupt threshold high byte */ +#define LSM9DS1_INT_GEN_THS_ZL_G 0x36 /* Gyroscope yaw (Z) interrupt threshold low byte */ +#define LSM9DS1_INT_GEN_DUR_G 0x37 /* Gyroscope interrupt duration */ + +/* Magnetometer registers */ + +#define LSM9DS1_OFFSET_X_REG_L_M 0x05 /* X low byte offset */ +#define LSM9DS1_OFFSET_X_REG_H_M 0x06 /* X high byte offset */ +#define LSM9DS1_OFFSET_Y_REG_L_M 0x07 /* Y low byte offset */ +#define LSM9DS1_OFFSET_Y_REG_H_M 0x08 /* Y high byte offset */ +#define LSM9DS1_OFFSET_Z_REG_L_M 0x09 /* Z low byte offset */ +#define LSM9DS1_OFFSET_Z_REG_H_M 0x0a /* Z high byte offset */ +#define LSM9DS1_WHO_AM_I_M 0x0f /* Device identification */ +#define LSM9DS1_CTRL_REG1_M 0x20 /* Control register 1 */ +#define LSM9DS1_CTRL_REG2_M 0x21 /* Control register 2 */ +#define LSM9DS1_CTRL_REG3_M 0x22 /* Control register 3 */ +#define LSM9DS1_CTRL_REG4_M 0x23 /* Control register 4 */ +#define LSM9DS1_CTRL_REG5_M 0x24 /* Control register 5 */ +#define LSM9DS1_STATUS_REG_M 0x27 /* Status register */ +#define LSM9DS1_OUT_X_L_M 0x28 /* X low byte */ +#define LSM9DS1_OUT_X_H_M 0x29 /* X high byte */ +#define LSM9DS1_OUT_Y_L_M 0x2a /* Y low byte */ +#define LSM9DS1_OUT_Y_H_M 0x2b /* Y high byte */ +#define LSM9DS1_OUT_Z_L_M 0x2c /* Z low byte */ +#define LSM9DS1_OUT_Z_H_M 0x2d /* Z high byte */ +#define LSM9DS1_INT_CFG_M 0x30 /* Interrupt configuration */ +#define LSM9DS1_INT_SRC_M 0x31 /* Interrupt source */ +#define LSM9DS1_INT_THS_L_M 0x32 /* Interrupt threshold low byte */ +#define LSM9DS1_INT_THS_H_M 0x33 /* Interrupt threshold high byte */ + +/* Register Bit Definitions *************************************************/ +/* Inactivity threshold register */ + +#define LSM9DS1_ACT_THS_ACT_THS_SHIFT 0 /* Inactivity threshold */ +#define LSM9DS1_ACT_THS_ACT_THS_MASK (127 << LSM9DS1_ACT_THS_ACT_THS_SHIFT) +#define LSM9DS1_ACT_THS_SLEEP_ON_INACT_EN (1 << 7) /* Gyroscope operating mode during inactivity */ + +/* Accelerometer interrupt configuration register */ + +#define LSM9DS1_INT_GEN_CFG_XL_XLIE_XL (1 << 0) /* X-axis low byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_XHIE_XL (1 << 1) /* X-axis high byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_YLIE_XL (1 << 2) /* Y-axis low byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_YHIE_XL (1 << 3) /* Y-axis high byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_ZLIE_XL (1 << 4) /* Z-axis low byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_ZHIE_XL (1 << 5) /* Z-axis high byte interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_XL_6D (1 << 6) /* 6-direction detection function for interrupt */ +#define LSM9DS1_INT_GEN_CFG_XL_AOI_XL (1 << 7) /* AND/OR combination of interrupt events */ + +/* Accelerometer interrupt duration register */ + +#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT 0 /* Enter/exit interrupt duration */ +#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_MASK (127 << LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT) +#define LSM9DS1_INT_GEN_DUR_XL_WAIT_XL (1 << 7) /* Wait function enabled on duration counter */ + +/* INT1_A/G pin control register */ + +#define LSM9DS1_INT1_CTRL_INT1_DRDY_XL (1 << 0) /* Accelerometer data ready */ +#define LSM9DS1_INT1_CTRL_INT1_DRDY_G (1 << 1) /* Gyroscope data ready */ +#define LSM9DS1_INT1_CTRL_INT1_BOOT (1 << 2) /* Boot status available */ +#define LSM9DS1_INT1_CTRL_INT1_FTH (1 << 3) /* FIFO threshold interrupt */ +#define LSM9DS1_INT1_CTRL_INT1_OVR (1 << 4) /* Overrun interrupt */ +#define LSM9DS1_INT1_CTRL_INT1_FSS5 (1 << 5) /* FSS5 interrupt */ +#define LSM9DS1_INT1_CTRL_INT1_IG_XL (1 << 6) /* Accelerometer interrupt enable */ +#define LSM9DS1_INT1_CTRL_INT1_IG_G (1 << 7) /* Gyroscope interrupt enable */ + +/* INT2_A/G pin control register */ + +#define LSM9DS1_INT2_CTRL_INT2_DRDY_XL (1 << 0) /* Accelerometer data ready */ +#define LSM9DS1_INT2_CTRL_INT2_DRDY_G (1 << 1) /* Gyroscope data ready */ +#define LSM9DS1_INT2_CTRL_INT2_DRDY_TEMP (1 << 2) /* Temperature data ready */ +#define LSM9DS1_INT2_CTRL_INT2_FTH (1 << 3) /* FIFO threshold interrupt */ +#define LSM9DS1_INT2_CTRL_INT2_OVR (1 << 4) /* Overrun interrupt */ +#define LSM9DS1_INT2_CTRL_INT2_FSS5 (1 << 5) /* FSS5 interrupt */ +#define LSM9DS1_INT2_CTRL_INT2_INACT (1 << 7) /* Inactivity interrupt output signal */ + +/* Device identification register */ + +#define LSM9DS1_WHO_AM_I_VALUE 0x68 + +/* Gyroscope control register 1 */ + +#define LSM9DS1_CTRL_REG1_G_BW_G_SHIFT 0 /* Gyroscope bandwidth selection */ +#define LSM9DS1_CTRL_REG1_G_BW_G_MASK (3 << LSM9DS1_CTRL_REG1_G_BW_G_SHIFT) +#define LSM9DS1_CTRL_REG1_G_FS_G_SHIFT 3 /* Gyroscope full-scale selection */ +#define LSM9DS1_CTRL_REG1_G_FS_G_MASK (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) +# define LSM9DS1_CTRL_REG1_G_FS_G_245DPS (0 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 245 dps */ +# define LSM9DS1_CTRL_REG1_G_FS_G_500DPS (1 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 500 dps */ +# define LSM9DS1_CTRL_REG1_G_FS_G_2000DPS (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 2000 dps */ +#define LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT 5 /* Gyroscope bandwidth selection */ +#define LSM9DS1_CTRL_REG1_G_ODR_G_MASK (7 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) +# define LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN (0 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* Power-down mode */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ (1 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 14.9 Hz */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ (2 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 59.5 Hz */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_119HZ (3 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 119 Hz */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_238HZ (4 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 238 Hz */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_476HZ (5 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 476 Hz */ +# define LSM9DS1_CTRL_REG1_G_ODR_G_952HZ (6 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 952 Hz */ + +/* Gyroscope control register 2 */ + +#define LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT 0 /* Out selection configuration */ +#define LSM9DS1_CTRL_REG2_G_OUT_SEL_MASK (3 << LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT) +#define LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT 2 /* INT selection configuration */ +#define LSM9DS1_CTRL_REG2_G_INT_SEL_MASK (3 << LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT) + +/* Gyroscope control register 3 */ + +#define LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT 0 /* Gyroscope high-pass filter cutoff frequency selection */ +#define LSM9DS1_CTRL_REG3_G_HPCF_G_MASK (15 << LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT) +#define LSM9DS1_CTRL_REG3_G_HP_EN (1 << 6) /* High-pass filter enable */ +#define LSM9DS1_CTRL_REG3_G_LP_MODE (1 << 7) /* Low-power mode enable */ + +/* Gyroscope sign and orientation register */ + +#define LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT 0 /* Directional user orientation selection */ +#define LSM9DS1_ORIENT_CFG_G_ORIENT_MASK (3 << LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT) +#define LSM9DS1_ORIENT_CFG_G_SIGNZ_G (1 << 3) /* Yaw axis (Z) angular rate sign */ +#define LSM9DS1_ORIENT_CFG_G_SIGNY_G (1 << 4) /* Roll axis (Y) angular rate sign */ +#define LSM9DS1_ORIENT_CFG_G_SIGNX_G (1 << 5) /* Pitch axis (X) angular rate sign */ + +/* Gyroscope interrupt source register */ + +#define LSM9DS1_INT_GEN_SRC_G_XL_G (1 << 0) /* Pitch (X) low */ +#define LSM9DS1_INT_GEN_SRC_G_XH_G (1 << 1) /* Pitch (X) high */ +#define LSM9DS1_INT_GEN_SRC_G_YL_G (1 << 2) /* Roll (Y) low */ +#define LSM9DS1_INT_GEN_SRC_G_YH_G (1 << 3) /* Roll (Y) high */ +#define LSM9DS1_INT_GEN_SRC_G_ZL_G (1 << 4) /* Yaw (Z) low */ +#define LSM9DS1_INT_GEN_SRC_G_ZH_G (1 << 5) /* Yaw (Z) high */ +#define LSM9DS1_INT_GEN_SRC_G_IA_G (1 << 6) /* Interrupt active */ + +/* Status register */ + +#define LSM9DS1_STATUS_REG_XLDA (1 << 0) /* Accelerometer new data available */ +#define LSM9DS1_STATUS_REG_GDA (1 << 1) /* Gyroscope new data available */ +#define LSM9DS1_STATUS_REG_TDA (1 << 2) /* Temperature sensor new data available */ +#define LSM9DS1_STATUS_REG_BOOT_STATUS (1 << 3) /* Boot running flag signal */ +#define LSM9DS1_STATUS_REG_INACT (1 << 4) /* Inactivity interrupt output signal */ +#define LSM9DS1_STATUS_REG_IG_G (1 << 5) /* Gyroscope interrupt output signal */ +#define LSM9DS1_STATUS_REG_IG_XL (1 << 6) /* Accelerometer interrupt output signal */ + +/* Control register 4 */ + +#define LSM9DS1_CTRL_REG4_4D_XL1 (1 << 0) /* 4D option enabled on interrupt */ +#define LSM9DS1_CTRL_REG4_LIR_XL1 (1 << 1) /* Latched interrupt */ +#define LSM9DS1_CTRL_REG4_XEN_G (1 << 3) /* Gyroscope's pitch axis (X) output enable */ +#define LSM9DS1_CTRL_REG4_YEN_G (1 << 4) /* Gyroscope's roll axis (Y) output enable */ +#define LSM9DS1_CTRL_REG4_ZEN_G (1 << 5) /* Gyroscope's yaw axis (Z) output enable */ + +/* Accelerometer control register 5 */ + +#define LSM9DS1_CTRL_REG5_XL_XEN_XL (1 << 3) /* Accelerometer's X-axis output enable */ +#define LSM9DS1_CTRL_REG5_XL_YEN_XL (1 << 4) /* Accelerometer's Y-axis output enable */ +#define LSM9DS1_CTRL_REG5_XL_ZEN_XL (1 << 5) /* Accelerometer's Z-axis output enable */ +#define LSM9DS1_CTRL_REG5_XL_DEC_SHIFT 6 /* Decimation of acceleration data on OUT REG and FIFO */ +#define LSM9DS1_CTRL_REG5_XL_DEC_MASK (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) +# define LSM9DS1_CTRL_REG5_XL_DEC_NODEC (0 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* No decimation */ +# define LSM9DS1_CTRL_REG5_XL_DEC_2SAMPLES (1 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 2 samples */ +# define LSM9DS1_CTRL_REG5_XL_DEC_4SAMPLES (2 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 4 samples */ +# define LSM9DS1_CTRL_REG5_XL_DEC_8SAMPLES (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 8 samples */ + +/* Accelerometer control register 6 */ + +#define LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT 0 /* Anti-aliasing filter bandwidth selection */ +#define LSM9DS1_CTRL_REG6_XL_BW_XL_MASK (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) +# define LSM9DS1_CTRL_REG6_XL_BW_XL_408HZ (0 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 408 Hz */ +# define LSM9DS1_CTRL_REG6_XL_BW_XL_211HZ (1 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 211 Hz */ +# define LSM9DS1_CTRL_REG6_XL_BW_XL_105HZ (2 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 105 Hz */ +# define LSM9DS1_CTRL_REG6_XL_BW_XL_50HZ (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 50 Hz */ +#define LSM9DS1_CTRL_REG6_XL_BW_SCAL_ODR (1 << 2) /* Bandwidth selection */ +#define LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT 3 /* Accelerometer full-scale selection */ +#define LSM9DS1_CTRL_REG6_XL_FS_XL_MASK (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) +# define LSM9DS1_CTRL_REG6_XL_FS_XL_2G (0 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 2 g */ +# define LSM9DS1_CTRL_REG6_XL_FS_XL_16G (1 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 16 g */ +# define LSM9DS1_CTRL_REG6_XL_FS_XL_4G (2 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 4 g */ +# define LSM9DS1_CTRL_REG6_XL_FS_XL_8G (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 8 g */ +#define LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT 5 /* Output data rate and power mode selection */ +#define LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK (7 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN (0 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* Power-down mode */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ (1 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 10 Hz */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ (2 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 50 Hz */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ (3 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 119 Hz */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ (4 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 238 Hz */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ (5 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 476 Hz */ +# define LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ (6 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 952 Hz */ + +/* Accelerometer control register 7 */ + +#define LSM9DS1_CTRL_REG7_XL_HPIS1 (1 << 0) /* High-pass filter enabled */ +#define LSM9DS1_CTRL_REG7_XL_FDS (1 << 2) /* Filtered data selection */ +#define LSM9DS1_CTRL_REG7_XL_DCF_SHIFT 5 /* Accelerometer digital filter cutoff frequency selection */ +#define LSM9DS1_CTRL_REG7_XL_DCF_MASK (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT) +# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV50 (0 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT) +# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV100 (1 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT) +# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV9 (2 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT) +# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV400 (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT) +#define LSM9DS1_CTRL_REG7_XL_HR (1 << 7) /* High resolution mode enable */ + +/* Control register 8 */ + +#define LSM9DS1_CTRL_REG8_SW_RESET (1 << 0) /* Software reset */ +#define LSM9DS1_CTRL_REG8_BLE (1 << 1) /* Big/little endian data selection */ +#define LSM9DS1_CTRL_REG8_IF_ADD_INC (1 << 2) /* Register address automatically incremented during a multibyte access */ +#define LSM9DS1_CTRL_REG8_SIM (1 << 3) /* SPI serial interface mode selection */ +#define LSM9DS1_CTRL_REG8_PP_OD (1 << 4) /* Push-pull/open-drain selection on the INT1_A/G and INT2_A/G pins */ +#define LSM9DS1_CTRL_REG8_H_LACTIVE (1 << 5) /* Interrupt activation level */ +#define LSM9DS1_CTRL_REG8_BDU (1 << 6) /* Block data update */ +#define LSM9DS1_CTRL_REG8_BOOT (1 << 7) /* Reboot memory content */ + +/* Control register 9 */ + +#define LSM9DS1_CTRL_REG9_STOP_ON_FTH (1 << 0) /* Enable FIFO threshold level use */ +#define LSM9DS1_CTRL_REG9_FIFO_EN (1 << 1) /* FIFO memory enable */ +#define LSM9DS1_CTRL_REG9_I2C_DISABLE (1 << 2) /* Disable I2C interface */ +#define LSM9DS1_CTRL_REG9_DRDY_MASK_BIT (1 << 3) /* Data available enable bit */ +#define LSM9DS1_CTRL_REG9_FIFO_TEMP_EN (1 << 4) /* Temperature data storage in FIFO enable */ +#define LSM9DS1_CTRL_REG9_SLEEP_G (1 << 6) /* Gyroscope sleep mode enable */ + +/* Control register 10 */ + +#define LSM9DS1_CTRL_REG10_ST_XL (1 << 0) /* Linear acceleration sensor self-test enable */ +#define LSM9DS1_CTRL_REG10_ST_G (1 << 2) /* Angular rate sensor self-test enable */ + +/* Accelerometer interrupt source register */ + +#define LSM9DS1_INT_GEN_SRC_XL_XL_XL (1 << 0) /* Accelerometer's X low event */ +#define LSM9DS1_INT_GEN_SRC_XL_XH_XL (1 << 1) /* Accelerometer's X high event */ +#define LSM9DS1_INT_GEN_SRC_XL_YL_XL (1 << 2) /* Accelerometer's Y low event */ +#define LSM9DS1_INT_GEN_SRC_XL_YH_XL (1 << 3) /* Accelerometer's Y high event */ +#define LSM9DS1_INT_GEN_SRC_XL_ZL_XL (1 << 4) /* Accelerometer's Z low event */ +#define LSM9DS1_INT_GEN_SRC_XL_ZH_XL (1 << 5) /* Accelerometer's Z high event */ +#define LSM9DS1_INT_GEN_SRC_XL_IA_XL (1 << 6) /* Interrupt active */ + +/* Status register 2 */ + +#define LSM9DS1_STATUS_REG2_XLDA (1 << 0) /* Accelerometer new data available */ +#define LSM9DS1_STATUS_REG2_GDA (1 << 1) /* Gyroscope new data available */ +#define LSM9DS1_STATUS_REG2_TDA (1 << 2) /* Temperature sensor new data available */ +#define LSM9DS1_STATUS_REG2_BOOT_STATUS (1 << 3) /* Boot running flag signal */ +#define LSM9DS1_STATUS_REG2_INACT (1 << 4) /* Inactivity interrupt output signal */ +#define LSM9DS1_STATUS_REG2_IG_G (1 << 5) /* Gyroscope interrupt output signal */ +#define LSM9DS1_STATUS_REG2_IG_XL (1 << 6) /* Accelerometer interrupt output signal */ + +/* FIFO control register */ + +#define LSM9DS1_FIFO_CTRL_FTH_SHIFT 0 /* FIFO threshold level setting */ +#define LSM9DS1_FIFO_CTRL_FTH_MASK (31 << LSM9DS1_FIFO_CTRL_FTH_SHIFT) +#define LSM9DS1_FIFO_CTRL_FMODE_SHIFT 5 /* FIFO mode selection bits */ +#define LSM9DS1_FIFO_CTRL_FMODE_MASK (7 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) +# define LSM9DS1_FIFO_CTRL_FMODE_BYPASS (0 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass mode */ +# define LSM9DS1_FIFO_CTRL_FMODE_FIFO (1 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* FIFO mode */ +# define LSM9DS1_FIFO_CTRL_FMODE_CONT_FIFO (3 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous-to-FIFO mode */ +# define LSM9DS1_FIFO_CTRL_FMODE_BYPASS_CONT (4 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass-to-continuous mode */ +# define LSM9DS1_FIFO_CTRL_FMODE_CONT (5 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous mode */ + +/* FIFO status control register */ + +#define LSM9DS1_FIFO_SRC_FSS_SHIFT 0 /* Number of unread samples stored into FIFO */ +#define LSM9DS1_FIFO_SRC_FSS_MASK (63 << LSM9DS1_FIFO_SRC_FSS_SHIFT) +#define LSM9DS1_FIFO_SRC_OVRN (1 << 6) /* FIFO overrun status */ +#define LSM9DS1_FIFO_SRC_FTH (1 << 7) /* FIFO threshold status */ + +/* Gyroscope interrupt configuration register */ + +#define LSM9DS1_INT_GEN_CFG_G_XLIE_G (1 << 0) /* Pitch (X) axis low event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_XHIE_G (1 << 1) /* Pitch (X) axis high event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_YLIE_G (1 << 2) /* Roll (Y) axis low event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_YHIE_G (1 << 3) /* Roll (Y) axis high event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_ZLIE_G (1 << 4) /* Yaw (Z) axis low event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_ZHIE_G (1 << 5) /* Yaw (Z) axis high event interrupt enable */ +#define LSM9DS1_INT_GEN_CFG_G_LIR_G (1 << 6) /* Latch interrupt request */ +#define LSM9DS1_INT_GEN_CFG_G_AOI_G (1 << 7) /* AND/OR combination of interrupt events */ + +/* Gyroscope interrupt threshold registers */ + +#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT 0 /* X interrupt threshold high byte */ +#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_MASK (127 << LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT) +#define LSM9DS1_INT_GEN_THS_XH_G_DCRM_G (1 << 7) /* Decrement or reset counter mode selection */ + +/* Gyroscope interrupt duration register */ + +#define LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT 0 /* Enter/exit interrupt duration */ +#define LSM9DS1_INT_GEN_DUR_G_DUR_G_MASK (127 << LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT) +#define LSM9DS1_INT_GEN_DUR_G_WAIT_G (1 << 7) /* Exit from interrupt wait function enable */ + +/* Device identification register */ + +#define LSM9DS1_WHO_AM_I_M_VALUE 0x3d + +/* Magnetometer control register 1 */ + +#define LSM9DS1_CTRL_REG1_M_ST (1 << 0) /* Self-test enable */ +#define LSM9DS1_CTRL_REG1_M_FAST_ODR (1 << 1) /* Enable data rates higher than 80 Hz */ +#define LSM9DS1_CTRL_REG1_M_DO_SHIFT 2 /* Output data rate selection */ +#define LSM9DS1_CTRL_REG1_M_DO_MASK (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) +# define LSM9DS1_CTRL_REG1_M_DO_0p625HZ (0 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 0.625 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_1p25HZ (1 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 1.25 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_2p5HZ (2 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 2.5 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_5HZ (3 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 5 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_10HZ (4 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 10 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_20HZ (5 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 20 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_40HZ (6 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 40 Hz */ +# define LSM9DS1_CTRL_REG1_M_DO_80HZ (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 80 Hz */ +#define LSM9DS1_CTRL_REG1_M_OM_SHIFT 5 /* X and Y axes operative mode selection */ +#define LSM9DS1_CTRL_REG1_M_OM_MASK (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) +# define LSM9DS1_CTRL_REG1_M_OM_LOW (0 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Low-power mode */ +# define LSM9DS1_CTRL_REG1_M_OM_MEDIUM (1 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Medium-performance mode */ +# define LSM9DS1_CTRL_REG1_M_OM_HIGH (2 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* High-performance mode */ +# define LSM9DS1_CTRL_REG1_M_OM_ULTRAHIGH (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Ultra-high performance mode */ +#define LSM9DS1_CTRL_REG1_M_TEMP_COMP (1 << 7) /* Temperature compensation enable */ + +/* Magnetometer control register 2 */ + +#define LSM9DS1_CTRL_REG2_M_SOFT_RST (1 << 2) /* Configuration register and user register reset */ +#define LSM9DS1_CTRL_REG2_M_REBOOT (1 << 3) /* Reboot memory content */ +#define LSM9DS1_CTRL_REG2_M_FS_SHIFT 5 /* Full-scale configuration */ +#define LSM9DS1_CTRL_REG2_M_FS_MASK (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) +# define LSM9DS1_CTRL_REG2_M_FS_4GAUSS (0 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 4 gauss */ +# define LSM9DS1_CTRL_REG2_M_FS_8GAUSS (1 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 8 gauss */ +# define LSM9DS1_CTRL_REG2_M_FS_12GAUSS (2 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 12 gauss */ +# define LSM9DS1_CTRL_REG2_M_FS_16GAUSS (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 16 gauss */ + +/* Magnetometer control register 3 */ + +#define LSM9DS1_CTRL_REG3_M_MD_SHIFT 0 /* Operating mode selection */ +#define LSM9DS1_CTRL_REG3_M_MD_MASK (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) +# define LSM9DS1_CTRL_REG3_M_MD_CONT (0 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Continuous-conversion mode */ +# define LSM9DS1_CTRL_REG3_M_MD_SINGLE (1 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Single-conversion mode */ +# define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN (2 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */ +# define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2 (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */ +#define LSM9DS1_CTRL_REG3_M_SIM (1 << 2) /* SPI serial interface mode selection */ +#define LSM9DS1_CTRL_REG3_M_LP (1 << 5) /* Low-power mode configuration */ +#define LSM9DS1_CTRL_REG3_M_I2C_DISABLE (1 << 7) /* Disable I2C interface */ + +/* Magnetometer control register 4 */ + +#define LSM9DS1_CTRL_REG4_M_BLE (1 << 1) /* Big/little endian data selection */ +#define LSM9DS1_CTRL_REG4_M_OMZ_SHIFT 2 /* Z-axis operative mode selection */ +#define LSM9DS1_CTRL_REG4_M_OMZ_MASK (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) +# define LSM9DS1_CTRL_REG4_M_OMZ_LOW (0 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Low-power mode */ +# define LSM9DS1_CTRL_REG4_M_OMZ_MEDIUM (1 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Medium-performance mode */ +# define LSM9DS1_CTRL_REG4_M_OMZ_HIGH (2 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* High-performance mode */ +# define LSM9DS1_CTRL_REG4_M_OMZ_ULTRAHIGH (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Ultra-high performance mode */ + +/* Magnetometer control register 5 */ + +#define LSM9DS1_CTRL_REG5_M_BDU (1 << 6) /* Block data update */ +#define LSM9DS1_CTRL_REG5_M_FAST_READ (1 << 7) /* Fast read enable */ + +/* Magnetometer status register */ + +#define LSM9DS1_STATUS_REG_M_XDA (1 << 0) /* X-axis new data available */ +#define LSM9DS1_STATUS_REG_M_YDA (1 << 1) /* Y-axis new data available */ +#define LSM9DS1_STATUS_REG_M_ZDA (1 << 2) /* Z-axis new data available */ +#define LSM9DS1_STATUS_REG_M_ZYXDA (1 << 3) /* X, Y and Z-axis new data available */ +#define LSM9DS1_STATUS_REG_M_XOR (1 << 4) /* X-axis data overrun */ +#define LSM9DS1_STATUS_REG_M_YOR (1 << 5) /* Y-axis data overrun */ +#define LSM9DS1_STATUS_REG_M_ZOR (1 << 6) /* Z-axis data overrun */ +#define LSM9DS1_STATUS_REG_M_ZYXOR (1 << 7) /* X, Y and Z-axis data overrun */ + +/* Magnetometer interrupt configuration register */ + +#define LSM9DS1_INT_CFG_M_IEN (1 << 0) /* Interrupt enable on the INT_M pin */ +#define LSM9DS1_INT_CFG_M_IEL (1 << 1) /* Latch interrupt request */ +#define LSM9DS1_INT_CFG_M_IEA (1 << 2) /* Interrupt active configuration on INT_MAG */ +#define LSM9DS1_INT_CFG_M_ZIEN (1 << 5) /* Z-axis interrupt enable */ +#define LSM9DS1_INT_CFG_M_YIEN (1 << 6) /* Y-axis interrupt enable */ +#define LSM9DS1_INT_CFG_M_XIEN (1 << 7) /* X-axis interrupt enable */ + +/* Magnetometer interrupt source register */ + +#define LSM9DS1_INT_SRC_M_INT (1 << 0) /* Interrupt occurred */ +#define LSM9DS1_INT_SRC_M_MROI (1 << 1) /* Internal measurement range overflow */ +#define LSM9DS1_INT_SRC_M_NTH_Z (1 << 2) /* Value on Z-axis exceeds threshold on negative side */ +#define LSM9DS1_INT_SRC_M_NTH_Y (1 << 3) /* Value on Y-axis exceeds threshold on negative side */ +#define LSM9DS1_INT_SRC_M_NTH_X (1 << 4) /* Value on X-axis exceeds threshold on negative side */ +#define LSM9DS1_INT_SRC_M_PTH_Z (1 << 5) /* Value on Z-axis exceeds threshold on positive side */ +#define LSM9DS1_INT_SRC_M_PTH_Y (1 << 6) /* Value on Y-axis exceeds threshold on positive side */ +#define LSM9DS1_INT_SRC_M_PTH_X (1 << 7) /* Value on X-axis exceeds threshold on positive side */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct lsm9ds1_dev_s; +struct lsm9ds1_ops_s +{ + CODE int (*config)(FAR struct lsm9ds1_dev_s *priv); + CODE int (*start)(FAR struct lsm9ds1_dev_s *priv); + CODE int (*stop)(FAR struct lsm9ds1_dev_s *priv); + CODE int (*setsamplerate)(FAR struct lsm9ds1_dev_s *priv, + uint32_t samplerate); + CODE int (*setfullscale)(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale); +}; + +struct lsm9ds1_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + + FAR const struct lsm9ds1_ops_s *ops; + + uint32_t samplerate; /* Output data rate */ + uint8_t datareg; /* Output data register of X low byte */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* I2C Helpers */ + +static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval); +static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr, + uint8_t regval); +static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv, + uint8_t regaddr, uint8_t clearbits, + uint8_t setbits); + +/* Other Helpers */ + +static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b); + +/* Accelerometer Operations */ + +static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv, + uint32_t samplerate); +static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale); + +/* Gyroscope Operations */ + +static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale); + +/* Magnetometer Operations */ + +static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv); +static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale); +static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv, + uint32_t samplerate); + +/* Character Driver Methods */ + +static int lsm9ds1_open(FAR struct file *filep); +static int lsm9ds1_close(FAR struct file *filep); +static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t lsm9ds1_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int lsm9ds1_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/* Common Register Function */ + +static int lsm9ds1_register(FAR const char *devpath, + FAR struct i2c_master_s *i2c, uint8_t addr, + FAR const struct lsm9ds1_ops_s *ops, + uint8_t datareg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_fops = +{ + lsm9ds1_open, + lsm9ds1_close, + lsm9ds1_read, + lsm9ds1_write, + NULL, + lsm9ds1_ioctl, +#ifndef CONFIG_DISABLE_POLL + NULL, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + NULL, +#endif +}; + +static const struct lsm9ds1_ops_s g_lsm9ds1accel_ops = +{ + lsm9ds1accelgyro_config, + lsm9ds1accel_start, + lsm9ds1accel_stop, + lsm9ds1accelgyro_setsamplerate, + lsm9ds1accel_setfullscale, +}; + +static const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops = +{ + lsm9ds1accelgyro_config, + lsm9ds1gyro_start, + lsm9ds1gyro_stop, + lsm9ds1accelgyro_setsamplerate, + lsm9ds1gyro_setfullscale, +}; + +static const struct lsm9ds1_ops_s g_lsm9ds1mag_ops = +{ + lsm9ds1mag_config, + lsm9ds1mag_start, + lsm9ds1mag_stop, + lsm9ds1mag_setsamplerate, + lsm9ds1mag_setfullscale, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lsm9ds1_readreg8 + * + * Description: + * Read from an 8-bit register. + * + ****************************************************************************/ + +static int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval) +{ + struct i2c_config_s config; + int ret; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(regval != NULL); + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + /* Restart and read 8 bits from the register */ + + ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval)); + if (ret < 0) + { + sndbg("i2c_read failed: %d\n", ret); + return ret; + } + + snvdbg("addr: %02x value: %02x\n", regaddr, *regval); + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1_writereg8 + * + * Description: + * Write to an 8-bit register. + * + ****************************************************************************/ + +static int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr, + uint8_t regval) +{ + struct i2c_config_s config; + uint8_t buffer[2]; + int ret; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + /* Set up a 2-byte message to send */ + + buffer[0] = regaddr; + buffer[1] = regval; + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address followed by the data (no RESTART) */ + + ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + snvdbg("addr: %02x value: %02x\n", regaddr, regval); + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1_modifyreg8 + * + * Description: + * Modify an 8-bit register. + * + ****************************************************************************/ + +static int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv, uint8_t regaddr, + uint8_t clearbits, uint8_t setbits) +{ + int ret; + uint8_t regval; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + ret = lsm9ds1_readreg8(priv, regaddr, ®val); + if (ret < 0) + { + sndbg("lsm9ds1_readreg8 failed: %d\n", ret); + return ret; + } + + regval &= ~clearbits; + regval |= setbits; + + ret = lsm9ds1_writereg8(priv, regaddr, regval); + if (ret < 0) + { + sndbg("lsm9ds1_writereg8 failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1_midpoint + * + * Description: + * Find the midpoint between two numbers. + * + ****************************************************************************/ + +static uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b) +{ + return (uint32_t)(((uint64_t)a + (uint64_t)b + (uint64_t)1) / (uint64_t)2); +} + +/**************************************************************************** + * Name: lsm9ds1accelgyro_config + * + * Description: + * Configure the accelerometer and gyroscope. + * + ****************************************************************************/ + +static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv) +{ + int ret; + uint8_t regval; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + /* Get the device identification */ + + ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I, ®val); + if (ret < 0) + { + sndbg("lsm9ds1_readreg8 failed: %d\n", ret); + return ret; + } + + if (regval != LSM9DS1_WHO_AM_I_VALUE) + { + sndbg("Invalid device identification %02x\n", regval); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1accel_start + * + * Description: + * Start the accelerometer. + * + ****************************************************************************/ + +static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + if (priv->samplerate < lsm9ds1_midpoint(10, 50)) + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(50, 119)) + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(119, 238)) + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(238, 476)) + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(476, 952)) + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ; + } + else + { + setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL, + LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1accel_stop + * + * Description: + * Stop the accelerometer. + * + ****************************************************************************/ + +static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv) +{ + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL, + LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, + LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN); +} + +/**************************************************************************** + * Name: lsm9ds1accelgyro_setsamplerate + * + * Description: + * Set the accelerometer or gyroscope's sample rate. + * + ****************************************************************************/ + +static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv, + uint32_t samplerate) +{ + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + priv->samplerate = samplerate; + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1accel_setfullscale + * + * Description: + * Set the accelerometer's full-scale range. + * + ****************************************************************************/ + +static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + if (fullscale < lsm9ds1_midpoint(2, 4)) + { + setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_2G; + } + else if (fullscale < lsm9ds1_midpoint(4, 8)) + { + setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_4G; + } + else if (fullscale < lsm9ds1_midpoint(8, 16)) + { + setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_8G; + } + else + { + setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_16G; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL, + LSM9DS1_CTRL_REG6_XL_FS_XL_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1gyro_start + * + * Description: + * Start the gyroscope. + * + ****************************************************************************/ + +static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + if (priv->samplerate < lsm9ds1_midpoint(14, 59)) + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(59, 119)) + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(119, 238)) + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_119HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(238, 476)) + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_238HZ; + } + else if (priv->samplerate < lsm9ds1_midpoint(476, 952)) + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_476HZ; + } + else + { + setbits = LSM9DS1_CTRL_REG1_G_ODR_G_952HZ; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G, + LSM9DS1_CTRL_REG1_G_ODR_G_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1gyro_stop + * + * Description: + * Stop the gyroscope. + * + ****************************************************************************/ + +static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv) +{ + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G, + LSM9DS1_CTRL_REG1_G_ODR_G_MASK, + LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN); +} + +/**************************************************************************** + * Name: lsm9ds1gyro_setfullscale + * + * Description: + * Set the gyroscope's full-scale range. + * + ****************************************************************************/ + +static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + if (fullscale < lsm9ds1_midpoint(245, 500)) + { + setbits = LSM9DS1_CTRL_REG1_G_FS_G_245DPS; + } + else if (fullscale < lsm9ds1_midpoint(500, 2000)) + { + setbits = LSM9DS1_CTRL_REG1_G_FS_G_500DPS; + } + else + { + setbits = LSM9DS1_CTRL_REG1_G_FS_G_2000DPS; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G, + LSM9DS1_CTRL_REG1_G_FS_G_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1mag_config + * + * Description: + * Configure the magnetometer. + * + ****************************************************************************/ + +static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv) +{ + int ret; + uint8_t regval; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + /* Get the device identification */ + + ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I_M, ®val); + if (ret < 0) + { + sndbg("lsm9ds1_readreg8 failed: %d\n", ret); + return ret; + } + + if (regval != LSM9DS1_WHO_AM_I_M_VALUE) + { + sndbg("Invalid device identification %02x\n", regval); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1mag_start + * + * Description: + * Start the magnetometer. + * + ****************************************************************************/ + +static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv) +{ + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M, + LSM9DS1_CTRL_REG3_M_MD_MASK, + LSM9DS1_CTRL_REG3_M_MD_CONT); +} + +/**************************************************************************** + * Name: lsm9ds1mag_stop + * + * Description: + * Stop the magnetometer. + * + ****************************************************************************/ + +static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv) +{ + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M, + LSM9DS1_CTRL_REG3_M_MD_MASK, + LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2); +} + +/**************************************************************************** + * Name: lsm9ds1mag_setfullscale + * + * Description: + * Set the magnetometer's full-scale range. + * + ****************************************************************************/ + +static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv, + uint32_t fullscale) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + if (fullscale < lsm9ds1_midpoint(4, 8)) + { + setbits = LSM9DS1_CTRL_REG2_M_FS_4GAUSS; + } + else if (fullscale < lsm9ds1_midpoint(8, 12)) + { + setbits = LSM9DS1_CTRL_REG2_M_FS_8GAUSS; + } + else if (fullscale < lsm9ds1_midpoint(12, 16)) + { + setbits = LSM9DS1_CTRL_REG2_M_FS_12GAUSS; + } + else + { + setbits = LSM9DS1_CTRL_REG2_M_FS_16GAUSS; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG2_M, + LSM9DS1_CTRL_REG2_M_FS_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1mag_setsamplerate + * + * Description: + * Set the magnetometer's sample rate. + * + ****************************************************************************/ + +static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv, + uint32_t samplerate) +{ + uint8_t setbits; + + /* Sanity check */ + + DEBUGASSERT(priv != NULL); + + /* The magnetometer can change its sample rate without exiting + * power-down mode, so we don't need to save the value for later, + * unlike the accelerometer and gyroscope. + */ + + if (samplerate < lsm9ds1_midpoint(0, 1)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_0p625HZ; + } + else if (samplerate < lsm9ds1_midpoint(1, 2)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_1p25HZ; + } + else if (samplerate < lsm9ds1_midpoint(2, 5)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_2p5HZ; + } + else if (samplerate < lsm9ds1_midpoint(5, 10)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_5HZ; + } + else if (samplerate < lsm9ds1_midpoint(10, 20)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_10HZ; + } + else if (samplerate < lsm9ds1_midpoint(20, 40)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_20HZ; + } + else if (samplerate < lsm9ds1_midpoint(40, 80)) + { + setbits = LSM9DS1_CTRL_REG1_M_DO_40HZ; + } + else + { + setbits = LSM9DS1_CTRL_REG1_M_DO_80HZ; + } + + return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_M, + LSM9DS1_CTRL_REG1_M_DO_MASK, setbits); +} + +/**************************************************************************** + * Name: lsm9ds1_open + * + * Description: + * This method is called when the device is opened. + * + ****************************************************************************/ + +static int lsm9ds1_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1_close + * + * Description: + * This method is called when the device is closed. + * + ****************************************************************************/ + +static int lsm9ds1_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lsm9ds1_read + * + * Description: + * The standard read method. + * + ****************************************************************************/ + +static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode; + FAR struct lsm9ds1_dev_s *priv; + int ret; + size_t i; + size_t j; + size_t samplesize; + size_t nsamples; + uint16_t data; + FAR int16_t *ptr; + uint8_t regaddr; + uint8_t lo; + uint8_t hi; + + /* Sanity check */ + + DEBUGASSERT(filep != NULL); + inode = filep->f_inode; + + DEBUGASSERT(inode != NULL); + priv = (FAR struct lsm9ds1_dev_s *)inode->i_private; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(priv->datareg == LSM9DS1_OUT_X_L_G || + priv->datareg == LSM9DS1_OUT_X_L_XL || + priv->datareg == LSM9DS1_OUT_X_L_M); + DEBUGASSERT(buffer != NULL); + + samplesize = 3 * sizeof(*ptr); + nsamples = buflen / samplesize; + ptr = (FAR int16_t *)buffer; + + /* Get the requested number of samples */ + + for (i = 0; i < nsamples; i++) + { + /* Reset the register address to the X low byte register */ + + regaddr = priv->datareg; + + /* Read the X, Y and Z data */ + + for (j = 0; j < 3; j++) + { + /* Read the low byte */ + + ret = lsm9ds1_readreg8(priv, regaddr, &lo); + if (ret < 0) + { + sndbg("lsm9ds1_readreg8 failed: %d\n", ret); + return (ssize_t)ret; + } + + regaddr++; + + /* Read the high byte */ + + ret = lsm9ds1_readreg8(priv, regaddr, &hi); + if (ret < 0) + { + sndbg("lsm9ds1_readreg8 failed: %d\n", ret); + return (ssize_t)ret; + } + + regaddr++; + + /* The data is 16 bits in two's complement representation */ + + data = ((uint16_t)hi << 8) | (uint16_t)lo; + + /* The value is positive */ + + if (data < 0x8000) + { + ptr[j] = (int16_t)data; + } + + /* The value is negative, so find its absolute value by taking the + * two's complement + */ + + else if (data > 0x8000) + { + data = ~data + 1; + ptr[j] = -(int16_t)data; + } + + /* The value is negative and can't be represented as a positive + * int16_t value + */ + + else + { + ptr[j] = (int16_t)(-32768); + } + } + } + + return nsamples * samplesize; +} + +/**************************************************************************** + * Name: lsm9ds1_write + * + * Description: + * A dummy write method. + * + ****************************************************************************/ + +static ssize_t lsm9ds1_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: lsm9ds1_ioctl + * + * Description: + * The standard ioctl method. + * + ****************************************************************************/ + +static int lsm9ds1_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct lsm9ds1_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(filep != NULL); + inode = filep->f_inode; + + DEBUGASSERT(inode != NULL); + priv = (FAR struct lsm9ds1_dev_s *)inode->i_private; + + DEBUGASSERT(priv != NULL); + + /* Handle ioctl commands */ + + switch (cmd) + { + /* Start converting. Arg: None. */ + + case SNIOC_START: + ret = priv->ops->start(priv); + break; + + /* Stop converting. Arg: None. */ + + case SNIOC_STOP: + ret = priv->ops->stop(priv); + break; + + /* Set the sample rate. Arg: uint32_t value. */ + + case SNIOC_SETSAMPLERATE: + ret = priv->ops->setsamplerate(priv, (uint32_t)arg); + sndbg("sample rate: %08x ret: %d\n", (uint32_t)arg, ret); + break; + + /* Set the full-scale range. Arg: uint32_t value. */ + + case SNIOC_SETFULLSCALE: + ret = priv->ops->setfullscale(priv, (uint32_t)arg); + sndbg("full-scale range: %08x ret: %d\n", (uint32_t)arg, ret); + break; + + /* Unrecognized commands */ + + default: + sndbg("Unrecognized cmd: %d arg: %lu\n", cmd, arg); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: lsm9ds1_register + * + * Description: + * Register the LSM9DS1 accelerometer, gyroscope or magnetometer character + * device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/accel0", + * "/dev/gyro0" or "/dev/mag0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 accelerometer, gyroscope or + * magnetometer. + * ops - The device operations structure. + * datareg - The register address of the low byte of the X-coordinate data. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int lsm9ds1_register(FAR const char *devpath, + FAR struct i2c_master_s *i2c, uint8_t addr, + FAR const struct lsm9ds1_ops_s *ops, + uint8_t datareg) +{ + FAR struct lsm9ds1_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(devpath != NULL); + DEBUGASSERT(i2c != NULL); + DEBUGASSERT(datareg == LSM9DS1_OUT_X_L_XL || + datareg == LSM9DS1_OUT_X_L_G || + datareg == LSM9DS1_OUT_X_L_M); + + /* Initialize the device's structure */ + + priv = (FAR struct lsm9ds1_dev_s *)kmm_malloc(sizeof(*priv)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + priv->ops = ops; + priv->samplerate = 0; + priv->datareg = datareg; + + /* Configure the device */ + + ret = priv->ops->config(priv); + if (ret < 0) + { + sndbg("Failed to configure device: %d\n", ret); + kmm_free(priv); + return ret; + } + + /* Register the character driver */ + + ret = register_driver(devpath, &g_fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lsm9ds1accel_register + * + * Description: + * Register the LSM9DS1 accelerometer character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/accel0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 accelerometer. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1accel_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + /* Sanity check */ + + DEBUGASSERT(addr == LSM9DS1ACCEL_ADDR0 || addr == LSM9DS1ACCEL_ADDR1); + + return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1accel_ops, + LSM9DS1_OUT_X_L_XL); +} + +/**************************************************************************** + * Name: lsm9ds1gyro_register + * + * Description: + * Register the LSM9DS1 gyroscope character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/gyro0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 gyroscope. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1gyro_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + /* Sanity check */ + + DEBUGASSERT(addr == LSM9DS1GYRO_ADDR0 || addr == LSM9DS1GYRO_ADDR1); + + return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1gyro_ops, + LSM9DS1_OUT_X_L_G); +} + +/**************************************************************************** + * Name: lsm9ds1mag_register + * + * Description: + * Register the LSM9DS1 magnetometer character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/mag0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 magnetometer. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1mag_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + /* Sanity check */ + + DEBUGASSERT(addr == LSM9DS1MAG_ADDR0 || addr == LSM9DS1MAG_ADDR1); + + return lsm9ds1_register(devpath, i2c, addr, &g_lsm9ds1mag_ops, + LSM9DS1_OUT_X_L_M); +} + +#endif /* CONFIG_I2C && CONFIG_SN_LSM9DS1 */ diff --git a/drivers/sensors/max31855.c b/drivers/sensors/max31855.c new file mode 100644 index 0000000000000000000000000000000000000000..c239d9688d823ed3cad7305ab2eb08384b3f73e7 --- /dev/null +++ b/drivers/sensors/max31855.c @@ -0,0 +1,293 @@ +/**************************************************************************** + * drivers/sensors/max31855.c + * Character driver for the Maxim MAX31855 Thermocouple-to-Digital Converter + * + * Copyright (C) 2015 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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. + * + ****************************************************************************/ + +/* NOTE: Some Maxim MAX31855 chips have an issue it report value 25% lower + * of real temperature, for more info read this thread: + * http://www.eevblog.com/forum/projects/max31855-temperature-error/ + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_SPI) && defined(CONFIG_MAX31855) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private + ****************************************************************************/ + +#define MAX31855_FAULT (1 << 16) +#define MAX31855_SHORT_VCC (1 << 2) +#define MAX31855_SHORT_GND (1 << 1) +#define MAX31855_OPEN_CIRCUIT (1 << 0) +#define MAX31855_TEMP_COUPLE 0xFFFFC000 +#define MAX31855_TEMP_JUNCTION 0xFFF0 + +struct max31855_dev_s +{ + FAR struct spi_dev_s *spi; /* Saved SPI driver instance */ + int16_t temp; +}; + + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int max31855_open(FAR struct file *filep); +static int max31855_close(FAR struct file *filep); +static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t max31855_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_max31855fops = +{ + max31855_open, + max31855_close, + max31855_read, + max31855_write, + NULL, + NULL +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: max31855_open + * + * Description: + * This function is called whenever the MAX31855 device is opened. + * + ****************************************************************************/ + +static int max31855_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: max31855_close + * + * Description: + * This routine is called when the MAX31855 device is closed. + * + ****************************************************************************/ + +static int max31855_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: max31855_read + ****************************************************************************/ + +static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct max31855_dev_s *priv = inode->i_private; + FAR uint16_t *temp = (FAR uint16_t *) buffer; + int ret = 2; + int32_t regmsb; + int32_t regval; + + /* Check for issues */ + + if (!buffer) + { + sndbg("Buffer is null\n"); + return -EINVAL; + } + + if (buflen != 2) + { + sndbg("You can't read something other than 16 bits (2 bytes)\n"); + return -EINVAL; + } + + /* Enable MAX31855's chip select */ + + SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, true); + + /* Read temperature */ + + SPI_RECVBLOCK(priv->spi, ®msb, 4); + + /* Disable MAX31855's chip select */ + + SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, false); + + regval = (regmsb & 0xFF000000) >> 24; + regval |= (regmsb & 0xFF0000) >> 8; + regval |= (regmsb & 0xFF00) << 8; + regval |= (regmsb & 0xFF) << 24; + + sndbg("Read from MAX31855 = 0x%08X\n", regval); + + /* If negative, fix signal bits */ + + if (regval & 0x80000000) + { + *temp = 0xc000 | (regval >> 18); + } + else + { + *temp = (regval >> 18); + } + + /* Detect any fault */ + + if (regval & MAX31855_FAULT) + { + sndbg("Error: A fault was detected by MAX31855:\n"); + + if (regval & MAX31855_SHORT_VCC) + { + sndbg("The thermocouple input is shorted to VCC!\n"); + } + + if (regval & MAX31855_SHORT_GND) + { + sndbg("The thermocouple input is shorted to GND!\n"); + } + + if (regval & MAX31855_OPEN_CIRCUIT) + { + sndbg("The thermocouple input is not connected!\n"); + } + + ret = -EINVAL; + } + + /* Return two bytes, the temperature is fixed point Q12.2, then divide by 4 + * in your application in other to get real temperature in Celsius degrees. + */ + + return ret; +} + +/**************************************************************************** + * Name: max31855_write + ****************************************************************************/ + +static ssize_t max31855_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: max31855_register + * + * Description: + * Register the MAX31855 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * i2c - An instance of the I2C interface to use to communicate wit + * MAX31855 addr - The I2C address of the MAX31855. The base I2C address + * of the MAX31855 is 0x48. Bits 0-3 can be controlled to get 8 unique + * addresses from 0x48 through 0x4f. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int max31855_register(FAR const char *devpath, FAR struct spi_dev_s *spi) +{ + FAR struct max31855_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(spi != NULL); + + /* Initialize the MAX31855 device structure */ + + priv = (FAR struct max31855_dev_s *)kmm_malloc(sizeof(struct max31855_dev_s)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->spi = spi; + priv->temp = 0; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_max31855fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} +#endif /* CONFIG_SPI && CONFIG_MAX31855 */ diff --git a/drivers/sensors/max6675.c b/drivers/sensors/max6675.c new file mode 100644 index 0000000000000000000000000000000000000000..38aa6c18a7f5e5e467335adbe4243dbf1105d5dc --- /dev/null +++ b/drivers/sensors/max6675.c @@ -0,0 +1,270 @@ +/**************************************************************************** + * drivers/sensors/max6675.c + * Character driver for the Maxim MAX6675 Thermocouple-to-Digital Converter + * + * Copyright (C) 2015 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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. + * + ****************************************************************************/ + +/* NOTE: Some Maxim MAX6675 chips have an issue it report value 25% lower + * of real temperature, for more info read this thread: + * http://www.eevblog.com/forum/projects/max6675-temperature-error/ +*/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_SPI) && defined(CONFIG_MAX6675) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private + ****************************************************************************/ + +#define MAX6675_THREE_STATE (1 << 0) +#define MAX6675_DEV_ID (1 << 1) +#define MAX6675_OPEN_CIRCUIT (1 << 2) +#define MAX6675_TEMP_COUPLE 0x7ff8 + +struct max6675_dev_s +{ + FAR struct spi_dev_s *spi; /* Saved SPI driver instance */ + int16_t temp; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int max6675_open(FAR struct file *filep); +static int max6675_close(FAR struct file *filep); +static ssize_t max6675_read(FAR struct file *, FAR char *, size_t); +static ssize_t max6675_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_max6675fops = +{ + max6675_open, + max6675_close, + max6675_read, + max6675_write, + NULL, + NULL +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: max6675_open + * + * Description: + * This function is called whenever the MAX6675 device is opened. + * + ****************************************************************************/ + +static int max6675_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: max6675_close + * + * Description: + * This routine is called when the MAX6675 device is closed. + * + ****************************************************************************/ + +static int max6675_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: max6675_read + ****************************************************************************/ + +static ssize_t max6675_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct max6675_dev_s *priv = inode->i_private; + FAR uint16_t *temp = (FAR uint16_t *) buffer; + int ret = 2; + int16_t regmsb; + int16_t regval; + + /* Check for issues */ + + if (!buffer) + { + sndbg("Buffer is null\n"); + return -EINVAL; + } + + if (buflen != 2) + { + sndbg("You can't read something other than 16 bits (2 bytes)\n"); + return -EINVAL; + } + + /* Enable MAX6675's chip select */ + + SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, true); + + /* Read temperature */ + + SPI_RECVBLOCK(priv->spi, ®msb, 2); + + /* Disable MAX6675's chip select */ + + SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, false); + + regval = (regmsb & 0xFF00) >> 8; + regval |= (regmsb & 0xFF) << 8; + + sndbg("Read from MAX6675 = 0x%04X\n", regval); + + /* Verify if the device ID bit is really zero */ + + if (regval & MAX6675_DEV_ID) + { + sndbg("ERROR: The Device ID bit needs to be 0 !\n"); + ret = -EINVAL; + } + + /* Detect if termocople input is open */ + + if (regval & MAX6675_OPEN_CIRCUIT) + { + sndbg("The thermocouple input is not connected!\n"); + ret = -EINVAL; + } + + /* Get the temperature */ + + *temp = (regval & MAX6675_TEMP_COUPLE) >> 3; + + /* Return two bytes, the temperature is fixed point Q10.2, then divide by 4 + * in your application in order to get real temperature in Celsius degrees. + */ + + return ret; +} + +/**************************************************************************** + * Name: max6675_write + ****************************************************************************/ + +static ssize_t max6675_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: max6675_register + * + * Description: + * Register the MAX6675 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * spi - An instance of the SPU interface to use to communicate with + * MAX6675. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int max6675_register(FAR const char *devpath, FAR struct spi_dev_s *spi) +{ + FAR struct max6675_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(spi != NULL); + + /* Initialize the MAX6675 device structure */ + + priv = (FAR struct max6675_dev_s *)kmm_malloc(sizeof(struct max6675_dev_s)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->spi = spi; + priv->temp = 0; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_max6675fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} +#endif /* CONFIG_SPI && CONFIG_MAX6675 */ diff --git a/drivers/sensors/mb7040.c b/drivers/sensors/mb7040.c new file mode 100644 index 0000000000000000000000000000000000000000..4308b2f73e7c4acbe3401d8da3a0844370c8ea49 --- /dev/null +++ b/drivers/sensors/mb7040.c @@ -0,0 +1,403 @@ +/**************************************************************************** + * drivers/sensors/mb7040.c + * Character driver for the MaxBotix MB7040 Sonar + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MB7040) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_MB7040_I2C_FREQUENCY +# define CONFIG_MB7040_I2C_FREQUENCY 400000 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mb7040_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* I2C Helpers */ + +static int mb7040_measurerange(FAR struct mb7040_dev_s *priv); +static int mb7040_readrange(FAR struct mb7040_dev_s *priv, + FAR uint16_t *range); +static int mb7040_changeaddr(FAR struct mb7040_dev_s *priv, uint8_t addr); + +/* Character Driver Methods */ + +static int mb7040_open(FAR struct file *filep); +static int mb7040_close(FAR struct file *filep); +static ssize_t mb7040_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t mb7040_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int mb7040_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_fops = +{ + mb7040_open, + mb7040_close, + mb7040_read, + mb7040_write, + NULL, + mb7040_ioctl +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mb7040_measurerange + * + * Description: + * Command the device to measure the range. + * + ****************************************************************************/ + +static int mb7040_measurerange(FAR struct mb7040_dev_s *priv) +{ + struct i2c_config_s config; + uint8_t regaddr; + int ret; + + sndbg("addr: %02x\n", regaddr); + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_MB7040_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + regaddr = MB7040_RANGE_REG; + + ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: mb7040_readrange + * + * Description: + * Read the range last measured by the device. The units are centimeters. + * + ****************************************************************************/ + +static int mb7040_readrange(FAR struct mb7040_dev_s *priv, + FAR uint16_t *range) +{ + struct i2c_config_s config; + uint8_t buffer[2]; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_MB7040_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Read two bytes */ + + ret = i2c_read(priv->i2c, &config, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("i2c_read failed: %d\n", ret); + return ret; + } + + *range = (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1]; + sndbg("range: %04x ret: %d\n", *range, ret); + return ret; +} + +/**************************************************************************** + * Name: mb7040_changeaddr + * + * Description: + * Change the device's I2C address. + * + ****************************************************************************/ + +static int mb7040_changeaddr(FAR struct mb7040_dev_s *priv, uint8_t addr) +{ + struct i2c_config_s config; + uint8_t buffer[3]; + int ret; + + sndbg("new addr: %02x\n", addr); + + /* Sanity check */ + + DEBUGASSERT((addr & 1) == 0); + DEBUGASSERT(addr != 0x00 && addr != 0x50 && addr != 0xa4 && addr != 0xaa); + + /* Set up a 3-byte message to send */ + + buffer[0] = MB7040_ADDRUNLOCK1_REG; + buffer[1] = MB7040_ADDRUNLOCK2_REG; + buffer[2] = addr; + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_MB7040_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address followed by the data (no RESTART) */ + + ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + priv->addr = addr; + return ret; +} + +/**************************************************************************** + * Name: mb7040_open + * + * Description: + * This method is called when the device is opened. + * + ****************************************************************************/ + +static int mb7040_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mb7040_close + * + * Description: + * This method is called when the device is closed. + * + ****************************************************************************/ + +static int mb7040_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mb7040_read + * + * Description: + * A dummy read method. + * + ****************************************************************************/ + +static ssize_t mb7040_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + return 0; +} + +/**************************************************************************** + * Name: mb7040_write + * + * Description: + * A dummy write method. + * + ****************************************************************************/ + +static ssize_t mb7040_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: mb7040_ioctl + * + * Description: + * The standard ioctl method. + * + ****************************************************************************/ + +static int mb7040_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct mb7040_dev_s *priv = inode->i_private; + int ret = OK; + + /* Handle ioctl commands */ + + switch (cmd) + { + /* Command the device to measure the range. Arg: None. */ + + case SNIOC_MEASURE: + DEBUGASSERT(arg == 0); + ret = mb7040_measurerange(priv); + break; + + /* Read the range last measured by the device. Arg: int32_t* pointer. */ + + case SNIOC_RANGE: + { + FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg); + uint16_t range = 0; + DEBUGASSERT(ptr != NULL); + ret = mb7040_readrange(priv, &range); + if (ret == OK) + { + *ptr = (int32_t)range; + } + sndbg("range: %04x ret: %d\n", *ptr, ret); + } + break; + + /* Change the device's I2C address. Arg: uint8_t value. */ + + case SNIOC_CHANGEADDR: + ret = mb7040_changeaddr(priv, (uint8_t)arg); + sndbg("new addr: %02x ret: %d\n", *(uint8_t *)arg, ret); + break; + + /* Unrecognized commands */ + + default: + sndbg("Unrecognized cmd: %d arg: %ld\n", cmd, arg); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mb7040_register + * + * Description: + * Register the MB7040 character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/sonar0". + * i2c - An I2C driver instance. + * addr - The I2C address of the MB7040. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mb7040_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + FAR struct mb7040_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + + /* Initialize the device's structure */ + + priv = (FAR struct mb7040_dev_s *)kmm_malloc(sizeof(*priv)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_MB7040 */ diff --git a/drivers/sensors/mcp9844.c b/drivers/sensors/mcp9844.c new file mode 100644 index 0000000000000000000000000000000000000000..c21e4155606ea97d70d3d5beef0d040118a465cd --- /dev/null +++ b/drivers/sensors/mcp9844.c @@ -0,0 +1,372 @@ +/**************************************************************************** + * drivers/sensors/mcp9844.c + * Character driver for the MCP9844 Temperature Sensor + * + * Copyright (C) 2015 DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MCP9844) + +/**************************************************************************** + * Pre-process Definitions + ****************************************************************************/ + +#ifndef CONFIG_MCP9844_I2C_FREQUENCY +# define CONFIG_MCP9844_I2C_FREQUENCY 400000 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mcp9844_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* I2C helper functions */ + +static int mcp9844_read_u16(FAR struct mcp9844_dev_s *priv, + uint8_t const regaddr, FAR uint16_t *value); +static int mcp9844_write_u16(FAR struct mcp9844_dev_s *priv, + uint8_t const regaddr, uint16_t const regval); + +/* Character driver methods */ + +static int mcp9844_open(FAR struct file *filep); +static int mcp9844_close(FAR struct file *filep); +static ssize_t mcp9844_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t mcp9844_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int mcp9844_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_mcp9844_fops = +{ + mcp9844_open, + mcp9844_close, + mcp9844_read, + mcp9844_write, + NULL, + mcp9844_ioctl +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcp9844_read_u16 + * + * Description: + * Read a 16 bit valie from the MCP9844 at the address regaddr. + * + ****************************************************************************/ + +static int mcp9844_read_u16(FAR struct mcp9844_dev_s *priv, + uint8_t const regaddr, FAR uint16_t *value) +{ + struct i2c_config_s config; + uint8_t buffer[2]; + int ret = -1; + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_MCP9844_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + ret = i2c_write(priv->i2c, &config, ®addr, 1); + if (ret < 0) + { + sndbg ("i2c_write failed: %d\n", ret); + return ret; + } + + /* Restart and read 16-bits from the register */ + + ret = i2c_read(priv->i2c, &config, buffer, 2); + if (ret < 0) + { + sndbg ("i2c_read failed: %d\n", ret); + return ret; + } + + /* Copy the content of the buffer to the location of the uint16_t pointer */ + + *value = (((uint16_t)(buffer[0]))<<8) + ((uint16_t)(buffer[1])); + + sndbg("addr: %02x value: %08x ret: %d\n", regaddr, *value, ret); + return OK; +} + +/**************************************************************************** + * Name: mcp9844_write_u16 + * + * Description: + * Write to a 16-bit register of the MCP9844. + * + ****************************************************************************/ + +static int mcp9844_write_u16(FAR struct mcp9844_dev_s *priv, + uint8_t const regaddr, uint16_t const regval) +{ + struct i2c_config_s config; + + sndbg("addr: %02x value: %08x\n", regaddr, regval); + + /* Set up a 3 byte message to send */ + + uint8_t const BUFFER_SIZE = 3; + uint8_t buffer[BUFFER_SIZE]; + + buffer[0] = regaddr; + buffer[1] = (uint8_t)(regval >> 8); + buffer[2] = (uint8_t)(regval); + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_MCP9844_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address followed by the data (no RESTART) */ + + return i2c_write(priv->i2c, &config, buffer, BUFFER_SIZE); +} + +/**************************************************************************** + * Name: mcp9844_open + * + * Description: + * This function is called whenever the MCP9844 device is opened. + * + ****************************************************************************/ + +static int mcp9844_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mcp9844_close + * + * Description: + * This routine is called when the MCP9844 device is closed. + * + ****************************************************************************/ + +static int mcp9844_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mcp9844_read + ****************************************************************************/ + +static ssize_t mcp9844_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: mcp9844_write + ****************************************************************************/ + +static ssize_t mcp9844_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: lm75_ioctl + ****************************************************************************/ + +static int mcp9844_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct mcp9844_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + /* Read from the ambient temperature register. Arg: uint16_t* pointer */ + + case SNIOC_READTEMP: + { + FAR struct mcp9844_temp_arg_s *temp_result = + (FAR struct mcp9844_temp_arg_s *)((uintptr_t)arg); + + DEBUGASSERT(temp_result != NULL); + + /* Read the ambient temperature value from the device */ + + uint16_t raw_temperature = 0; + ret = mcp9844_read_u16(priv, MCP9844_TEMP_REG, &raw_temperature); + + /* Convert from the proprietary sensor temperature data representation + * to a more user friendly version. + */ + + if (ret == OK) + { + /* BIT15 - 13 contain information if preset temperature values + * have been exceeded or undercut. BIT12 is now not any longer + * needed since we do have the sign information retrieved. + * We do not need them for the temperature so those bits + * need to be masked out. + */ + + raw_temperature &= 0x0FFF; /* 0x0FFF = 0b 0000 1111 1111 1111 */ + + /* The post comma temperature value is encoded in BIT3 to BIT0 */ + + temp_result->temp_post_comma = (uint8_t)(raw_temperature & 0x000F); + + /* The pre comma temperature value is encoded in BIT11 to BIT4 */ + + temp_result->temp_pre_comma = (int8_t)(raw_temperature >> 4); + } + else + { + sndbg("ioctl::SNIOC_READTEMP - mcp9844_read_u16 failed - no temperature retrieved\n"); + } + } + break; + + case SNIOC_SETRESOLUTION: + { + ret = mcp9844_write_u16(priv, MCP9844_RESO_REG, (uint16_t)(arg)); + if (ret != OK) + { + sndbg("ioctl::SNIOC_SETRESOLUTION - mcp9844_write_u16 failed - no resolution set\n"); + } + } + break; + + default: + sndbg("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mcp9844_register + * + * Description: + * Register the MCP9844 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * i2c - An instance of the I2C interface to use to communicate with MCP9844 + * addr - The I2C address of the MCP9844. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mcp9844_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + + /* Initialize the LM-75 device structure */ + + FAR struct mcp9844_dev_s *priv = + (FAR struct mcp9844_dev_s *)kmm_malloc(sizeof(struct mcp9844_dev_s)); + + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + + /* Register the character driver */ + + int ret = register_driver(devpath, &g_mcp9844_fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} +#endif /* CONFIG_I2C && CONFIG_I2C_LM75 */ diff --git a/drivers/sensors/mpl115a.c b/drivers/sensors/mpl115a.c index a5b940ab7b4ee2745bb4469589d889027a6752db..0c4e87414c32a72cd65d044caf3678d225c6f57f 100644 --- a/drivers/sensors/mpl115a.c +++ b/drivers/sensors/mpl115a.c @@ -86,7 +86,8 @@ static int mpl115a_getpressure(FAR struct mpl115a_dev_s *priv); static int mpl115a_open(FAR struct file *filep); static int mpl115a_close(FAR struct file *filep); -static ssize_t mpl115a_read(FAR struct file *, FAR char *, size_t); +static ssize_t mpl115a_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); static ssize_t mpl115a_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); /**************************************************************************** @@ -111,16 +112,15 @@ static const struct file_operations g_mpl115afops = * Private Functions ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static inline void mpl115a_configspi(FAR struct spi_dev_s *spi) { /* Configure SPI for the MPL115A */ SPI_SETMODE(spi, SPIDEV_MODE0); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, MPL115A_SPI_MAXFREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, MPL115A_SPI_MAXFREQUENCY); } -#endif /**************************************************************************** * Name: mpl115a_getreg8 @@ -136,10 +136,8 @@ static uint8_t mpl115a_getreg8(FAR struct mpl115a_dev_s *priv, uint8_t regaddr) /* If SPI bus is shared then lock and configure it */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, true); mpl115a_configspi(priv->spi); -#endif /* Select the MPL115A */ @@ -156,9 +154,7 @@ static uint8_t mpl115a_getreg8(FAR struct mpl115a_dev_s *priv, uint8_t regaddr) /* Unlock bus */ -#ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(priv->spi, false); -#endif #ifdef CONFIG_MPL115A_REGDEBUG dbg("%02x->%02x\n", regaddr, regval); @@ -212,8 +208,6 @@ static void mpl115a_updatecaldata(FAR struct mpl115a_dev_s *priv) static void mpl115a_read_press_temp(FAR struct mpl115a_dev_s *priv) { - uint16_t pressure; - /* Start a new conversion */ mpl115a_getreg8(priv, (MPL115A_CONVERT << 1)); @@ -251,8 +245,8 @@ static int mpl115a_getpressure(FAR struct mpl115a_dev_s *priv) /* Check if coefficient data were read correctly */ - if ( (priv->mpl115a_cal_a0 == 0) || (priv->mpl115a_cal_b1 == 0) || - (priv->mpl115a_cal_b2 == 0) || (priv->mpl115a_cal_c12 == 0) ) + if ((priv->mpl115a_cal_a0 == 0) || (priv->mpl115a_cal_b1 == 0) || + (priv->mpl115a_cal_b2 == 0) || (priv->mpl115a_cal_c12 == 0)) { mpl115a_updatecaldata(priv); } @@ -326,7 +320,7 @@ static ssize_t mpl115a_read(FAR struct file *filep, FAR char *buffer, size_t buf return -1; } - if ( buflen != 2) + if (buflen != 2) { sndbg("You can't read something other than 16 bits (2 bytes)\n"); return -1; diff --git a/drivers/sensors/ms58xx.c b/drivers/sensors/ms58xx.c new file mode 100644 index 0000000000000000000000000000000000000000..410a391a725e0095c14fb8d4b44bac3b81b06999 --- /dev/null +++ b/drivers/sensors/ms58xx.c @@ -0,0 +1,1120 @@ +/**************************************************************************** + * drivers/sensors/ms58xx.c + * Character driver for MEAS MS58XX Altimeters + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * Updated by: Karim Keddam + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MS58XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_MS58XX_I2C_FREQUENCY +# define CONFIG_MS58XX_I2C_FREQUENCY 400000 +#endif + +/* Register Definitions *****************************************************/ +/* Register Addresses */ + +#define MS58XX_RESET_REG 0x1e /* Reset Register */ +#define MS58XX_PRESS_REG 0x40 /* Pressure Register */ +#define MS58XX_TEMP_REG 0x50 /* Temperature Register */ +#define MS58XX_ADC_REG 0x00 /* ADC Register */ +#define MS58XX_PROM_REG 0xa0 /* PROM Register */ + +/* PROM Definitions *********************************************************/ + +#define MS58XX_PROM_LEN 8 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ms58xx_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + + enum ms58xx_model_e model; + uint8_t crcindex; + uint8_t crcshift; + + int32_t temp; /* Uncompensated temperature (degrees Centigrade) */ + int32_t press; /* Uncompensated pressure (millibar) */ + + uint8_t osr; /* Oversampling ratio bits */ + useconds_t delay; /* Oversampling ratio delay */ + + /* Calibration coefficients */ + + uint16_t c1; + uint16_t c2; + uint16_t c3; + uint16_t c4; + uint16_t c5; + uint16_t c6; + uint8_t c7; + uint8_t c8; + + /* Constants used when calculating the temperature and the pressure */ + + uint8_t c1s; + uint8_t c2s; + uint8_t c3s; + uint8_t c4s; + + uint8_t diffmull; + uint8_t diffdivls; + uint8_t offmull; + uint8_t offdivls; + uint8_t sensmull; + uint8_t sensdivls; + + uint8_t offmulvl; + uint8_t sensmulvl; + + uint8_t diffmulh; + uint8_t diffdivhs; + uint8_t offmulh; + uint8_t offdivhs; + uint8_t sensmulh; + uint8_t sensdivhs; + + uint8_t pressdivs; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* CRC Calculation */ + +static uint8_t ms58xx_crc(FAR uint16_t *src, uint8_t crcIndex); + +/* I2C Helpers */ + +static int ms58xx_i2c_write(FAR struct ms58xx_dev_s *priv, + FAR const uint8_t *buffer, int buflen); +static int ms58xx_i2c_read(FAR struct ms58xx_dev_s *priv, + FAR uint8_t *buffer, int buflen); +static int ms58xx_readu16(FAR struct ms58xx_dev_s *priv, uint8_t regaddr, + FAR uint16_t *regval); +static int ms58xx_readadc(FAR struct ms58xx_dev_s *priv, FAR uint32_t *adc); +static int ms58xx_setosr(FAR struct ms58xx_dev_s *priv, uint16_t osr); +static int ms58xx_reset(FAR struct ms58xx_dev_s *priv); +static int ms58xx_readprom(FAR struct ms58xx_dev_s *priv); +static int ms58xx_convert(FAR struct ms58xx_dev_s *priv, uint8_t regaddr, + FAR uint32_t *regval); +static int ms58xx_measure(FAR struct ms58xx_dev_s *priv); + +/* Character Driver Methods */ + +static int ms58xx_open(FAR struct file *filep); +static int ms58xx_close(FAR struct file *filep); +static ssize_t ms58xx_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t ms58xx_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int ms58xx_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_fops = +{ + ms58xx_open, + ms58xx_close, + ms58xx_read, + ms58xx_write, + NULL, + ms58xx_ioctl +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ms58xx_crc + * + * Description: + * Calculate the CRC. + * + ****************************************************************************/ + +static uint8_t ms58xx_crc(FAR uint16_t *src, uint8_t crcIndex) +{ + uint16_t cnt; + uint16_t n_rem; + uint16_t crc_read; + uint8_t n_bit; + + n_rem = 0x00; + crc_read = src[crcIndex]; + src[crcIndex] = (0xff00 & (src[7])); + + for (cnt = 0; cnt < 16; cnt++) + { + if (cnt % 2 == 1) + { + n_rem ^= (uint16_t)((src[cnt >> 1]) & 0x00ff); + } + else + { + n_rem ^= (uint16_t)(src[cnt >> 1] >> 8); + } + + for (n_bit = 8; n_bit > 0; n_bit--) + { + if (n_rem & (0x8000)) + { + n_rem = (n_rem << 1) ^ 0x3000; + } + else + { + n_rem = (n_rem << 1); + } + } + } + + n_rem = (0x000F & (n_rem >> 12)); + src[crcIndex] = crc_read; + return (n_rem ^ 0x00); +} + +/**************************************************************************** + * Name: ms58xx_i2c_write + * + * Description: + * Write to the I2C device. + * + ****************************************************************************/ + +static int ms58xx_i2c_write(FAR struct ms58xx_dev_s *priv, + FAR const uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_MS58XX_I2C_FREQUENCY, + msg.addr = priv->addr; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + +/**************************************************************************** + * Name: ms58xx_i2c_read + * + * Description: + * Read from the I2C device. + * + ****************************************************************************/ + +static int ms58xx_i2c_read(FAR struct ms58xx_dev_s *priv, + FAR uint8_t *buffer, int buflen) +{ + struct i2c_msg_s msg; + + /* Setup for the transfer */ + + msg.frequency = CONFIG_MS58XX_I2C_FREQUENCY, + msg.addr = priv->addr, + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + return I2C_TRANSFER(priv->i2c, &msg, 1); +} + +/**************************************************************************** + * Name: ms58xx_readu16 + * + * Description: + * Read from a 16-bit register. + * + ****************************************************************************/ + +static int ms58xx_readu16(FAR struct ms58xx_dev_s *priv, uint8_t regaddr, + FAR uint16_t *regval) +{ + uint8_t buffer[2]; + int ret; + + sndbg("addr: %02x\n", regaddr); + + /* Write the register address */ + + ret = ms58xx_i2c_write(priv, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + /* Restart and read 16 bits from the register */ + + ret = ms58xx_i2c_read(priv, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("i2c_read failed: %d\n", ret); + return ret; + } + + *regval = (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1]; + sndbg("value: %04x ret: %d\n", *regval, ret); + return ret; +} + +/**************************************************************************** + * Name: ms58xx_readadc + * + * Description: + * Read from the ADC register. + * + ****************************************************************************/ + +static int ms58xx_readadc(FAR struct ms58xx_dev_s *priv, FAR uint32_t *adc) +{ + uint8_t regaddr; + uint8_t buffer[3]; + int ret; + + regaddr = MS58XX_ADC_REG; + sndbg("addr: %02x\n", regaddr); + + /* Write the register address */ + + ret = ms58xx_i2c_write(priv, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + /* Restart and read 24 bits from the register */ + + ret = ms58xx_i2c_read(priv, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("i2c_read failed: %d\n", ret); + return ret; + } + + *adc = (uint32_t)buffer[0] << 16 | + (uint32_t)buffer[1] << 8 | + (uint32_t)buffer[2]; + sndbg("adc: %06x ret: %d\n", *adc, ret); + return ret; +} + +/**************************************************************************** + * Name: ms58xx_setosr + * + * Description: + * Set the oversampling ratio. + * + ****************************************************************************/ + +static int ms58xx_setosr(FAR struct ms58xx_dev_s *priv, uint16_t osr) +{ + int ret = OK; + + sndbg("osr: %04x\n", osr); + + switch (osr) + { + case 256: + priv->delay = 600; + break; + + case 512: + priv->delay = 1170; + break; + + case 1024: + priv->delay = 2280; + break; + + case 2048: + priv->delay = 4540; + break; + + case 4096: + priv->delay = 9040; + break; + + case 8192: + switch (priv->model) + { + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5837_30: + priv->delay = 18080; + break; + + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_07: + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5806_02: + default: + ret = -EINVAL; + break; + } + break; + + default: + ret = -EINVAL; + break; + } + + if (ret == OK) + { + priv->osr = (osr / 256 - 1) * 2; + } + + return ret; +} + +/**************************************************************************** + * Name: ms58xx_readprom + * + * Description: + * Read from the PROM. + * + ****************************************************************************/ + +static int ms58xx_readprom(FAR struct ms58xx_dev_s *priv) +{ + uint16_t prom[MS58XX_PROM_LEN]; + uint8_t crc; + uint8_t crcindex; + uint8_t crcshift; + uint16_t crcmask; + int ret; + int i; + int len = MS58XX_PROM_LEN; + + switch (priv->model) + { + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5837_30: + prom[MS58XX_PROM_LEN-1] = 0; + len--; + crcindex = 0; + crcshift = 12; + break; + + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_07: + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5806_02: + default: + crcindex = 7; + crcshift = 0; + break; + } + + /* We have to wait before the prom is ready is be read */ + + up_udelay(10000); + for (i = 0; i < len; i++) + { + ret = ms58xx_readu16(priv, MS58XX_PROM_REG + i * 2, prom + i); + if (ret < 0) + { + sndbg("ms58xx_readu16 failed: %d\n", ret); + return ret; + } + } + + crcmask = (uint16_t)0xf << crcshift; + crc = (uint8_t)((prom[crcindex] & crcmask) >> crcshift); + + if (crc != ms58xx_crc(prom, crcindex)) + { + sndbg("crc mismatch\n"); + return -ENODEV; + } + + priv->c1 = prom[1]; + priv->c2 = prom[2]; + priv->c3 = prom[3]; + priv->c4 = prom[4]; + priv->c5 = prom[5]; + priv->c6 = prom[6]; + + switch (priv->model) + { + case MS58XX_MODEL_MS5803_07: + priv->c7 = (uint8_t)((prom[7] & 0x03f0) >> 4); + priv->c8 = (uint8_t)((prom[7] & 0xf700) >> 10); + break; + + case MS58XX_MODEL_MS5806_02: + priv->c7 = (uint8_t)((prom[7] & 0x0ff0) >> 4); + priv->c8 = 0; + break; + + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5837_30: + default: + priv->c7 = 0; + priv->c8 = 0; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: ms58xx_reset + * + * Description: + * Reset the device. + * + ****************************************************************************/ + +static int ms58xx_reset(FAR struct ms58xx_dev_s *priv) +{ + uint8_t regaddr; + int ret; + + regaddr = MS58XX_RESET_REG; + sndbg("addr: %02x\n", regaddr); + + /* Write the register address */ + + ret = ms58xx_i2c_write(priv, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + return ret; + } + + /* Check the CRC and read the calibration coefficients */ + + ret = ms58xx_readprom(priv); + if (ret < 0) + { + sndbg("ms58xx_readprom failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: ms58xx_convert + * + * Description: + * Measure the uncompensated temperature or the uncompensated pressure. + * + ****************************************************************************/ + +static int ms58xx_convert(FAR struct ms58xx_dev_s *priv, uint8_t regaddr, + FAR uint32_t *regval) +{ + int ret; + + regaddr |= priv->osr; + sndbg("addr: %02x\n", regaddr); + + /* Write the register address */ + + ret = ms58xx_i2c_write(priv, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("i2c_write failed: %d\n", ret); + } + + /* Wait for the conversion to end */ + + up_udelay(priv->delay); + + /* Read the value from the ADC */ + + ret = ms58xx_readadc(priv, regval); + if (ret < 0) + { + sndbg("ms58xx_readadc failed: %d\n", ret); + return ret; + } + + return ret; +} + +/**************************************************************************** + * Name: ms58xx_measure + * + * Description: + * Measure the compensated temperature and the compensated pressure. + * + ****************************************************************************/ + +static int ms58xx_measure(FAR struct ms58xx_dev_s *priv) +{ + uint32_t rawpress; + uint32_t rawtemp; + int32_t diff; + int32_t temp; + int64_t off; + int64_t sens; + int32_t press; + int64_t diffmul; + int64_t diffdiv; + int64_t offmula; + int64_t offdiva; + int64_t sensmula; + int64_t sensdiva; + int64_t offmulb; + int64_t sensmulb; + int64_t tm; + int64_t tp; + int ret; + + ret = ms58xx_convert(priv, MS58XX_PRESS_REG, &rawpress); + if (ret < 0) + { + sndbg("ms58xx_convert failed: %d\n", ret); + return ret; + } + + ret = ms58xx_convert(priv, MS58XX_TEMP_REG, &rawtemp); + if (ret < 0) + { + sndbg("ms58xx_convert failed: %d\n", ret); + return ret; + } + + diff = (int32_t)rawtemp - (int32_t)priv->c5 * ((int32_t)1 << 8); + temp = (int32_t)((int64_t)2000 + + (int64_t)diff * (int64_t)priv->c6 / ((int64_t)1 << 23)); + + off = (int64_t)priv->c2 * ((int64_t)1 << priv->c2s) + + (int64_t)priv->c4 * (int64_t)diff / ((int64_t)1 << priv->c4s); + sens = (int64_t)priv->c1 * ((int64_t)1 << priv->c1s) + + (int64_t)priv->c3 * (int64_t)diff / ((int64_t)1 << priv->c3s); + + if (temp < 2000) + { + diffmul = (int64_t)priv->diffmull; + diffdiv = (int64_t)1 << priv->diffdivls; + offmula = (int64_t)priv->offmull; + offdiva = (int64_t)1 << priv->offdivls; + sensmula = (int64_t)priv->sensmull; + sensdiva = (int64_t)1 << priv->sensdivls; + + if (temp < -1500) + { + offmulb = (int64_t)priv->offmulvl; + sensmulb = (int64_t)priv->sensmulvl; + } + else + { + offmulb = 0; + sensmulb = 0; + } + } + else + { + diffmul = (int64_t)priv->diffmulh; + diffdiv = (int64_t)1 << priv->diffdivhs; + offmula = (int64_t)priv->offmulh; + offdiva = (int64_t)1 << priv->offdivhs; + sensmula = (int64_t)priv->sensmulh; + sensdiva = (int64_t)1 << priv->sensdivhs; + + offmulb = 0; + sensmulb = 0; + } + + tm = (int64_t)temp - (int64_t)2000; + tm *= tm; + + tp = (int64_t)temp + (int64_t)1500; + tp *= tp; + + off -= offmula * tm / offdiva + offmulb * tp; + sens -= sensmula * tm / sensdiva + sensmulb * tp; + temp -= (int32_t)(diffmul * (int64_t)diff * (int64_t)diff / diffdiv); + + press = (int32_t)(((int64_t)rawpress * sens / ((int64_t)1 << 21) - off) / + ((int64_t)1 << priv->pressdivs)); + + switch (priv->model) + { + case MS58XX_MODEL_MS5803_07: + if (press > 110000) + { + press += (int32_t)((((int64_t)priv->c7 - ((int64_t)1 << 5)) * + (int64_t)100 * ((int64_t)1 << 2) - + ((int64_t)priv->c8 - ((int64_t)1 << 5)) * + ((int64_t)temp - (int64_t)2000) / + ((int64_t)1 << 4)) * + ((int64_t)press - (int64_t)110000) / + (int64_t)49000000); + } + break; + + case MS58XX_MODEL_MS5806_02: +#if CONFIG_MS58XX_VDD >= 22 && CONFIG_MS58XX_VDD <= 30 + press += (int32_t)(((int64_t)30 - (int64_t)CONFIG_MS58XX_VDD) * + (int64_t)priv->c7 / + (((int64_t)1 << 6) * (int64_t)10)); +#endif + break; + + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5837_30: + break; + } + + priv->temp = temp; + priv->press = press; + return ret; +} + +/**************************************************************************** + * Name: ms58xx_open + * + * Description: + * This method is called when the device is opened. + * + ****************************************************************************/ + +static int ms58xx_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: ms58xx_close + * + * Description: + * This method is called when the device is closed. + * + ****************************************************************************/ + +static int ms58xx_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: ms58xx_read + * + * Description: + * A dummy read method. + * + ****************************************************************************/ + +static ssize_t ms58xx_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + return 0; +} + +/**************************************************************************** + * Name: ms58xx_write + * + * Description: + * A dummy write method. + * + ****************************************************************************/ + +static ssize_t ms58xx_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ms58xx_ioctl + * + * Description: + * The standard ioctl method. + * + ****************************************************************************/ + +static int ms58xx_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ms58xx_dev_s *priv = inode->i_private; + int ret = OK; + + /* Handle ioctl commands */ + + switch (cmd) + { + /* Measure the temperature and the pressure. Arg: None. */ + + case SNIOC_MEASURE: + DEBUGASSERT(arg == 0); + ret = ms58xx_measure(priv); + break; + + /* Return the temperature last measured. Arg: int32_t* pointer. */ + + case SNIOC_TEMPERATURE: + { + FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); + *ptr = priv->temp; + sndbg("temp: %08x\n", *ptr); + } + break; + + /* Return the pressure last measured. Arg: int32_t* pointer. */ + + case SNIOC_PRESSURE: + { + FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg); + DEBUGASSERT(ptr != NULL); + *ptr = priv->press; + sndbg("press: %08x\n", *ptr); + } + break; + + /* Reset the device. Arg: None. */ + + case SNIOC_RESET: + DEBUGASSERT(arg == 0); + ret = ms58xx_reset(priv); + break; + + /* Change the oversampling ratio. Arg: uint16_t value. */ + + case SNIOC_OVERSAMPLING: + ret = ms58xx_setosr(priv, (uint16_t)arg); + sndbg("osr: %04x ret: %d\n", *(uint16_t *)arg, ret); + break; + + /* Unrecognized commands */ + + default: + sndbg("Unrecognized cmd: %d arg: %ld\n", cmd, arg); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ms58xx_register + * + * Description: + * Register the MS58XX character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/press0". + * i2c - An I2C driver instance. + * addr - The I2C address of the MS58XX. + * osr - The oversampling ratio. + * model - The MS58XX model. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ms58xx_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr, uint16_t osr, enum ms58xx_model_e model) +{ + FAR struct ms58xx_dev_s *priv; + int ret; + + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + DEBUGASSERT((model == MS58XX_MODEL_MS5803_02 || + model == MS58XX_MODEL_MS5803_05 || + model == MS58XX_MODEL_MS5803_07 || + model == MS58XX_MODEL_MS5803_14 || + model == MS58XX_MODEL_MS5803_30 || + model == MS58XX_MODEL_MS5806_02) && + (addr == MS58XX_ADDR0 || addr == MS58XX_ADDR1) || + (model == MS58XX_MODEL_MS5805_02 || + model == MS58XX_MODEL_MS5837_30) && + addr == MS58XX_ADDR0); + + /* Initialize the device's structure */ + + priv = (FAR struct ms58xx_dev_s *)kmm_malloc(sizeof(*priv)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + priv->model = model; + priv->temp = 0; + priv->press = 0; + + switch (priv->model) + { + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5806_02: + default: + priv->c1s = 16; + priv->c2s = 17; + priv->c3s = 7; + priv->c4s = 6; + break; + + case MS58XX_MODEL_MS5803_05: + priv->c1s = 17; + priv->c2s = 18; + priv->c3s = 7; + priv->c4s = 5; + break; + + case MS58XX_MODEL_MS5803_07: + priv->c1s = 17; + priv->c2s = 18; + priv->c3s = 6; + priv->c4s = 5; + break; + + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5837_30: + priv->c1s = 15; + priv->c2s = 16; + priv->c3s = 8; + priv->c4s = 7; + break; + } + + switch (priv->model) + { + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5806_02: + priv->diffmull = 1; + priv->diffdivls = 31; + priv->offmull = 61; + priv->offdivls = 4; + priv->sensmull = 2; + priv->sensdivls = 0; + + priv->offmulvl = 20; + priv->sensmulvl = 12; + + priv->diffmulh = 0; + priv->diffdivhs = 0; + priv->offmulh = 0; + priv->offdivhs = 0; + priv->sensmulh = 0; + priv->sensdivhs = 0; + break; + + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_07: + priv->diffmull = 3; + priv->diffdivls = 33; + priv->offmull = 3; + priv->offdivls = 3; + priv->sensmull = 7; + priv->sensdivls = 3; + + priv->offmulvl = 0; + priv->sensmulvl = 3; + + priv->diffmulh = 0; + priv->diffdivhs = 0; + priv->offmulh = 0; + priv->offdivhs = 0; + priv->sensmulh = 0; + priv->sensdivhs = 0; + break; + + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5803_30: + priv->diffmull = 3; + priv->diffdivls = 33; + priv->offmull = 3; + priv->offdivls = 1; + priv->sensmull = 5; + priv->sensdivls = 3; + + priv->offmulvl = 7; + priv->sensmulvl = 4; + + priv->diffmulh = 7; + priv->diffdivhs = 37; + priv->offmulh = 1; + priv->offdivhs = 4; + priv->sensmulh = 0; + priv->sensdivhs = 0; + break; + + case MS58XX_MODEL_MS5805_02: + priv->diffmull = 11; + priv->diffdivls = 35; + priv->offmull = 31; + priv->offdivls = 3; + priv->sensmull = 63; + priv->sensdivls = 5; + + priv->offmulvl = 0; + priv->sensmulvl = 0; + + priv->diffmulh = 0; + priv->diffdivhs = 0; + priv->offmulh = 0; + priv->offdivhs = 0; + priv->sensmulh = 0; + priv->sensdivhs = 0; + break; + + case MS58XX_MODEL_MS5837_30: + priv->diffmull = 3; + priv->diffdivls = 33; + priv->offmull = 3; + priv->offdivls = 1; + priv->sensmull = 5; + priv->sensdivls = 3; + + priv->offmulvl = 7; + priv->sensmulvl = 4; + + priv->diffmulh = 2; + priv->diffdivhs = 37; + priv->offmulh = 1; + priv->offdivhs = 4; + priv->sensmulh = 0; + priv->sensdivhs = 0; + break; + } + + switch (priv->model) + { + case MS58XX_MODEL_MS5803_02: + case MS58XX_MODEL_MS5803_05: + case MS58XX_MODEL_MS5803_14: + case MS58XX_MODEL_MS5805_02: + case MS58XX_MODEL_MS5806_02: + default: + priv->pressdivs = 15; + break; + + case MS58XX_MODEL_MS5803_30: + case MS58XX_MODEL_MS5837_30: + priv->pressdivs = 13; + break; + } + + ret = ms58xx_setosr(priv, osr); + if (ret < 0) + { + sndbg("ms58xx_setosr failed: %d\n", ret); + goto err; + } + + ret = ms58xx_reset(priv); + if (ret < 0) + { + sndbg("ms58xx_reset failed: %d\n", ret); + goto err; + } + + /* Register the character driver */ + + ret = register_driver(devpath, &g_fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + goto err; + } + + return ret; + +err: + kmm_free(priv); + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_MS58XX */ diff --git a/drivers/sensors/qencoder.c b/drivers/sensors/qencoder.c index f550beeeae023bdd7740b647b6e05941e8756300..34cb029d4c3f32968c25f2e898e57426d540e8c6 100644 --- a/drivers/sensors/qencoder.c +++ b/drivers/sensors/qencoder.c @@ -231,10 +231,9 @@ static int qe_close(FAR struct file *filep) lower->ops->shutdown(lower); } - ret = OK; -//errout_with_sem: sem_post(&upper->exclsem); + ret = OK; errout: return ret; @@ -243,7 +242,7 @@ errout: /************************************************************************************ * Name: qe_read * - * Description: + * Description:O * A dummy read method. This is provided only to satsify the VFS layer. * ************************************************************************************/ diff --git a/drivers/sensors/zerocross.c b/drivers/sensors/zerocross.c new file mode 100644 index 0000000000000000000000000000000000000000..980ffdd86ca5a6390dfc77312dcf539c21feec1b --- /dev/null +++ b/drivers/sensors/zerocross.c @@ -0,0 +1,546 @@ +/**************************************************************************** + * drivers/sensors/zerocross.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_ZEROCROSS + +#ifdef CONFIG_DISABLE_SIGNALS +#error "This driver needs SIGNAL support, remove CONFIG_DISABLE_SIGNALS" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* This structure describes the state of the upper half driver */ + +struct zc_upperhalf_s +{ + FAR struct zc_lowerhalf_s *lower; /* lower-half state */ + sem_t exclsem; /* Supports mutual exclusion */ + + /* The following is a singly linked list of open references to the + * zero cross device. + */ + + FAR struct zc_open_s *zu_open; + +}; + +/* This structure describes the state of one open zero cross driver instance */ + +struct zc_open_s +{ + /* Supports a singly linked list */ + + FAR struct zc_open_s *do_flink; + + /* The following will be true if we are closing */ + + volatile bool do_closing; + + /* Zero cross event notification information */ + + pid_t do_pid; + struct zc_notify_s do_notify; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int zc_open(FAR struct file *filep); +static int zc_close(FAR struct file *filep); +static ssize_t zc_read(FAR struct file *filep, FAR char *buffer, size_t + buflen); +static ssize_t zc_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int zc_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +static void zerocross_enable(FAR struct zc_upperhalf_s *priv); +static void zerocross_interrupt(FAR const struct zc_lowerhalf_s *lower, + FAR void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_zcops = +{ + zc_open, /* open */ + zc_close, /* close */ + zc_read, /* read */ + zc_write, /* write */ + 0, /* seek */ + zc_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +}; + +volatile int sample = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: zerocross_enable + ****************************************************************************/ + +static void zerocross_enable(FAR struct zc_upperhalf_s *priv) +{ + FAR const struct zc_lowerhalf_s *lower; + irqstate_t flags; + + DEBUGASSERT(priv && priv->lower); + lower = priv->lower; + + /* This routine is called both task level and interrupt level, so + * interrupts must be disabled. + */ + + flags = enter_critical_section(); + + /* Enable interrupts */ + + DEBUGASSERT(lower->zc_enable); + + /* Enable interrupts with the new button set */ + + lower->zc_enable(lower, (zc_interrupt_t)zerocross_interrupt, priv); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: zerocross_interrupt + ****************************************************************************/ + +static void zerocross_interrupt(FAR const struct zc_lowerhalf_s *lower, + FAR void *arg) +{ + FAR struct zc_upperhalf_s *priv = (FAR struct zc_upperhalf_s *)arg; + FAR struct zc_open_s *opriv; + irqstate_t flags; + + /* This routine is called both task level and interrupt level, so + * interrupts must be disabled. + */ + + flags = enter_critical_section(); + + /* Update sample value */ + + sample++; + + /* Visit each opened reference and notify a zero cross event */ + + for (opriv = priv->zu_open; opriv; opriv = opriv->do_flink) + { + /* Signal the waiter */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; + value.sival_int = (int)sample; + (void)sigqueue(opriv->do_pid, opriv->do_notify.zc_signo, value); +#else + (void)sigqueue(opriv->do_pid, opriv->do_notify.zc_signo, + (FAR void *)sample); +#endif + } + + leave_critical_section(flags); +} + +/************************************************************************************ + * Name: zc_open + * + * Description: + * This function is called whenever the PWM device is opened. + * + ************************************************************************************/ + +static int zc_open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct zc_upperhalf_s *priv; + FAR const struct zc_lowerhalf_s *lower; + FAR struct zc_open_s *opriv; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct zc_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the driver structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + snvdbg("ERROR: sem_wait failed: %d\n", ret); + return ret; + } + + /* Allocate a new open structure */ + + opriv = (FAR struct zc_open_s *)kmm_zalloc(sizeof(struct zc_open_s)); + if (!opriv) + { + snvdbg("ERROR: Failled to allocate open structure\n"); + ret = -ENOMEM; + goto errout_with_sem; + } + + /* Attach the open structure to the device */ + + opriv->do_flink = priv->zu_open; + priv->zu_open = opriv; + + /* Attach the open structure to the file structure */ + + filep->f_priv = (FAR void *)opriv; + ret = OK; + +errout_with_sem: + sem_post(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: zc_close + * + * Description: + * This function is called when the PWM device is closed. + * + ************************************************************************************/ + +static int zc_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct zc_upperhalf_s *priv; + FAR struct zc_open_s *opriv; + FAR struct zc_open_s *curr; + FAR struct zc_open_s *prev; + irqstate_t flags; + bool closing; + int ret; + + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private); + priv = (FAR struct zc_upperhalf_s *)inode->i_private; + + /* Handle an improbable race conditions with the following atomic test + * and set. + * + * This is actually a pretty feeble attempt to handle this. The + * improbable race condition occurs if two different threads try to + * close the zero cross driver at the same time. The rule: don't do + * that! It is feeble because we do not really enforce stale pointer + * detection anyway. + */ + + flags = enter_critical_section(); + closing = opriv->do_closing; + opriv->do_closing = true; + leave_critical_section(flags); + + if (closing) + { + /* Another thread is doing the close */ + + return OK; + } + + /* Get exclusive access to the driver structure */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + snvdbg("ERROR: sem_wait failed: %d\n", ret); + return ret; + } + + /* Find the open structure in the list of open structures for the device */ + + for (prev = NULL, curr = priv->zu_open; + curr && curr != opriv; + prev = curr, curr = curr->do_flink); + + DEBUGASSERT(curr); + if (!curr) + { + snvdbg("ERROR: Failed to find open entry\n"); + ret = -ENOENT; + goto errout_with_exclsem; + } + + /* Remove the structure from the device */ + + if (prev) + { + prev->do_flink = opriv->do_flink; + } + else + { + priv->zu_open = opriv->do_flink; + } + + /* And free the open structure */ + + kmm_free(opriv); + + /* Enable/disable interrupt handling */ + + zerocross_enable(priv); + ret = OK; + +errout_with_exclsem: + sem_post(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: zc_read + * + * Description:O + * A dummy read method. This is provided only to satsify the VFS layer. + * + ************************************************************************************/ + +static ssize_t zc_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + /* Return zero -- usually meaning end-of-file */ + + return 0; +} + +/************************************************************************************ + * Name: zc_write + * + * Description: + * A dummy write method. This is provided only to satsify the VFS layer. + * + ************************************************************************************/ + +static ssize_t zc_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + /* Return a failure */ + + return -EPERM; +} + +/************************************************************************************ + * Name: zc_ioctl + * + * Description: + * The standard ioctl method. This is where ALL of the PWM work is done. + * + ************************************************************************************/ + +static int zc_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct zc_upperhalf_s *priv; + FAR struct zc_open_s *opriv; + FAR struct zc_lowerhalf_s *lower; + int ret; + + snvdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(filep && filep->f_priv && filep->f_inode); + opriv = filep->f_priv; + inode = filep->f_inode; + DEBUGASSERT(inode->i_private) + priv = (FAR struct zc_upperhalf_s *)inode->i_private; + + /* Get exclusive access to the device structures */ + + ret = sem_wait(&priv->exclsem); + if (ret < 0) + { + return ret; + } + + /* Handle built-in ioctl commands */ + + ret = -EINVAL; + switch (cmd) + { +#ifndef CONFIG_DISABLE_SIGNALS + /* Command: ZCIOC_REGISTER + * Description: Register to receive a signal whenever there is zero + * cross detection interrupt. + * Argument: A read-only pointer to an instance of struct + * zc_notify_s + * Return: Zero (OK) on success. Minus one will be returned on + * failure with the errno value set appropriately. + */ + + case ZCIOC_REGISTER: + { + FAR struct zc_notify_s *notify = + (FAR struct zc_notify_s *)((uintptr_t)arg); + + if (notify) + { + /* Save the notification events */ + + opriv->do_notify.zc_signo = notify->zc_signo; + opriv->do_pid = getpid(); + + /* Enable/disable interrupt handling */ + + zerocross_enable(priv); + ret = OK; + } + } + break; +#endif + + default: + { + snvdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg); + ret = -ENOTTY; + } + break; + } + + sem_post(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: zc_register + * + * Description: + * Register the Zero Cross lower half device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/zc0" + * lower - An instance of the lower half interface + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. The following + * possible error values may be returned (most are returned by + * register_driver()): + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ + +int zc_register(FAR const char *devname, FAR struct zc_lowerhalf_s *lower) +{ + FAR struct zc_upperhalf_s *priv; + int ret; + + DEBUGASSERT(devname && lower); + + /* Allocate a new zero cross driver instance */ + + priv = (FAR struct zc_upperhalf_s *) + kmm_zalloc(sizeof(struct zc_upperhalf_s)); + + if (!priv) + { + snvdbg("ERROR: Failed to allocate device structure\n"); + return -ENOMEM; + } + + /* Make sure that zero cross interrupt is disabled */ + + DEBUGASSERT(lower->zc_enable); + lower->zc_enable(lower, NULL, NULL); + + /* Initialize the new zero cross driver instance */ + + priv->lower = lower; + sem_init(&priv->exclsem, 0, 1); + + /* And register the zero cross driver */ + + ret = register_driver(devname, &g_zcops, 0666, priv); + if (ret < 0) + { + snvdbg("ERROR: register_driver failed: %d\n", ret); + sem_destroy(&priv->exclsem); + kmm_free(priv); + } + + return ret; +} + +#endif /* CONFIG_ZEROCROSS */ diff --git a/drivers/sercomm/console.c b/drivers/sercomm/console.c index c066e8fe7ae89aa2c2d6a588aedde5c5029cfead..53b321964f7a6adcdab311bef5ee9c159e3dc44f 100644 --- a/drivers/sercomm/console.c +++ b/drivers/sercomm/console.c @@ -35,7 +35,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - **************************************************************************/ + ****************************************************************************/ #include #include @@ -49,16 +49,6 @@ #include "uart.h" #include -/* stubs to make serial driver happy */ - -void sercomm_recvchars(void *a) { } -void sercomm_xmitchars(void *a) { } - -/* Stubs to make memory allocator happy */ - -void cons_puts(void *foo){} -void delay_ms(int ms){} - /************************************************************************************ * Fileops Prototypes and Structures ************************************************************************************/ @@ -102,7 +92,8 @@ static void recv_cb(uint8_t dlci, struct msgb *msg) * Fileops ****************************************************************************/ -/* XXX: recvmsg is overwritten when multiple msg arrive! */ +/* REVISIT: recvmsg is overwritten when multiple msg arrive! */ + static ssize_t sc_console_read(file_t *filep, FAR char *buffer, size_t buflen) { size_t len; @@ -130,7 +121,7 @@ static ssize_t sc_console_read(file_t *filep, FAR char *buffer, size_t buflen) return len; } -/* XXX: redirect to old Osmocom-BB comm/sercomm_cons.c -> 2 buffers */ +/* REVISIT: redirect to old Osmocom-BB comm/sercomm_cons.c -> 2 buffers */ extern int sercomm_puts(const char *s); @@ -180,7 +171,7 @@ static int sc_console_ioctl(struct file *filep, int cmd, unsigned long arg) int sercomm_register(FAR const char *path, FAR uart_dev_t *dev) { - /* XXX: initialize MODEMUART to be used for sercomm*/ + /* REVISIT: initialize MODEMUART to be used for sercomm */ uart_init(SERCOMM_UART_NR, 1); uart_baudrate(SERCOMM_UART_NR, UART_115200); @@ -199,3 +190,23 @@ int sercomm_register(FAR const char *path, FAR uart_dev_t *dev) dbg("Registering %s\n", path); return register_driver(path, &g_sercom_console_ops, 0666, NULL); } + +/* Stubs to make serial driver happy */ + +void sercomm_recvchars(void *a) +{ +} + +void sercomm_xmitchars(void *a) +{ +} + +/* Stubs to make memory allocator happy */ + +void cons_puts(void *foo) +{ +} + +void delay_ms(int ms) +{ +} diff --git a/drivers/sercomm/uart.c b/drivers/sercomm/uart.c index 3cf52f7dbb3b309abdf01212a3bfba27a8632f44..9e257455a89c62631c921e8c6deee80f0549bc5c 100644 --- a/drivers/sercomm/uart.c +++ b/drivers/sercomm/uart.c @@ -32,7 +32,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - **************************************************************************/ + ****************************************************************************/ #include #include @@ -46,7 +46,6 @@ #include #include -//#include #include #include "uart.h" @@ -269,8 +268,6 @@ static void uart_irq_handler_cons(__unused enum irq_nr irqnr) const uint8_t uart = CONS_UART_NR; uint8_t iir; - //uart_putchar_nb(uart, 'U'); - iir = uart_reg_read(uart, IIR); if (iir & IIR_INT_PENDING) { @@ -313,8 +310,6 @@ static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr, __unused void * const uint8_t uart = SERCOMM_UART_NR; uint8_t iir, ch; - //uart_putchar_nb(uart, 'U'); - iir = uart_reg_read(uart, IIR); if (iir & IIR_INT_PENDING) { @@ -422,7 +417,7 @@ void uart_init(uint8_t uart, uint8_t interrupts) #if 0 if (uart == 1) { - /* assign UART to MCU and unmask interrupts*/ + /* assign UART to MCU and unmask interrupts */ writeb(UART_REG_UIR, 0x00); } @@ -454,7 +449,7 @@ void uart_init(uint8_t uart, uint8_t interrupts) /* THR interrupt only when TX FIFO and TX shift register are empty */ - uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); + uart_reg_write(uart, SCR, (1 << 0)); /* | (1 << 3)); */ /* 8 bit, 1 stop bit, no parity, no break */ @@ -570,7 +565,6 @@ int uart_getchar_nb(uint8_t uart, uint8_t *ch) } *ch = readb(UART_REG(uart, RHR)); - //printf("getchar_nb(%u) = %02x\n", uart, *ch); return 1; } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6e7d7865e5543d7110fd16ab534a8244836179ad..ec333bc0d811dd8a381e6e27b8fa4906b99df35e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -540,6 +540,10 @@ config SERIAL_OFLOWCONTROL bool default n +config SERIAL_DMA + bool + default n + config SERIAL_IFLOWCONTROL_WATERMARKS bool "RX flow control watermarks" default n @@ -762,6 +766,13 @@ config UART_OFLOWCONTROL ---help--- Enable UART CTS flow control +config UART_DMA + bool "UART DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART + endmenu menu "UART0 Configuration" @@ -820,6 +831,13 @@ config UART0_OFLOWCONTROL ---help--- Enable UART0 CTS flow control +config UART0_DMA + bool "UART0 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART0 + endmenu menu "USART0 Configuration" @@ -878,6 +896,13 @@ config USART0_OFLOWCONTROL ---help--- Enable USART0 CTS flow control +config USART0_DMA + bool "USART0 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART0 + endmenu menu "UART1 Configuration" @@ -936,6 +961,13 @@ config UART1_OFLOWCONTROL ---help--- Enable UART1 CTS flow control +config UART1_DMA + bool "UART1 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART1 + endmenu menu "USART1 Configuration" @@ -994,6 +1026,13 @@ config USART1_OFLOWCONTROL ---help--- Enable USART1 CTS flow control +config USART1_DMA + bool "USART1 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART1 + endmenu menu "UART2 Configuration" @@ -1052,6 +1091,13 @@ config UART2_OFLOWCONTROL ---help--- Enable UART2 CTS flow control +config UART2_DMA + bool "UART2 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART2 + endmenu menu "USART2 Configuration" @@ -1110,6 +1156,12 @@ config USART2_OFLOWCONTROL ---help--- Enable USART2 CTS flow control +config USART2_DMA + bool "USART2 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART2 endmenu menu "UART3 Configuration" @@ -1168,6 +1220,13 @@ config UART3_OFLOWCONTROL ---help--- Enable UART3 CTS flow control +config UART3_DMA + bool "UART3 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART3 + endmenu menu "USART3 Configuration" @@ -1226,6 +1285,13 @@ config USART3_OFLOWCONTROL ---help--- Enable USART3 CTS flow control +config USART3_DMA + bool "USART3 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART3 + endmenu menu "UART4 Configuration" @@ -1284,6 +1350,13 @@ config UART4_OFLOWCONTROL ---help--- Enable UART4 CTS flow control +config UART4_DMA + bool "UART4 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART4 + endmenu menu "USART4 Configuration" @@ -1342,6 +1415,13 @@ config USART4_OFLOWCONTROL ---help--- Enable USART4 CTS flow control +config USART4_DMA + bool "USART4 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART4 + endmenu menu "UART5 Configuration" @@ -1400,6 +1480,13 @@ config UART5_OFLOWCONTROL ---help--- Enable UART5 CTS flow control +config UART5_DMA + bool "UART5 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART5 + endmenu menu "USART5 Configuration" @@ -1458,6 +1545,13 @@ config USART5_OFLOWCONTROL ---help--- Enable USART5 CTS flow control +config USART5_DMA + bool "USART5 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART5 + endmenu menu "USART6 Configuration" @@ -1516,6 +1610,13 @@ config USART6_OFLOWCONTROL ---help--- Enable USART6 CTS flow control +config USART6_DMA + bool "USART6 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART6 + endmenu menu "UART6 Configuration" @@ -1574,6 +1675,13 @@ config UART6_OFLOWCONTROL ---help--- Enable UART6 CTS flow control +config UART6_DMA + bool "UART6 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART6 + endmenu menu "USART7 Configuration" @@ -1632,6 +1740,13 @@ config USART7_OFLOWCONTROL ---help--- Enable USART7 CTS flow control +config USART7_DMA + bool "USART7 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART7 + endmenu menu "UART7 Configuration" @@ -1690,6 +1805,13 @@ config UART7_OFLOWCONTROL ---help--- Enable UART7 CTS flow control +config UART7_DMA + bool "UART7 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART7 + endmenu menu "USART8 Configuration" @@ -1748,6 +1870,13 @@ config USART8_OFLOWCONTROL ---help--- Enable USART8 CTS flow control +config USART8_DMA + bool "USART8 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on USART8 + endmenu menu "UART8 Configuration" @@ -1806,6 +1935,13 @@ config UART8_OFLOWCONTROL ---help--- Enable UART8 CTS flow control +config UART8_DMA + bool "UART8 DMA support" + default n + select SERIAL_DMA + ---help--- + Enable DMA transfers on UART8 + endmenu menu "SCI0 Configuration" diff --git a/drivers/serial/Make.defs b/drivers/serial/Make.defs index b99f4eb3621d3bc3e0e10423e60a4b271d4334a4..bcbffd8368e8129e5034d7e67838d8a3bdc049f4 100644 --- a/drivers/serial/Make.defs +++ b/drivers/serial/Make.defs @@ -37,7 +37,11 @@ ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) # Include serial drivers -CSRCS += serial.c serialirq.c lowconsole.c +CSRCS += serial.c serial_io.c lowconsole.c + +ifeq ($(CONFIG_SERIAL_DMA),y) + CSRCS += serial_dma.c +endif ifeq ($(CONFIG_16550_UART),y) CSRCS += uart_16550.c diff --git a/drivers/serial/lowconsole.c b/drivers/serial/lowconsole.c index ada5b518d12f318b408c475073b6b6f4c0948e08..c6228d79a6f858e5e1c56670b96ec79f74a9b63b 100644 --- a/drivers/serial/lowconsole.c +++ b/drivers/serial/lowconsole.c @@ -65,7 +65,7 @@ static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t b static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static const struct file_operations g_consoleops = @@ -125,7 +125,7 @@ static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t b /**************************************************************************** * Name: lowconsole_init -****************************************************************************/ + ****************************************************************************/ void lowconsole_init(void) { diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index ff4fe55d4743c863af03466b9e8bab8b9b18625a..2e13f3790a89354d9bb0163f33a9aa6e1572d393 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1,7 +1,7 @@ /************************************************************************************ * drivers/serial/serial.c * - * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,7 @@ static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool se #endif /************************************************************************************ - * Private Variables + * Private Data ************************************************************************************/ static const struct file_operations g_serialops = @@ -169,7 +169,7 @@ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset) if (fds) { #ifdef CONFIG_SERIAL_REMOVABLE - fds->revents |= ((fds->events | (POLLERR|POLLHUP)) & eventset); + fds->revents |= ((fds->events | (POLLERR | POLLHUP)) & eventset); #else fds->revents |= (fds->events & eventset); #endif @@ -207,7 +207,7 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock) /* Loop until we are able to add the character to the TX buffer */ - for (;;) + for (; ; ) { if (nexthead != dev->xmit.tail) { @@ -227,7 +227,7 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock) * the following steps must be atomic. */ - flags = irqsave(); + flags = enter_critical_section(); #ifdef CONFIG_SERIAL_REMOVABLE /* Check if the removable device is no longer connected while we @@ -249,12 +249,15 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock) */ dev->xmitwaiting = true; +#ifdef CONFIG_SERIAL_DMA + uart_dmatxavail(dev); +#endif uart_enabletxint(dev); ret = uart_takesem(&dev->xmitsem, true); uart_disabletxint(dev); } - irqrestore(flags); + leave_critical_section(flags); #ifdef CONFIG_SERIAL_REMOVABLE /* Check if the removable device was disconnected while we were @@ -270,9 +273,9 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock) if (ret < 0) { - /* A signal received while waiting for the xmit buffer to become - * non-full will abort the transfer. - */ + /* A signal received while waiting for the xmit buffer to become + * non-full will abort the transfer. + */ return -EINTR; } @@ -363,9 +366,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, if (dev->isconsole) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); ret = uart_irqwrite(dev, buffer, buflen); - irqrestore(flags); + leave_critical_section(flags); return ret; } else @@ -507,6 +510,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, if (dev->xmit.head != dev->xmit.tail) { +#ifdef CONFIG_SERIAL_DMA + uart_dmatxavail(dev); +#endif uart_enabletxint(dev); } @@ -706,7 +712,21 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen * that the following operations are atomic. */ - flags = irqsave(); + flags = enter_critical_section(); + +#ifdef CONFIG_SERIAL_DMA + /* If RX buffer is empty move tail and head to zero position */ + + if (rxbuf->head == rxbuf->tail) + { + rxbuf->head = rxbuf->tail = 0; + } + + /* Notify DMA that there is free space in the RX buffer */ + + uart_dmarxfree(dev); +#endif + uart_enablerxint(dev); #ifdef CONFIG_SERIAL_REMOVABLE @@ -731,7 +751,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen ret = uart_takesem(&dev->recvsem, true); } - irqrestore(flags); + leave_critical_section(flags); /* Was a signal received while waiting for data to be * received? Was a removable device disconnected while @@ -778,6 +798,27 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen } } +#ifdef CONFIG_SERIAL_DMA + flags = enter_critical_section(); + + /* If RX buffer is empty move tail and head to zero position */ + + if (rxbuf->head == rxbuf->tail) + { + rxbuf->head = rxbuf->tail = 0; + } + + leave_critical_section(flags); + + /* Notify DMA that there is free space in the RX buffer */ + + uart_dmarxfree(dev); + + /* RX interrupt could be disabled by RX buffer overflow. Enable it now. */ + + uart_enablerxint(dev); +#endif + #ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS /* How many bytes are now buffered */ @@ -792,7 +833,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen nbuffered = rxbuf->size - rxbuf->tail + rxbuf->head; } - /* Is the level now below the watermark level that we need to report? */ + /* Is the level now below the watermark level that we need to report? */ watermark = (CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK * rxbuf->size) / 100; if (nbuffered <= watermark) @@ -844,7 +885,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case FIONREAD: { int count; - irqstate_t state = irqsave(); + irqstate_t flags = enter_critical_section(); /* Determine the number of bytes available in the buffer */ @@ -857,9 +898,9 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) count = dev->recv.size - (dev->recv.tail - dev->recv.head); } - irqrestore(state); + leave_critical_section(flags); - *(int *)arg = count; + *(FAR int *)((uintptr_t)arg) = count; ret = 0; } break; @@ -867,7 +908,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case FIONWRITE: { int count; - irqstate_t state = irqsave(); + irqstate_t flags = enter_critical_section(); /* Determine the number of bytes free in the buffer */ @@ -880,9 +921,9 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) count = dev->xmit.size - (dev->xmit.head - dev->xmit.tail) - 1; } - irqrestore(state); + leave_critical_section(flags); - *(int *)arg = count; + *(FAR int *)((uintptr_t)arg) = count; ret = 0; } break; @@ -898,7 +939,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { case TCGETS: { - FAR struct termios *termiosp = (struct termios*)arg; + FAR struct termios *termiosp = (FAR struct termios *)arg; if (!termiosp) { @@ -916,7 +957,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case TCSETS: { - FAR struct termios *termiosp = (struct termios*)arg; + FAR struct termios *termiosp = (FAR struct termios *)arg; if (!termiosp) { @@ -954,7 +995,7 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) /* Some sanity checking */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !fds) { return -ENODEV; @@ -1044,7 +1085,7 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) if (dev->disconnected) { - eventset |= (POLLERR|POLLHUP); + eventset |= (POLLERR | POLLHUP); } #endif @@ -1141,14 +1182,14 @@ static int uart_close(FAR struct file *filep) /* Free the IRQ and disable the UART */ - flags = irqsave(); /* Disable interrupts */ + flags = enter_critical_section(); /* Disable interrupts */ uart_detach(dev); /* Detach interrupts */ if (!dev->isconsole) /* Check for the serial console UART */ { uart_shutdown(dev); /* Disable the UART */ } - irqrestore(flags); + leave_critical_section(flags); /* We need to re-initialize the semaphores if this is the last close * of the device, as the close might be caused by pthread_cancel() of @@ -1170,7 +1211,7 @@ static int uart_close(FAR struct file *filep) uart_givesem(&dev->closesem); return OK; - } +} /************************************************************************************ * Name: uart_open @@ -1228,7 +1269,7 @@ static int uart_open(FAR struct file *filep) if (tmp == 1) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); /* If this is the console, then the UART has already been initialized. */ @@ -1239,7 +1280,7 @@ static int uart_open(FAR struct file *filep) ret = uart_setup(dev); if (ret < 0) { - irqrestore(flags); + leave_critical_section(flags); goto errout_with_sem; } } @@ -1254,7 +1295,7 @@ static int uart_open(FAR struct file *filep) if (ret < 0) { uart_shutdown(dev); - irqrestore(flags); + leave_critical_section(flags); goto errout_with_sem; } @@ -1265,7 +1306,7 @@ static int uart_open(FAR struct file *filep) dev->recv.head = 0; dev->recv.tail = 0; - /* Initialise termios state */ + /* Initialize termios state */ #ifdef CONFIG_SERIAL_TERMIOS dev->tc_iflag = 0; @@ -1281,10 +1322,16 @@ static int uart_open(FAR struct file *filep) } #endif +#ifdef CONFIG_SERIAL_DMA + /* Notify DMA that there is free space in the RX buffer */ + + uart_dmarxfree(dev); +#endif + /* Enable the RX interrupt */ uart_enablerxint(dev); - irqrestore(flags); + leave_critical_section(flags); } /* Save the new open count on success */ @@ -1407,7 +1454,7 @@ void uart_connected(FAR uart_dev_t *dev, bool connected) * function may be called from interrupt handling logic. */ - flags = irqsave(); + flags = enter_critical_section(); dev->disconnected = !connected; if (!connected) { @@ -1437,12 +1484,9 @@ void uart_connected(FAR uart_dev_t *dev, bool connected) /* Notify all poll/select waiters that a hangup occurred */ - uart_pollnotify(dev, (POLLERR|POLLHUP)); + uart_pollnotify(dev, (POLLERR | POLLHUP)); } - irqrestore(flags); + leave_critical_section(flags); } #endif - - - diff --git a/drivers/serial/serial_dma.c b/drivers/serial/serial_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..f363f9ed0aabd47c29523ecdda97d39d844076c0 --- /dev/null +++ b/drivers/serial/serial_dma.c @@ -0,0 +1,270 @@ +/************************************************************************************ + * drivers/serial/serial_dma.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Max Neklyudov + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_SERIAL_DMA + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: uart_xmitchars_dma + * + * Description: + * Set up to transfer bytes from the TX circular buffer using DMA + * + ************************************************************************************/ + +void uart_xmitchars_dma(FAR uart_dev_t *dev) +{ + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + + if (dev->xmit.head == dev->xmit.tail) + { + /* No data to transfer. */ + + return; + } + + if (dev->xmit.tail < dev->xmit.head) + { + xfer->buffer = &dev->xmit.buffer[dev->xmit.tail]; + xfer->length = dev->xmit.head - dev->xmit.tail; + xfer->nbuffer = NULL; + xfer->nlength = 0; + } + else + { + xfer->buffer = &dev->xmit.buffer[dev->xmit.tail]; + xfer->length = dev->xmit.size - dev->xmit.tail; + xfer->nbuffer = dev->xmit.buffer; + xfer->nlength = dev->xmit.head; + } + + uart_dmasend(dev); +} + +/************************************************************************************ + * Name: uart_xmitchars_done + * + * Description: + * Perform operations necessary at the complete of DMA including adjusting the + * TX circular buffer indices and waking up of any threads that may have been + * waiting for space to become available in the TX circular buffer. + * + ************************************************************************************/ + +void uart_xmitchars_done(FAR uart_dev_t *dev) +{ + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t nbytes = xfer->nbytes; + struct uart_buffer_s *txbuf = &dev->xmit; + + /* Move tail for nbytes. */ + + txbuf->tail = (txbuf->tail + nbytes) % txbuf->size; + xfer->nbytes = 0; + xfer->length = xfer->nlength = 0; + + /* If any bytes were removed from the buffer, inform any waiters there there is + * space available. + */ + + if (nbytes) + { + uart_datasent(dev); + } +} + +/************************************************************************************ + * Name: uart_recvchars_dma + * + * Description: + * Set up to receive bytes into the RX circular buffer using DMA + * + ************************************************************************************/ + +void uart_recvchars_dma(FAR uart_dev_t *dev) +{ + FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; + FAR struct uart_buffer_s *rxbuf = &dev->recv; +#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS + unsigned int nbuffered; + unsigned int watermark; +#endif + bool is_full; + int nexthead = rxbuf->head + 1; + + if (nexthead >= rxbuf->size) + { + nexthead = 0; + } + + is_full = nexthead == rxbuf->tail; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS + /* Pre-calcuate the watermark level that we will need to test against. */ + + watermark = (CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK * rxbuf->size) / 100; +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS + /* How many bytes are buffered */ + + if (rxbuf->head >= rxbuf->tail) + { + nbuffered = rxbuf->head - rxbuf->tail; + } + else + { + nbuffered = rxbuf->size - rxbuf->tail + rxbuf->head; + } + + /* Is the level now above the watermark level that we need to report? */ + + if (nbuffered >= watermark) + { + /* Let the lower level driver know that the watermark level has been + * crossed. It will probably activate RX flow control. + */ + + if (uart_rxflowcontrol(dev, nbuffered, true)) + { + /* Low-level driver activated RX flow control, return now. */ + + return; + } + } + +#else + /* Check if RX buffer is full and allow serial low-level driver to pause + * processing. This allows proper utilization of hardware flow control. + */ + + if (is_full) + { + if (uart_rxflowcontrol(dev, rxbuf->size, true)) + { + /* Low-level driver activated RX flow control, return now. */ + + return; + } + } +#endif +#endif + + if (is_full) + { + /* If there is no free space in receive buffer we cannot start DMA + * transfer. + */ + + return; + } + + if (rxbuf->tail <= rxbuf->head) + { + xfer->buffer = &rxbuf->buffer[rxbuf->head]; + xfer->nbuffer = rxbuf->buffer; + + if (rxbuf->tail > 0) + { + xfer->length = rxbuf->size - rxbuf->head; + xfer->nlength = rxbuf->tail - 1; + } + else + { + xfer->length = rxbuf->size - rxbuf->head - 1; + xfer->nlength = 0; + } + } + else + { + xfer->buffer = &rxbuf->buffer[rxbuf->head]; + xfer->length = rxbuf->tail - rxbuf->head - 1; + xfer->nbuffer = NULL; + xfer->nlength = 0; + } + + uart_dmareceive(dev); +} + +/************************************************************************************ + * Name: uart_recvchars_done + * + * Description: + * Perform operations necessary at the complete of DMA including adjusting the + * RX circular buffer indices and waking up of any threads that may have been + * waiting for new data to become available in the RX circular buffer. + * + ************************************************************************************/ + +void uart_recvchars_done(FAR uart_dev_t *dev) +{ + FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; + FAR struct uart_buffer_s *rxbuf = &dev->recv; + size_t nbytes = xfer->nbytes; + + /* Move head for nbytes. */ + + rxbuf->head = (rxbuf->head + nbytes) % rxbuf->size; + xfer->nbytes = 0; + xfer->length = xfer->nlength = 0; + + /* If any bytes were added to the buffer, inform any waiters there is new + * incoming data available. + */ + + if (nbytes) + { + uart_datareceived(dev); + } +} + +#endif /* CONFIG_SERIAL_DMA */ diff --git a/drivers/serial/serialirq.c b/drivers/serial/serial_io.c similarity index 86% rename from drivers/serial/serialirq.c rename to drivers/serial/serial_io.c index 3962d985cfe815751bcd4509cf3b1f10f11021c3..9d28d64b74e60fdea5b66530bb0871eff0961281 100644 --- a/drivers/serial/serialirq.c +++ b/drivers/serial/serial_io.c @@ -1,7 +1,7 @@ /************************************************************************************ - * drivers/serial/serialirq.c + * drivers/serial/serial_io.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,27 +43,8 @@ #include #include #include -#include - -/************************************************************************************ - * Pre-processor Definitions - ************************************************************************************/ - -/************************************************************************************ - * Private Types - ************************************************************************************/ - -/************************************************************************************ - * Private Function Prototypes - ************************************************************************************/ - -/************************************************************************************ - * Private Variables - ************************************************************************************/ -/************************************************************************************ - * Private Functions - ************************************************************************************/ +#include /************************************************************************************ * Public Functions @@ -240,7 +221,7 @@ void uart_recvchars(FAR uart_dev_t *dev) } } - /* If any bytes were added to the buffer, inform any waiters there there is new + /* If any bytes were added to the buffer, inform any waiters there is new * incoming data available. */ diff --git a/drivers/serial/uart_16550.c b/drivers/serial/uart_16550.c index ffa7f7a4c9d5ef583aca9fbf7a31bba6e53afae9..8b8eb82564d14f637c6d2f02227493415c40933b 100644 --- a/drivers/serial/uart_16550.c +++ b/drivers/serial/uart_16550.c @@ -106,7 +106,7 @@ static bool u16550_txready(struct uart_dev_s *dev); static bool u16550_txempty(struct uart_dev_s *dev); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static const struct uart_ops_s g_uart_ops = @@ -464,7 +464,7 @@ static uart_dev_t g_uart3port = * Name: u16550_serialin ****************************************************************************/ -static inline uart_datawidth_t u16550_serialin(struct u16550_s *priv, int offset) +static inline uart_datawidth_t u16550_serialin(FAR struct u16550_s *priv, int offset) { return uart_getreg(priv->uartbase, offset); } @@ -473,7 +473,8 @@ static inline uart_datawidth_t u16550_serialin(struct u16550_s *priv, int offset * Name: u16550_serialout ****************************************************************************/ -static inline void u16550_serialout(struct u16550_s *priv, int offset, uart_datawidth_t value) +static inline void u16550_serialout(FAR struct u16550_s *priv, int offset, + uart_datawidth_t value) { uart_putreg(priv->uartbase, offset, value); } @@ -483,7 +484,8 @@ static inline void u16550_serialout(struct u16550_s *priv, int offset, uart_data ****************************************************************************/ #ifndef CONFIG_SUPPRESS_SERIAL_INTS -static inline void u16550_disableuartint(struct u16550_s *priv, uart_datawidth_t *ier) +static inline void u16550_disableuartint(FAR struct u16550_s *priv, + FAR uart_datawidth_t *ier) { if (ier) { @@ -502,7 +504,7 @@ static inline void u16550_disableuartint(struct u16550_s *priv, uart_datawidth_t ****************************************************************************/ #ifndef CONFIG_SUPPRESS_SERIAL_INTS -static inline void u16550_restoreuartint(struct u16550_s *priv, uint32_t ier) +static inline void u16550_restoreuartint(FAR struct u16550_s *priv, uint32_t ier) { priv->ier |= ier & UART_IER_ALLIE; u16550_serialout(priv, UART_IER_OFFSET, priv->ier); @@ -515,7 +517,7 @@ static inline void u16550_restoreuartint(struct u16550_s *priv, uint32_t ier) * Name: u16550_enablebreaks ****************************************************************************/ -static inline void u16550_enablebreaks(struct u16550_s *priv, bool enable) +static inline void u16550_enablebreaks(FAR struct u16550_s *priv, bool enable) { uint32_t lcr = u16550_serialin(priv, UART_LCR_OFFSET); if (enable) @@ -543,7 +545,7 @@ static inline void u16550_enablebreaks(struct u16550_s *priv, bool enable) ************************************************************************************/ #ifndef CONFIG_16550_SUPRESS_CONFIG -static inline uint32_t u16550_divisor(struct u16550_s *priv) +static inline uint32_t u16550_divisor(FAR struct u16550_s *priv) { return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4); } @@ -566,17 +568,19 @@ static inline uint32_t u16550_divisor(struct u16550_s *priv) static int u16550_setup(struct uart_dev_s *dev) { #ifndef CONFIG_16550_SUPRESS_CONFIG - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; uint16_t div; uint32_t lcr; /* Clear fifos */ - u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_RXRST|UART_FCR_TXRST)); + u16550_serialout(priv, UART_FCR_OFFSET, + (UART_FCR_RXRST | UART_FCR_TXRST)); /* Set trigger */ - u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_FIFOEN|UART_FCR_RXTRIGGER_8)); + u16550_serialout(priv, UART_FCR_OFFSET, + (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); /* Set up the IER */ @@ -618,7 +622,7 @@ static int u16550_setup(struct uart_dev_s *dev) } else if (priv->parity == 2) { - lcr |= (UART_LCR_PEN|UART_LCR_EPS); + lcr |= (UART_LCR_PEN | UART_LCR_EPS); } /* Enter DLAB=1 */ @@ -638,7 +642,8 @@ static int u16550_setup(struct uart_dev_s *dev) /* Configure the FIFOs */ u16550_serialout(priv, UART_FCR_OFFSET, - (UART_FCR_RXTRIGGER_8|UART_FCR_TXRST|UART_FCR_RXRST|UART_FCR_FIFOEN)); + (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | + UART_FCR_FIFOEN)); #endif return OK; } @@ -654,7 +659,7 @@ static int u16550_setup(struct uart_dev_s *dev) static void u16550_shutdown(struct uart_dev_s *dev) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; u16550_disableuartint(priv, NULL); } @@ -676,7 +681,7 @@ static void u16550_shutdown(struct uart_dev_s *dev) static int u16550_attach(struct uart_dev_s *dev) { #ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; int ret; /* Attach and enable the IRQ */ @@ -708,10 +713,10 @@ static int u16550_attach(struct uart_dev_s *dev) * ****************************************************************************/ -static void u16550_detach(struct uart_dev_s *dev) +static void u16550_detach(FAR struct uart_dev_s *dev) { #ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; #ifndef CONFIG_ARCH_NOINTC up_disable_irq(priv->irq); #endif @@ -767,7 +772,7 @@ static int u16550_interrupt(int irq, void *context) } #endif ASSERT(dev != NULL); - priv = (struct u16550_s*)dev->priv; + priv = (FAR struct u16550_s *)dev->priv; /* Loop until there are no characters to be transferred or, * until we have been looping for a long time. @@ -863,7 +868,7 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg) { struct inode *inode = filep->f_inode; struct uart_dev_s *dev = inode->i_private; - struct u16550_s *priv = (struct u16550_s*)dev->priv; + struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; #ifdef CONFIG_SERIAL_UART_ARCH_IOCTL int ret = uart_ioctl(filep, cmd, arg); @@ -879,7 +884,7 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT case TIOCSERGSTRUCT: { - struct u16550_s *user = (struct u16550_s*)arg; + FAR struct u16550_s *user = (FAR struct u16550_s *)arg; if (!user) { set_errno(EINVAL); @@ -895,18 +900,18 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg) case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); u16550_enablebreaks(priv, true); - irqrestore(flags); + leave_critical_section(flags); } break; case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ { irqstate_t flags; - flags = irqsave(); + flags = enter_critical_section(); u16550_enablebreaks(priv, false); - irqrestore(flags); + leave_critical_section(flags); } break; @@ -931,7 +936,7 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg) static int u16550_receive(struct uart_dev_s *dev, uint32_t *status) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; uint32_t rbr; *status = u16550_serialin(priv, UART_LSR_OFFSET); @@ -950,7 +955,7 @@ static int u16550_receive(struct uart_dev_s *dev, uint32_t *status) static void u16550_rxint(struct uart_dev_s *dev, bool enable) { #ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; if (enable) { priv->ier |= UART_IER_ERBFI; @@ -973,7 +978,7 @@ static void u16550_rxint(struct uart_dev_s *dev, bool enable) static bool u16550_rxavailable(struct uart_dev_s *dev) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0); } @@ -987,7 +992,7 @@ static bool u16550_rxavailable(struct uart_dev_s *dev) static void u16550_send(struct uart_dev_s *dev, int ch) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); } @@ -1002,10 +1007,10 @@ static void u16550_send(struct uart_dev_s *dev, int ch) static void u16550_txint(struct uart_dev_s *dev, bool enable) { #ifndef CONFIG_SUPPRESS_SERIAL_INTS - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; irqstate_t flags; - flags = irqsave(); + flags = enter_critical_section(); if (enable) { priv->ier |= UART_IER_ETBEI; @@ -1023,7 +1028,7 @@ static void u16550_txint(struct uart_dev_s *dev, bool enable) u16550_serialout(priv, UART_IER_OFFSET, priv->ier); } - irqrestore(flags); + leave_critical_section(flags); #endif } @@ -1037,7 +1042,7 @@ static void u16550_txint(struct uart_dev_s *dev, bool enable) static bool u16550_txready(struct uart_dev_s *dev) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0); } @@ -1051,7 +1056,7 @@ static bool u16550_txready(struct uart_dev_s *dev) static bool u16550_txempty(struct uart_dev_s *dev) { - struct u16550_s *priv = (struct u16550_s*)dev->priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv; return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0); } @@ -1063,7 +1068,7 @@ static bool u16550_txempty(struct uart_dev_s *dev) * ****************************************************************************/ -static void u16550_putc(struct u16550_s *priv, int ch) +static void u16550_putc(FAR struct u16550_s *priv, int ch) { while ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) == 0); u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); @@ -1150,7 +1155,7 @@ void up_serialinit(void) #ifdef HAVE_16550_CONSOLE int up_putc(int ch) { - struct u16550_s *priv = (struct u16550_s*)CONSOLE_DEV.priv; + FAR struct u16550_s *priv = (FAR struct u16550_s *)CONSOLE_DEV.priv; #ifndef CONFIG_SUPPRESS_SERIAL_INTS uart_datawidth_t ier; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 488c08c2513562862c68e932dd291773b78553a0..b4c8e93bbc01fdf6df5da7a52489732b170c2961 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -22,14 +22,6 @@ config SPI_SLAVE_DMA endif -config SPI_OWNBUS - bool "SPI single device" - default n - ---help--- - Set if there is only one active device on the SPI bus. No locking or - SPI configuration will be performed. It is not necessary for clients to - lock, re-configure, etc. - config SPI_EXCHANGE bool "SPI exchange" default y @@ -62,6 +54,23 @@ config SPI_BITBANG Enable support for a generic SPI bit-bang device. See include/nuttx/spi/spi_bitbang.h for further information. +config SPI_HWFEATURES + bool + default n + ---help--- + Selected only if a specific H/W feature is selected. This is + basically the OR of any specific hardware feature and eanbles + the SPI hwfeatures() interface method. + +config SPI_CRCGENERATION + bool + default n + select SPI_HWFEATURES + ---help--- + Selected by MCU Kconfig logic if implementation supports automatic + generation of SPI CRCs. Enables the HWFEAT_CRCGENERATION option + as well as the hwfeartures() interface method. + if SPI_BITBANG config SPI_BITBANG_VARWIDTH @@ -71,5 +80,5 @@ config SPI_BITBANG_VARWIDTH Enable support for a variable data width transfers. Default: 8-bit only. -endif -endif +endif # SPI_BITBANG +endif # SPI diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index b720266ee7f6bd50b02f87aee0df9ed8f3b6089e..823b330982f734a42527349377b8e31277d2136b 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/spi/spi_bitbang.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ #ifdef CONFIG_SPI_BITBANG - /**************************************************************************** +/**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /* This file holds the static, device-independ portion of the generica SPI- @@ -110,9 +110,7 @@ /* SPI methods */ -#ifndef CONFIG_SPI_OWNBUS static int spi_lock(FAR struct spi_dev_s *dev, bool lock); -#endif static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, @@ -144,25 +142,26 @@ static int spi_cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, static const struct spi_ops_s g_spiops = { -#ifndef CONFIG_SPI_OWNBUS - .lock = spi_lock, + spi_lock, /* lock */ + spi_select, /* select */ + spi_setfrequency, /* setfrequency */ + spi_setmode, /* setmode */ + spi_setbits, /* setbits */ +#ifdef CONFIG_SPI_HWFEATURES + 0, /* hwfeatures */ #endif - .select = spi_select, - .setfrequency = spi_setfrequency, - .setmode = spi_setmode, - .setbits = spi_setbits, - .status = spi_status, + spi_status, /* status */ #ifdef CONFIG_SPI_CMDDATA - .cmddata = spi_cmddata, + spi_cmddata, /* cmddata */ #endif - .send = spi_send, + spi_send, /* send */ #ifdef CONFIG_SPI_EXCHANGE - .exchange = spi_exchange, + spi_exchange, /* exchange */ #else - .sndblock = spi_sndblock, - .recvblock = spi_recvblock, + spi_sndblock, /* sndblock */ + spi_recvblock, /* recvblock */ #endif - .registercallback = 0, /* Not implemented */ + 0 /* registercallback */ }; /**************************************************************************** @@ -190,7 +189,6 @@ static const struct spi_ops_s g_spiops = * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static int spi_lock(FAR struct spi_dev_s *dev, bool lock) { FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev; @@ -216,7 +214,6 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock) return OK; } -#endif /**************************************************************************** * Name: spi_select @@ -438,7 +435,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, } } -/*************************************************************************** +/**************************************************************************** * Name: spi_sndblock * * Description: diff --git a/drivers/syslog/Kconfig b/drivers/syslog/Kconfig index e450d52de115553176c004381300b6b200f795da..d273e3d1a3a8293165cb14a7d9c82808d1ac73ee 100644 --- a/drivers/syslog/Kconfig +++ b/drivers/syslog/Kconfig @@ -83,3 +83,10 @@ config SYSLOG_CONSOLE console. Then in that case, console output from non-Telnet threads will go to the syslog output. +config DRIVER_NOTE + bool "Scheduler instrumentation driver" + default n + depends on SCHED_INSTRUMENTATION_BUFFER + ---help--- + Enable building a serial driver that can be used by an application to read data + from the in-memory, scheduler instrumentatin "note" buffer. diff --git a/drivers/syslog/Make.defs b/drivers/syslog/Make.defs index c9aa7a024049693c9399fa02e583eb84d413ecf8..f573217d6de944a94ceedb65b77d2a084f1cf9b0 100644 --- a/drivers/syslog/Make.defs +++ b/drivers/syslog/Make.defs @@ -34,6 +34,7 @@ # ############################################################################ +############################################################################ # Include SYSLOG drivers (only one should be enabled) ifeq ($(CONFIG_SYSLOG),y) @@ -47,6 +48,10 @@ ifeq ($(CONFIG_RAMLOG),y) CSRCS += ramlog.c endif +ifeq ($(CONFIG_DRIVER_NOTE),y) + CSRCS += note_driver.c +endif + # (Add other SYSLOG_CONSOLE drivers here) ifeq ($(CONFIG_SYSLOG_CONSOLE),y) @@ -58,17 +63,32 @@ endif DEPPATH += --dep-path syslog VPATH += :syslog -else - +############################################################################ # The RAMLOG can be used even if system logging is not enabled. -ifeq ($(CONFIG_RAMLOG),y) +else ifeq ($(CONFIG_RAMLOG),y) + +CSRCS += ramlog.c + +ifeq ($(CONFIG_DRIVER_NOTE),y) + CSRCS += note_driver.c +endif # Include RAMLOG build support -CSRCS += ramlog.c DEPPATH += --dep-path syslog VPATH += :syslog -endif +############################################################################ +# The scheduler note driver can be used in any event. + +else ifeq ($(CONFIG_DRIVER_NOTE),y) + +CSRCS += note_driver.c + +# Include note driver build support + +DEPPATH += --dep-path syslog +VPATH += :syslog + endif diff --git a/drivers/syslog/note_driver.c b/drivers/syslog/note_driver.c new file mode 100644 index 0000000000000000000000000000000000000000..5b9230791714ce23767a2205a61fedcb27939adf --- /dev/null +++ b/drivers/syslog/note_driver.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * drivers/syslog/note_driver.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t note_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations note_fops = +{ + 0, /* open */ + 0, /* close */ + note_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: note_read + ****************************************************************************/ + +static ssize_t note_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + ssize_t notelen; + ssize_t retlen ; + + DEBUGASSERT(filep != 0 && buffer != NULL && buflen > 0); + + /* Then loop, adding as many notes as possible to the user buffer. */ + + retlen = 0; + sched_lock(); + do + { + /* Get the next note (removing it from the buffer) */ + + notelen = sched_note_get((FAR uint8_t *)buffer, buflen); + if (notelen < 0) + { + /* We were unable to read the next note, probably because it will + * not fit into the user buffer. + */ + + if (retlen == 0) + { + /* If nothing was read then report the error. Otherwise, + * just silently drop the note. + */ + + retlen = notelen; + } + + break; + } + + /* Update pointers from the note that was transferred */ + + retlen += notelen; + buffer += notelen; + buflen -= notelen; + + /* Will the next note fit? There is a race here and even if the next + * note will fit, it may fail still when sched_note_get() is called. + * + * It won't fit (or an error occurred). Return what we have without + * trying to get the next note (which would cause it to be deleted). + */ + + notelen = sched_note_size(); + } + while (notelen > 0 && notelen <= buflen); + + sched_unlock(); + return retlen; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: note_register + * + * Description: + * Register a serial driver at /dev/note that can be used by an + * application to read data from the circular not buffer. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero is returned if the circular buffer is empty. Otherwise, a negated + * errno value is returned. + * + ****************************************************************************/ + +int note_register(void) +{ + return register_driver("/dev/note", ¬e_fops, 0666, NULL); +} + +#endif /* CONFIG_SCHED_INSTRUMENTATION_BUFFER && CONFIG_DRIVER_NOTE */ \ No newline at end of file diff --git a/drivers/syslog/ramlog.c b/drivers/syslog/ramlog.c index fde47c1c62780cbfb36758ad78a227e42352efa7..ea8e035ce703ff98bde8aa0969104f9c7b7fe7b0 100644 --- a/drivers/syslog/ramlog.c +++ b/drivers/syslog/ramlog.c @@ -59,7 +59,7 @@ #include #include -#include +#include #ifdef CONFIG_RAMLOG @@ -91,7 +91,7 @@ struct ramlog_dev_s */ #ifndef CONFIG_DISABLE_POLL - struct pollfd *rl_fds[CONFIG_RAMLOG_NPOLLWAITERS]; + FAR struct pollfd *rl_fds[CONFIG_RAMLOG_NPOLLWAITERS]; #endif }; @@ -108,8 +108,10 @@ static ssize_t ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch); /* Character driver methods */ -static ssize_t ramlog_read(FAR struct file *, FAR char *, size_t); -static ssize_t ramlog_write(FAR struct file *, FAR const char *, size_t); +static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); #ifndef CONFIG_DISABLE_POLL static int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); @@ -170,7 +172,7 @@ static struct ramlog_dev_s g_sysdev = #ifndef CONFIG_DISABLE_POLL static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv, - pollevent_t eventset) + pollevent_t eventset) { FAR struct pollfd *fds; irqstate_t flags; @@ -180,7 +182,7 @@ static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv, for (i = 0; i < CONFIG_RAMLOG_NPOLLWAITERS; i++) { - flags = irqsave(); + flags = enter_critical_section(); fds = priv->rl_fds[i]; if (fds) { @@ -190,7 +192,7 @@ static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv, sem_post(fds->sem); } } - irqrestore(flags); + leave_critical_section(flags); } } #else @@ -208,7 +210,7 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch) /* Disable interrupts (in case we are NOT called from interrupt handler) */ - flags = irqsave(); + flags = enter_critical_section(); /* Calculate the write index AFTER the next byte is written */ @@ -224,7 +226,7 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch) { /* Yes... Return an indication that nothing was saved in the buffer. */ - irqrestore(flags); + leave_critical_section(flags); return -EBUSY; } @@ -232,7 +234,7 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch) priv->rl_buffer[priv->rl_head] = ch; priv->rl_head = nexthead; - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -242,8 +244,8 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch) static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len) { - struct inode *inode = filep->f_inode; - struct ramlog_dev_s *priv; + FAR struct inode *inode = filep->f_inode; + FAR struct ramlog_dev_s *priv; ssize_t nread; char ch; int ret; @@ -251,7 +253,7 @@ static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len) /* Some sanity checking */ DEBUGASSERT(inode && inode->i_private); - priv = inode->i_private; + priv = (FAR struct ramlog_dev_s *)inode->i_private; /* If the circular buffer is empty, then wait for something to be written * to it. This function may NOT be called from an interrupt handler. @@ -415,8 +417,8 @@ errout_without_sem: static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size_t len) { - struct inode *inode = filep->f_inode; - struct ramlog_dev_s *priv; + FAR struct inode *inode = filep->f_inode; + FAR struct ramlog_dev_s *priv; ssize_t nwritten; char ch; int ret; @@ -424,16 +426,16 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size /* Some sanity checking */ DEBUGASSERT(inode && inode->i_private); - priv = inode->i_private; - - /* Loop until all of the bytes have been written. This function may be - * called from an interrupt handler! Semaphores cannot be used! - * - * The write logic only needs to modify the rl_head index. Therefore, - * there is a difference in the way that rl_head and rl_tail are protected: - * rl_tail is protected with a semaphore; rl_tail is protected by disabling - * interrupts. - */ + priv = (FAR struct ramlog_dev_s *)inode->i_private; + + /* Loop until all of the bytes have been written. This function may be + * called from an interrupt handler! Semaphores cannot be used! + * + * The write logic only needs to modify the rl_head index. Therefore, + * there is a difference in the way that rl_head and rl_tail are protected: + * rl_tail is protected with a semaphore; rl_tail is protected by disabling + * interrupts. + */ for (nwritten = 0; nwritten < len; nwritten++) { @@ -468,7 +470,7 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size /* Then output the character */ - ret = ramlog_addchar(priv,ch); + ret = ramlog_addchar(priv, ch); if (ret < 0) { /* The buffer is full and nothing was saved. Break out of the @@ -492,7 +494,7 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size /* Are there threads waiting for read data? */ - flags = irqsave(); + flags = enter_critical_section(); #ifndef CONFIG_RAMLOG_NONBLOCKING for (i = 0; i < priv->rl_nwaiters; i++) { @@ -505,7 +507,7 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size /* Notify all poll/select waiters that they can write to the FIFO */ ramlog_pollnotify(priv, POLLIN); - irqrestore(flags); + leave_critical_section(flags); } #endif @@ -534,7 +536,7 @@ int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) /* Some sanity checking */ DEBUGASSERT(inode && inode->i_private); - priv = inode->i_private; + priv = (FAR struct ramlog_dev_s *)inode->i_private; /* Get exclusive access to the poll structures */ @@ -655,7 +657,7 @@ int ramlog_register(FAR const char *devpath, FAR char *buffer, size_t buflen) /* Allocate a RAM logging device structure */ priv = (struct ramlog_dev_s *)kmm_zalloc(sizeof(struct ramlog_dev_s)); - if (priv) + if (priv != NULL) { /* Initialize the non-zero values in the RAM logging device structure */ diff --git a/drivers/syslog/syslog_console.c b/drivers/syslog/syslog_console.c index 6e21231bd693cb9baebdc6dcb21da69cf916dc95..a3d3bb2bea35ad979a5178f6a29bdf8cff478db1 100644 --- a/drivers/syslog/syslog_console.c +++ b/drivers/syslog/syslog_console.c @@ -67,7 +67,7 @@ static int syslog_console_ioctl(FAR struct file *filep, int cmd, unsigned long arg); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static const struct file_operations g_consoleops = @@ -130,7 +130,7 @@ static ssize_t syslog_console_write(FAR struct file *filep, /**************************************************************************** * Name: syslog_console_init -****************************************************************************/ + ****************************************************************************/ void syslog_console_init(void) { diff --git a/drivers/timers/Kconfig b/drivers/timers/Kconfig index c8579a8fea4e8739fb7d68129524e105e26ff975..7e053175cef67514c467e058a127e74f6e96a2f9 100644 --- a/drivers/timers/Kconfig +++ b/drivers/timers/Kconfig @@ -117,6 +117,92 @@ config RTC_IOCTL architecture-specific RTC operations to the RTC interface endif # RTC_DRIVER + +config RTC_EXTERNAL + bool "External RTC Support" + default n + ---help--- + In modern MCUs, the RTC is usually implement as an internal + peripheral to the MCU. An option is to use an external RTC + connected to the MCU typically via SPI or I2C. + + If an external RTC is connect to the MCU through some bus, then the + RTC will not be available to the system until after the system + fully boots up and is able to access the bus. In that case, this + setting must be included to suppress attempts to initialize the RTC + early in the boot sequence. + +config RTC_DSXXXX + bool "DS130x/DS323x RTC Driver" + default n + select I2C + select I2C_TRANSFER + select RTC_DATETIME + depends on RTC_EXTERNAL + ---help--- + Enables support for the Maxim Integrated DS3231 I2C RTC timer. + +if RTC_DSXXXX + +choice + prompt "Maxim Integrated RTC" + default RTC_DS3231 + +config RTC_DS1302 + bool "DS1302" + ---help--- + Enables support for the Maxim Integrated DS1307 serial RTC timer. + +config RTC_DS1307 + bool "DS1307" + ---help--- + Enables support for the Maxim Integrated DS1307 I2C RTC timer. + +config RTC_DS3231 + bool "DS3231" + ---help--- + Enables support for the Maxim Integrated DS3231 I2C RTC timer. + +config RTC_DS3232 + bool "DS3232" + ---help--- + Enables support for the Maxim Integrated DS3232 I2C RTC timer. + +config RTC_DS3234 + bool "DS3234" + depends on EXPERIMENTAL + ---help--- + Enables support for the Maxim Integrated DS3234 SPI RTC timer. + + Not yet implemented. + +endchoice # Maxim Integrated RTC + +config DS3231_I2C_FREQUENCY + int "DS1307/DS323x I2C frequency" + default 400000 + range 1 400000 + +endif # RTC_DSXXXX + +config RTC_PCF85263 + bool "PCF85263 RTC Driver" + default n + select I2C + select I2C_TRANSFER + select RTC_DATETIME + depends on RTC_EXTERNAL + ---help--- + Enables support for the Maxim Integrated DS3231 I2C RTC timer. + +if RTC_PCF85263 + +config PCF85263_I2C_FREQUENCY + int "PCF85263 I2C frequency" + default 400000 + range 1 400000 + +endif # RTC_PCF85263 endif # RTC menuconfig WATCHDOG diff --git a/drivers/timers/Make.defs b/drivers/timers/Make.defs index f70052a21ffb112c1174f7033e6dd336deb46634..61c7a9764fae2f04690dfadc9b80331f62fe2f62 100644 --- a/drivers/timers/Make.defs +++ b/drivers/timers/Make.defs @@ -2,7 +2,7 @@ # drivers/timers/Make.defs # These drivers support various timer devices # -# Copyright (C) 20125Gregory Nutt. All rights reserved. +# Copyright (C) 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -51,6 +51,18 @@ ifeq ($(CONFIG_TIMER),y) TMRVPATH = :timers endif +ifeq ($(CONFIG_RTC_DSXXXX),y) + CSRCS += ds3231.c + TMRDEPPATH = --dep-path timers + TMRVPATH = :timers +endif + +ifeq ($(CONFIG_RTC_PCF85263),y) + CSRCS += pcf85263.c + TMRDEPPATH = --dep-path timers + TMRVPATH = :timers +endif + ifeq ($(CONFIG_RTC_DRIVER),y) CSRCS += rtc.c TMRDEPPATH = --dep-path timers diff --git a/drivers/timers/cs2100-cp.c b/drivers/timers/cs2100-cp.c index 65530678a1c76389d25c58dce60dbc25e064c589..11ed144cb4432c340a590e2879183dcd4ca17b97 100644 --- a/drivers/timers/cs2100-cp.c +++ b/drivers/timers/cs2100-cp.c @@ -46,7 +46,7 @@ #include #include -#include +#include #include #ifdef CONFIG_TIMERS_CS2100CP @@ -54,6 +54,7 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* Driver Definitions *******************************************************/ #define MAX_REFCLK_FREQ 75000000 @@ -133,15 +134,17 @@ static int cs2100_write_reg(FAR const struct cs2100_config_s *config, /* Construct the I2C message (write N+1 bytes with no restart) */ - msgs[0].addr = config->i2caddr; - msgs[0].flags = 0; - msgs[0].buffer = ®addr; - msgs[0].length = 1; + msga[0].frequency = config->i2cfreq; + msgs[0].addr = config->i2caddr; + msgs[0].flags = 0; + msgs[0].buffer = ®addr; + msgs[0].length = 1; - msgs[1].addr = config->i2caddr; - msgs[1].flags = I2C_M_NORESTART; - msgs[1].buffer = ®val; - msgs[1].length = 1; + msga[1].frequency = config->i2cfreq; + msgs[1].addr = config->i2caddr; + msgs[1].flags = I2C_M_NORESTART; + msgs[1].buffer = ®val; + msgs[1].length = 1; /* Send the message */ @@ -175,20 +178,22 @@ static int cs2100_read_reg(FAR const struct cs2100_config_s *config, /* Construct the I2C message (write 1 bytes, restart, read N bytes) */ - msg.addr = config->i2caddr; - msg.flags = 0; - msg.buffer = ®addr; - msg.length = 1; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = 0; + msg.buffer = ®addr; + msg.length = 1; /* Send the address followed by a STOP */ ret = I2C_TRANSFER(config->i2c, &msg, 1); if (ret == OK) { - msg.addr = config->i2caddr; - msg.flags = I2C_M_READ; - msg.buffer = regval; - msg.length = 1; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = I2C_M_READ; + msg.buffer = regval; + msg.length = 1; /* Read the register beginning with another START */ @@ -199,7 +204,7 @@ static int cs2100_read_reg(FAR const struct cs2100_config_s *config, } } - return ret; + return ret; } #endif @@ -229,16 +234,17 @@ static int cs2100_write_ratio(FAR const struct cs2100_config_s *config, /* Construct the I2C message (write N+1 bytes with no restart) */ - buffer[0] = CS2100_RATIO0; - buffer[1] = (uint8_t)(ratio >> 24); - buffer[2] = (uint8_t)((ratio >> 16) & 0xff); - buffer[3] = (uint8_t)((ratio >> 8) & 0xff); - buffer[4] = (uint8_t)(ratio & 0xff); + buffer[0] = CS2100_RATIO0; + buffer[1] = (uint8_t)(ratio >> 24); + buffer[2] = (uint8_t)((ratio >> 16) & 0xff); + buffer[3] = (uint8_t)((ratio >> 8) & 0xff); + buffer[4] = (uint8_t)(ratio & 0xff); - msg.addr = config->i2caddr; - msg.flags = 0; - msg.buffer = buffer; - msg.length = 5; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = 0; + msg.buffer = buffer; + msg.length = 5; /* Send the message */ @@ -272,22 +278,24 @@ static int cs2100_read_ratio(FAR const struct cs2100_config_s *config, /* Construct the I2C message (write N+1 bytes with no restart) */ - buffer[0] = CS2100_RATIO0; + buffer[0] = CS2100_RATIO0; - msg.addr = config->i2caddr; - msg.flags = 0; - msg.buffer = buffer; - msg.length = 1; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = 0; + msg.buffer = buffer; + msg.length = 1; /* Send the address followed by a STOP */ ret = I2C_TRANSFER(config->i2c, &msg, 1); if (ret == OK) { - msg.addr = config->i2caddr; - msg.flags = I2C_M_READ; - msg.buffer = buffer; - msg.length = 4; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = 4; /* Read the ratio registers beginning with another START */ @@ -368,7 +376,7 @@ static int cs2100_refclk(FAR const struct cs2100_config_s *config) /* Set the minimum loop bandwidth */ - DEBUGASSERT(config->loopbw >=1 && config->loopbw <= 128); + DEBUGASSERT(config->loopbw >= 1 && config->loopbw <= 128); if (config->loopbw < 2) { @@ -409,7 +417,7 @@ static int cs2100_refclk(FAR const struct cs2100_config_s *config) csdbg("ERROR: Failed to set CS2100_FNCCFG3: %d\n", ret); return ret; } - + /* Configure so that CLK_OUT will be enabled when the registers are * unlocked (also clears other settings). * NOTE: This implicitly sets High Multiplier mode for the Rud. @@ -446,7 +454,7 @@ static int cs2100_ratio(FAR const struct cs2100_config_s *config) bool highmul; int rmod; int ret; - + DEBUGASSERT(config->clkin > 0 && config->clkout > 0); /* Calculate a 64-bit RUD value: diff --git a/drivers/timers/ds3231.c b/drivers/timers/ds3231.c new file mode 100644 index 0000000000000000000000000000000000000000..7efaaecb0397fd5656f025ca49fc152bfaff39aa --- /dev/null +++ b/drivers/timers/ds3231.c @@ -0,0 +1,567 @@ +/************************************************************************************ + * drivers/timers/ds3231.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "ds3231.h" + +#ifdef CONFIG_RTC_DSXXXX + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error CONFIG_RTC_DATETIME must be set to use this driver +#endif + +#ifdef CONFIG_RTC_HIRES +# error CONFIG_RTC_HIRES must NOT be set with this driver +#endif + +#ifndef CONFIG_DS3231_I2C_FREQUENCY +# error CONFIG_DS3231_I2C_FREQUENCY is not configured +# define CONFIG_DS3231_I2C_FREQUENCY 400000 +#endif + +#if CONFIG_DS3231_I2C_FREQUENCY > 400000 +# error CONFIG_DS3231_I2C_FREQUENCY is out of range +#endif + +#define DS3231_I2C_ADDRESS 0x68 + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Priviate Types + ************************************************************************************/ +/* This structure describes the state of the DS3231 chip. Only a single RTC is + * supported. + */ + +struct ds3231_dev_s +{ + FAR struct i2c_master_s *i2c; /* Contained reference to the I2C bus driver */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Data + ************************************************************************************/ +/* The state of the DS3231 chip. Only a single RTC is supported */ + +static struct ds3231_dev_s g_ds3231; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Show the broken out time. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + rtclldbg(" tm_wday: %08x\n", tp->tm_wday); + rtclldbg(" tm_yday: %08x\n", tp->tm_yday); + rtclldbg(" tm_isdst: %08x\n", tp->tm_isdst); +#endif +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint8_t rtc_bin2bcd(int value) +{ + uint8_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bcd2bin + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint8_t value) +{ + int tens = ((int)value >> 4) * 10; + return tens + (value & 0x0f); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: dsxxxx_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence by board-specific logic. + * + * After dsxxxx_rtc_initialize() is called, the OS function clock_synchronize() + * should also be called to synchronize the system timer to a hardware RTC. That + * operation is normally performed automatically by the system during clock + * initialization. However, when an external RTC is used, the board logic will + * need to explicitly re-synchronize the system timer to the RTC when the RTC + * becomes available. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int dsxxxx_rtc_initialize(FAR struct i2c_master_s *i2c) +{ + /* Remember the i2c device and claim that the RTC is enabled */ + + g_ds3231.i2c = i2c; + g_rtc_enabled = true; + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + struct i2c_msg_s msg[4]; + uint8_t secaddr; + uint8_t buffer[7]; + uint8_t seconds; + int tmp; + int ret; + + /* If this function is called before the RTC has been initialized (and it will be), + * then just return the data/time of the epoch, 12:00 am, Jan 1, 1970. + */ + + if (!g_rtc_enabled) + { + tp->tm_sec = 0; + tp->tm_min = 0; + tp->tm_hour = 0; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* Jan 1, 1970 was a Thursday */ + + tp->tm_wday = 4; +#endif + + tp->tm_mday = 1; + tp->tm_mon = 0; + tp->tm_year = 70; + return -EAGAIN; + } + + /* Select to begin reading at the seconds register */ + + secaddr = DSXXXX_TIME_SECR; + + msg[0].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[0].addr = DS3231_I2C_ADDRESS; + msg[0].flags = 0; + msg[0].buffer = &secaddr; + msg[0].length = 1; + + /* Set up to read 7 registers: secondss, minutes, hour, day-of-week, date, + * month, year + */ + + msg[1].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[1].addr = DS3231_I2C_ADDRESS; + msg[1].flags = I2C_M_READ; + msg[1].buffer = buffer; + msg[1].length = 7; + + /* Read the seconds register again */ + + msg[2].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[2].addr = DS3231_I2C_ADDRESS; + msg[2].flags = 0; + msg[2].buffer = &secaddr; + msg[2].length = 1; + + msg[3].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[3].addr = DS3231_I2C_ADDRESS; + msg[3].flags = I2C_M_READ; + msg[3].buffer = &seconds; + msg[3].length = 1; + + /* Perform the transfer. The transfer may be performed repeatedly of the + * seconds values decreases, meaning that that was a rollover in the seconds. + */ + + do + { + ret = I2C_TRANSFER(g_ds3231.i2c, msg, 4); + if (ret < 0) + { + rtcdbg("ERROR: I2C_TRANSFER failed: %d\n", ret) + return ret; + } + } + while ((buffer[0] & DSXXXX_TIME_SEC_BCDMASK) > + (seconds & DSXXXX_TIME_SEC_BCDMASK)); + + /* Format the return time */ + /* Return seconds (0-61) */ + + tp->tm_sec = rtc_bcd2bin(buffer[0] & DSXXXX_TIME_SEC_BCDMASK); + + /* Return minutes (0-59) */ + + tp->tm_min = rtc_bcd2bin(buffer[1] & DSXXXX_TIME_MIN_BCDMASK); + + /* Return hour (0-23). This assumes 24-hour time was set. */ + + tp->tm_hour = rtc_bcd2bin(buffer[2] & DSXXXX_TIME_HOUR24_BCDMASK); + + #if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* Return the day of the week (0-6) */ + + tp->tm_wday = (rtc_bcd2bin(buffer[3]) & DSXXXX_TIME_DAY_MASK) - 1; +#endif + + /* Return the day of the month (1-31) */ + + tp->tm_mday = rtc_bcd2bin(buffer[4] & DSXXXX_TIME_DATE_BCDMASK); + + /* Return the month (0-11) */ + + tp->tm_mon = rtc_bcd2bin(buffer[5] & DSXXXX_TIME_MONTH_BCDMASK) - 1; + + /* Return the years since 1900 */ + + tmp = rtc_bcd2bin(buffer[6] & DSXXXX_TIME_YEAR_BCDMASK); + +#if defined(CONFIG_RTC_DS3231) || defined(CONFIG_RTC_DS3232) + if ((buffer[5] & DS323X_TIME_CENTURY_MASK) == DS323X_TIME_1900) + { + tp->tm_year = tmp; + } + else + { + tp->tm_year = tmp + 100; + } +#else + /* No century indicator. The RTC will hold years since 1968 (a leap year like + * 2000) + */ + + tp->tm_year = tmp + 68; +#endif + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + struct i2c_msg_s msg[3]; + struct tm newtm; + time_t newtime; + uint8_t buffer[8]; + uint8_t seconds; + uint8_t century; + uint8_t year; + int ret; + + /* If this function is called before the RTC has been initialized then just return + * an error. + */ + + if (!g_rtc_enabled) + { + return -EAGAIN; + } + + rtc_dumptime(tp, "Setting time"); + + /* Get the broken out time */ + + newtime = (time_t)tp->tv_sec; + if (tp->tv_nsec >= 500000000) + { + /* Round up */ + + newtime++; + } + + #ifdef CONFIG_LIBC_LOCALTIME + if (localtime_r(&newtime, &newtm) == NULL) + { + rtcdbg("ERROR: localtime_r failed\n") + return -EINVAL; + } +#else + if (gmtime_r(&newtime, &newtm) == NULL) + { + rtcdbg("ERROR: gmtime_r failed\n") + return -EINVAL; + } +#endif + + rtc_dumptime(&tm, "New time"); + + /* Construct the message */ + /* Write starting with the seconds regiser */ + + buffer[0] = DSXXXX_TIME_SECR; + + /* Save seconds (0-59) converted to BCD */ + + buffer[1] = rtc_bin2bcd(newtm.tm_sec); + + /* Save minutes (0-59) converted to BCD */ + + buffer[2] = rtc_bin2bcd(newtm.tm_min); + + /* Save hour (0-23) with 24-hour time indication */ + + buffer[3] = rtc_bin2bcd(newtm.tm_hour) | DSXXXX_TIME_24; + + /* Save the day of the week (1-7) */ + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + buffer[4] = rtc_bin2bcd(newtm.tm_wday + 1); +#else + buffer[4] = 1; +#endif + + /* Save the day of the month (1-31) */ + + buffer[5] = rtc_bin2bcd(newtm.tm_mday); + +#if defined(CONFIG_RTC_DS3231) || defined(CONFIG_RTC_DS3232) + /* Handle years in the 20th vs the 21st century */ + + if (newtm.tm_year < 100) + { + /* Convert years in the range 1900-1999 */ + + century = DS323X_TIME_1900; + year = newtm.tm_year; + } + else + { + /* Convert years in the range 2000-2099 */ + + century = DS323X_TIME_2000; + year = newtm.tm_year - 100; + } + +#else + /* Use years since 1968 (a leap year like 2000) */ + + century = 0; + year = newtm.tm_year - 68; +#endif + + /* Save the month (1-12) with century */ + + buffer[6] = rtc_bin2bcd(newtm.tm_mon + 1) | century; + + /* Save the year */ + + buffer[7] = rtc_bin2bcd(year); + + /* Setup the I2C message */ + + msg[0].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[0].addr = DS3231_I2C_ADDRESS; + msg[0].flags = 0; + msg[0].buffer = buffer; + msg[0].length = 8; + + /* Read back the seconds register */ + + msg[1].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[1].addr = DS3231_I2C_ADDRESS; + msg[1].flags = 0; + msg[1].buffer = buffer; + msg[1].length = 1; + + msg[2].frequency = CONFIG_DS3231_I2C_FREQUENCY; + msg[2].addr = DS3231_I2C_ADDRESS; + msg[2].flags = I2C_M_READ; + msg[2].buffer = &seconds; + msg[2].length = 1; + + /* Perform the transfer. This transfer will be repeated if the seconds + * count rolls over to a smaller value while writing. + */ + + do + { + ret = I2C_TRANSFER(g_ds3231.i2c, msg, 3); + if (ret < 0) + { + rtcdbg("ERROR: I2C_TRANSFER failed: %d\n", ret) + return ret; + } + } + while ((buffer[1] & DSXXXX_TIME_SEC_BCDMASK) > + (seconds & DSXXXX_TIME_SEC_BCDMASK)); + + return OK; +} + +#endif /* CONFIG_RTC_DSXXXX */ diff --git a/drivers/timers/ds3231.h b/drivers/timers/ds3231.h new file mode 100644 index 0000000000000000000000000000000000000000..737e0b48f283ac91cc2147fc99d479677c3d7d1f --- /dev/null +++ b/drivers/timers/ds3231.h @@ -0,0 +1,345 @@ +/**************************************************************************** + * drivers/timers/ds3231.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __DRIVERS_TIMERS_DS3231_H +#define __DRIVERS_TIMERS_DS3231_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DSXXXX_TIME_SECR 0x00 /* Seconds register */ +# define DSXXXX_TIME_SEC_SHIFT 0 /* Bits 0-3: Seconds, range 0-9 */ +# define DSXXXX_TIME_SEC_MASK (15 << DSXXXX_TIME_SEC_SHIFT) +# define DSXXXX_TIME_SEC(n) ((uint8_t)(n) << DSXXXX_TIME_SEC_SHIFT) +# define DSXXXX_TIME_10SEC_SHIFT 4 /* Bits 4-6: 10 seconds, range 0-5 */ +# define DSXXXX_TIME_10SEC_MASK (7 << DSXXXX_TIME_10SEC_SHIFT) +# define DSXXXX_TIME_10SEC(n) ((uint8_t)(n) << DSXXXX_TIME_10SEC_SHIFT) +# define DSXXXX_TIME_SEC_BCDMASK (DSXXXX_TIME_SEC_MASK | DSXXXX_TIME_10SEC_MASK) +#if defined(CONFIG_RTC_DS1302) || defined(CONFIG_RTC_DS1307) +# define DS130x_TIME_CH (1 << 7) /* Bit 7: Clock halt */ +#endif + +#define DSXXXX_TIME_MINR 0x01 /* Minutes register */ +# define DSXXXX_TIME_MIN_SHIFT 0 /* Bits 0-3: Minutes, range 0-9 */ +# define DSXXXX_TIME_MIN_MASK (15 << DSXXXX_TIME_MIN_SHIFT) +# define DSXXXX_TIME_MIN(n) ((uint8_t)(n) << DSXXXX_TIME_MIN_SHIFT) +# define DSXXXX_TIME_10MIN_SHIFT 4 /* Bits 4-6: 10 minutes, range 0-5 */ +# define DSXXXX_TIME_10MIN_MASK (7 << DSXXXX_TIME_10MIN_SHIFT) +# define DSXXXX_TIME_10MIN(n) ((uint8_t)(n) << DSXXXX_TIME_10MIN_SHIFT) +# define DSXXXX_TIME_MIN_BCDMASK (DSXXXX_TIME_MIN_MASK | DSXXXX_TIME_10MIN_MASK) + +#define DSXXXX_TIME_HOURR 0x02 /* Hours register */ +# define DSXXXX_TIME_HOUR_SHIFT 0 /* Bits 0-3: Hours, range 0-9 */ +# define DSXXXX_TIME_HOUR_MASK (15 << DSXXXX_TIME_HOUR_SHIFT) +# define DSXXXX_TIME_HOUR(n) ((uint8_t)(n) << DSXXXX_TIME_HOUR_SHIFT) +# define DSXXXX_TIME_10HOUR12_SHIFT 4 /* Bit 4: 10 hours, range 0-1 */ +# define DSXXXX_TIME_10HOUR12_MASK (1 << DSXXXX_TIME_10HOUR12_SHIFT) +# define DSXXXX_TIME_10HOUR12(n) ((uint8_t)(n) << DSXXXX_TIME_10HOUR12_SHIFT) +# define DSXXXX_TIME_10HOUR24_SHIFT 4 /* Bits 4-5: 10 hours, range 0-2 */ +# define DSXXXX_TIME_10HOUR24_MASK (3 << DSXXXX_TIME_10HOUR24_SHIFT) +# define DSXXXX_TIME_10HOUR24(n) ((uint8_t)(n) << DSXXXX_TIME_10HOUR24_SHIFT) +# define DSXXXX_TIME_HOUR12_BCDMASK (DSXXXX_TIME_HOUR_MASK | DSXXXX_TIME_10HOUR12_MASK) +# define DSXXXX_TIME_HOUR24_BCDMASK (DSXXXX_TIME_HOUR_MASK | DSXXXX_TIME_10HOUR24_MASK) +# define DSXXXX_TIME_AMPM_SHIFT 5 /* Bit 5: AM/PM Indication */ +# define DSXXXX_TIME_AMPM_MASK (1 << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_AM ((uint8_t)(0) << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_PM ((uint8_t)(1) << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_1224_SHIFT 6 /* Bit 6: 12/24 Indication */ +# define DSXXXX_TIME_1224_MASK (1 << DSXXXX_TIME_1224_SHIFT) +# define DSXXXX_TIME_24 ((uint8_t)(0) << DSXXXX_TIME_1224_SHIFT) +# define DSXXXX_TIME_12 ((uint8_t)(1) << DSXXXX_TIME_1224_SHIFT) + +#define DSXXXX_TIME_DAYR 0x03 /* Day of the week register */ +# define DSXXXX_TIME_DAY_SHIFT 0 /* Bits 0-3: Day of the week, range 1-7 */ +# define DSXXXX_TIME_DAY_MASK (7 << DSXXXX_TIME_DAY_SHIFT) +# define DSXXXX_TIME_DAY(n) ((uint8_t)(n) << DSXXXX_TIME_DAY_SHIFT) + +#define DSXXXX_TIME_DATER 0x04 /* Date register */ +# define DSXXXX_TIME_DATE_SHIFT 0 /* Bits 0-3: Days, range 0-9 */ +# define DSXXXX_TIME_DATE_MASK (15 << DSXXXX_TIME_DATE_SHIFT) +# define DSXXXX_TIME_DATE(n) ((uint8_t)(n) << DSXXXX_TIME_DATE_SHIFT) +# define DSXXXX_TIME_10DATE_SHIFT 4 /* Bits 4-5: 10 days, range 0-5 */ +# define DSXXXX_TIME_10DATE_MASK (3 << DSXXXX_TIME_10DATE_SHIFT) +# define DSXXXX_TIME_10DATE(n) ((uint8_t)(n) << DSXXXX_TIME_10DATE_SHIFT) +# define DSXXXX_TIME_DATE_BCDMASK (DSXXXX_TIME_DATE_MASK | DSXXXX_TIME_10DATE_MASK) + +#define DSXXXX_TIME_MONTHR 0x05 /* Month register */ +# define DSXXXX_TIME_MONTH_SHIFT 0 /* Bits 0-3: Month, range 0-9 */ +# define DSXXXX_TIME_MONTH_MASK (15 << DSXXXX_TIME_MONTH_SHIFT) +# define DSXXXX_TIME_MONTH(n) ((uint8_t)(n) << DSXXXX_TIME_MONTH_SHIFT) +# define DSXXXX_TIME_10MONTH_SHIFT 4 /* Bit 4: 10 month, range 0-1 */ +# define DSXXXX_TIME_10MONTH_MASK (1 << DSXXXX_TIME_10MONTH_SHIFT) +# define DSXXXX_TIME_10MONTH(n) ((uint8_t)(n) << DSXXXX_TIME_10MONTH_SHIFT) +# define DSXXXX_TIME_MONTH_BCDMASK (DSXXXX_TIME_MONTH_MASK | DSXXXX_TIME_10MONTH_MASK) +#if defined(CONFIG_RTC_DS3231) || defined(CONFIG_RTC_DS3232) || defined(CONFIG_RTC_DS3234) +# define DS323X_TIME_CENTURY_SHIFT 7 /* Bit 7: Century Indication */ +# define DS323X_TIME_CENTURY_MASK (1 << DS323X_TIME_CENTURY_SHIFT) +# define DS323X_TIME_1900 ((uint8_t)(0) << DS323X_TIME_CENTURY_SHIFT) +# define DS323X_TIME_2000 ((uint8_t)(1) << DS323X_TIME_CENTURY_SHIFT) +#endif + +#define DSXXXX_TIME_YEARR 0x06 /* Date register */ +# define DSXXXX_TIME_YEAR_SHIFT 0 /* Bits 0-3: Year, range 0-9 */ +# define DSXXXX_TIME_YEAR_MASK (15 << DSXXXX_TIME_YEAR_SHIFT) +# define DSXXXX_TIME_YEAR(n) ((uint8_t)(n) << DSXXXX_TIME_YEAR_SHIFT) +# define DSXXXX_TIME_10YEAR_SHIFT 4 /* Bits 4-7: 10 year, range 0-9 */ +# define DSXXXX_TIME_10YEAR_MASK (15 << DSXXXX_TIME_10YEAR_SHIFT) +# define DSXXXX_TIME_10YEAR(n) ((uint8_t)(n) << DSXXXX_TIME_10YEAR_SHIFT) +# define DSXXXX_TIME_YEAR_BCDMASK (DSXXXX_TIME_YEAR_MASK | DSXXXX_TIME_10YEAR_MASK) + +#ifdef CONFIG_RTC_DS1302 +# define DS1302_CR 0x07 /* Control register */ +# define DS1302_CR_WP (1 << 7) /* Bit 7: Write protect */ + +# define DS1302_TCR 0x08 /* Trickle charge register */ +# define DS1302_TCR_RS_SHIFT (0) /* Bits 0-1: Reistance select */ +# define DS1302_TCR_RS_MASK (3 << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_RS(n) ((uint8_t)(n) << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_RS_DISABLED (0 << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_RS_2OHM (1 << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_RS_4OHM (2 << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_RS_8OHM (3 << DS1302_TCR_RS_SHIFT) +# define DS1302_TCR_DS_SHIFT (4) /* Bits 2-3: Diode select */ +# define DS1302_TCR_DS_MASK (3 << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_DS(n) ((uint8_t)(n) << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_DS_DISABLED (0 << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_DS_1DIODE (1 << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_DS_2DIODE (2 << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_DS_DISABLED_2 (3 << DS1302_TCR_DS_SHIFT) +# define DS1302_TCR_TCS_SHIFT (4) /* Bits 4-7: Trickle charge select */ +# define DS1302_TCR_TCS_MASK (15 << DS1302_TCR_TCS_SHIFT) +# define DS1302_TCR_TCS(n) ((uint8_t)(n) << DS1302_TCR_TCS_SHIFT) + +# define DS1302_TCR_DISABLED (DS1302_TCR_RS_DISABLED | DS1302_TCR_DS_DISABLED | define DS1302_TCR_TCS(0)) +# define DS1302_TCR_1DIODE_2OHM (DS1302_TCR_RS_2OHM | DS1302_TCR_DS_1DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_1DIODE_4OHM (DS1302_TCR_RS_4OHM | DS1302_TCR_DS_1DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_1DIODE_8OHM (DS1302_TCR_RS_8OHM | DS1302_TCR_DS_1DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_2DIODE_2OHM (DS1302_TCR_RS_2OHM | DS1302_TCR_DS_2DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_2DIODE_4OHM (DS1302_TCR_RS_4OHM | DS1302_TCR_DS_2DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_2DIODE_8OHM (DS1302_TCR_RS_8OHM | DS1302_TCR_DS_2DIODE | define DS1302_TCR_TCS(10)) +# define DS1302_TCR_INIT (DS1302_TCR_RS_DISABLED | DS1302_TCR_DS_DISABLED_2 | define DS1302_TCR_TCS(5)) +#endif + +#ifdef CONFIG_RTC_DS1307 +# define DS1307_CR 0x07 /* Control register */ +# define DS1307_CR_RS_SHIFT (3) /* Bits 0-1: Rate selection */ +# define DS1307_CR_RS_MASK (3 << DS1307_CR_RS_SHIFT) +# define DS1307_CR_RS_1HZ (0 << DS1307_CR_RS_SHIFT) /* 1Hz */ +# define DS1307_CR_RS_4KHZ (1 << DS1307_CR_RS_SHIFT) /* 4.096kHz */ +# define DS1307_CR_RS_8KHZ (2 << DS1307_CR_RS_SHIFT) /* 8.192kHz */ +# define DS1307_CR_RS_32KHZ (3 << DS1307_CR_RS_SHIFT) /* 32.768kHz */ +# define DS1307_CR_SQWE (1 << 4) /* Bit 4: Square wave enable */ +# define DS1307_CR_OUT (1 << 7) /* Bit 7: Output control */ +# define DS1307_RAM_BASER 0x08 /* 0x08-0x3f: 56x8 RAM */ +#endif + +#if defined(CONFIG_RTC_DS3231) || defined(CONFIG_RTC_DS3232) || defined(CONFIG_RTC_DS3234) +# define DS323X_ALARM1_SECR 0x07 /* Alarm1 seconds register */ +# define DS323X_ALARM1_SEC_SHIFT 0 /* Bits 0-3: Seconds, range 0-9 */ +# define DS323X_ALARM1_SEC_MASK (15 << DS323X_ALARM1_SEC_SHIFT) +# define DS323X_ALARM1_SEC(n) ((uint8_t)(n) << DS323X_ALARM1_SEC_SHIFT) +# define DS323X_ALARM1_10SEC_SHIFT 4 /* Bits 4-6: 10 seconds, range 0-5 */ +# define DS323X_ALARM1_10SEC_MASK (7 << DS323X_ALARM1_10SEC_SHIFT) +# define DS323X_ALARM1_10SEC(n) ((uint8_t)(n) << DS323X_ALARM1_10SEC_SHIFT) +# define DS323X_ALARM1_SEC_BCDMASK (DS323X_ALARM1_SEC_MASK | DS323X_ALARM1_10SEC_MASK) +# define DS323X_ALARM1_A1M1_SHIFT 7 /* Bits 7: A1M1 mask */ +# define DS323X_ALARM1_A1M1_MASK (1 << DS323X_ALARM1_A1M1_SHIFT) +# define DS323X_ALARM1_A1M1(n) ((uint8_t)(n) << DS323X_ALARM1_A1M1_SHIFT) + +# define DS323X_ALARM1_MINR 0x08 /* Alarm1 minutes register */ +# define DS323X_ALARM1_MIN_SHIFT 0 /* Bits 0-3: Minutes, range 0-9 */ +# define DS323X_ALARM1_MIN_MASK (15 << DS323X_ALARM1_MIN_SHIFT) +# define DS323X_ALARM1_MIN(n) ((uint8_t)(n) << DS323X_ALARM1_MIN_SHIFT) +# define DS323X_ALARM1_10MIN_SHIFT 4 /* Bits 4-6: 10 minutes, range 0-5 */ +# define DS323X_ALARM1_10MIN_MASK (7 << DS323X_ALARM1_10MIN_SHIFT) +# define DS323X_ALARM1_10MIN(n) ((uint8_t)(n) << DS323X_ALARM1_10MIN_SHIFT) +# define DS323X_ALARM1_MIN_BCDMASK (DS323X_ALARM1_MIN_MASK | DS323X_ALARM1_10MIN_MASK) +# define DS323X_ALARM1_A1M2_SHIFT 7 /* Bits 7: A1M2 mask */ +# define DS323X_ALARM1_A1M2_MASK (1 << DS323X_ALARM1_A1M2_SHIFT) +# define DS323X_ALARM1_A1M2(n) ((uint8_t)(n) << DS323X_ALARM1_A1M2_SHIFT) + +# define DS323X_ALARM1_HOURR 0x09 /* Alarm1 hours register */ +# define DS323X_ALARM1_HOUR_SHIFT 0 /* Bits 0-3: Hours, range 0-9 */ +# define DS323X_ALARM1_HOUR_MASK (15 << DS323X_ALARM1_HOUR_SHIFT) +# define DS323X_ALARM1_HOUR(n) ((uint8_t)(n) << DS323X_ALARM1_HOUR_SHIFT) +# define DS323X_ALARM1_10HOUR12_SHIFT 4 /* Bit 4: 10 hours, range 0-1 */ +# define DS323X_ALARM1_10HOUR12_MASK (1 << DS323X_ALARM1_10HOUR12_SHIFT) +# define DS323X_ALARM1_10HOUR12(n) ((uint8_t)(n) << DS323X_ALARM1_10HOUR12_SHIFT) +# define DS323X_ALARM1_10HOUR24_SHIFT 4 /* Bits 4-5: 10 hours, range 0-2 */ +# define DS323X_ALARM1_10HOUR24_MASK (3 << DS323X_ALARM1_10HOUR24_SHIFT) +# define DS323X_ALARM1_10HOUR24(n) ((uint8_t)(n) << DS323X_ALARM1_10HOUR24_SHIFT) +# define DS323X_ALARM1_HOUR12_BCDMASK (DS323X_ALARM1_HOUR_MASK | DS323X_ALARM1_10HOUR12_MASK) +# define DS323X_ALARM1_HOUR24_BCDMASK (DS323X_ALARM1_HOUR_MASK | DS323X_ALARM1_10HOUR24_MASK) +# define DS323X_ALARM1_AMPM_SHIFT 5 /* Bit 5: AM/PM Indication */ +# define DS323X_ALARM1_AMPM_MASK (1 << DS323X_ALARM1_AMPM_SHIFT) +# define DS323X_ALARM1_AM ((uint8_t)(0) << DS323X_ALARM1_AMPM_SHIFT) +# define DS323X_ALARM1_PM ((uint8_t)(1) << DS323X_ALARM1_AMPM_SHIFT) +# define DS323X_ALARM1_1224_SHIFT 6 /* Bit 6: 12/24 Indication */ +# define DS323X_ALARM1_1224_MASK (1 << DS323X_ALARM1_1224_SHIFT) +# define DS323X_ALARM1_12 ((uint8_t)(0) << DS323X_ALARM1_1224_SHIFT) +# define DS323X_ALARM1_24 ((uint8_t)(1) << DS323X_ALARM1_1224_SHIFT) +# define DS323X_ALARM1_A1M3_SHIFT 7 /* Bits 7: A1M3 mask */ +# define DS323X_ALARM1_A1M3_MASK (1 << DS323X_ALARM1_A1M3_SHIFT) +# define DS323X_ALARM1_A1M3(n) ((uint8_t)(n) << DS323X_ALARM1_A1M3_SHIFT) + +# define DS323X_ALARM1_DAYDATER 0x0a /* Alarm1 date / day of the week register */ +# define DS323X_ALARM1_DAY_SHIFT 0 /* Bits 0-3: Day of the week, range 1-7 */ +# define DS323X_ALARM1_DAY_MASK (7 << DS323X_ALARM1_DAY_SHIFT) +# define DS323X_ALARM1_DAY(n) ((uint8_t)(n) << DS323X_ALARM1_DAY_SHIFT) +# define DS323X_ALARM1_DATE_SHIFT 0 /* Bits 0-3: Days, range 0-9 */ +# define DS323X_ALARM1_DATE_MASK (15 << DS323X_ALARM1_DATE_SHIFT) +# define DS323X_ALARM1_DATE(n) ((uint8_t)(n) << DS323X_ALARM1_DATE_SHIFT) +# define DS323X_ALARM1_10DATE_SHIFT 4 /* Bits 4-5: 10 days, range 0-5 */ +# define DS323X_ALARM1_10DATE_MASK (3 << DS323X_ALARM1_10DATE_SHIFT) +# define DS323X_ALARM1_10DATE(n) ((uint8_t)(n) << DS323X_ALARM1_10DATE_SHIFT) +# define DS323X_ALARM1_DATE_BCDMASK (DS323X_ALARM1_DATE_MASK | DS323X_ALARM1_10DATE_MASK) +# define DS323X_ALARM1_DYDT_SHIFT 6 /* Bits 6: DY/DT */ +# define DS323X_ALARM1_DYDT_MASK (1 << DS323X_ALARM1_DYDT_SHIFT) +# define DS323X_ALARM1_DYDT_DATE ((uint8_t)(0) << DS323X_ALARM1_DYDT_SHIFT) +# define DS323X_ALARM1_DYDT_DAY ((uint8_t)(1) << DS323X_ALARM1_DYDT_SHIFT) +# define DS323X_ALARM1_A1M4_SHIFT 7 /* Bits 7: A1M4 mask */ +# define DS323X_ALARM1_A1M4_MASK (1 << DS323X_ALARM1_A1M4_SHIFT) +# define DS323X_ALARM1_A1M4(n) ((uint8_t)(n) << DS323X_ALARM1_A1M4_SHIFT) + +# define DS323X_ALARM2_MINR 0x0b /* Alarm2 minutes register */ +# define DS323X_ALARM2_MIN_SHIFT 0 /* Bits 0-3: Minutes, range 0-9 */ +# define DS323X_ALARM2_MIN_MASK (15 << DS323X_ALARM2_MIN_SHIFT) +# define DS323X_ALARM2_MIN(n) ((uint8_t)(n) << DS323X_ALARM2_MIN_SHIFT) +# define DS323X_ALARM2_10MIN_SHIFT 4 /* Bits 4-6: 10 minutes, range 0-5 */ +# define DS323X_ALARM2_10MIN_MASK (7 << DS323X_ALARM2_10MIN_SHIFT) +# define DS323X_ALARM2_10MIN(n) ((uint8_t)(n) << DS323X_ALARM2_10MIN_SHIFT) +# define DS323X_ALARM2_MIN_BCDMASK (DS323X_ALARM2_MIN_MASK | DS323X_ALARM2_10MIN_MASK) +# define DS323X_ALARM2_A2M2_SHIFT 7 /* Bits 7: A2M2 mask */ +# define DS323X_ALARM2_A2M2_MASK (1 << DS323X_ALARM2_A2M2_SHIFT) +# define DS323X_ALARM2_A2M2(n) ((uint8_t)(n) << DS323X_ALARM2_A2M2_SHIFT) + +# define DS323X_ALARM2_HOURR 0x0c /* Alarm2 hours register */ +# define DS323X_ALARM2_HOUR_SHIFT 0 /* Bits 0-3: Hours, range 0-9 */ +# define DS323X_ALARM2_HOUR_MASK (15 << DS323X_ALARM2_HOUR_SHIFT) +# define DS323X_ALARM2_HOUR(n) ((uint8_t)(n) << DS323X_ALARM2_HOUR_SHIFT) +# define DS323X_ALARM2_10HOUR12_SHIFT 4 /* Bit 4: 10 hours, range 0-1 */ +# define DS323X_ALARM2_10HOUR12_MASK (1 << DS323X_ALARM2_10HOUR12_SHIFT) +# define DS323X_ALARM2_10HOUR12(n) ((uint8_t)(n) << DS323X_ALARM2_10HOUR12_SHIFT) +# define DS323X_ALARM2_10HOUR24_SHIFT 4 /* Bits 4-5: 10 hours, range 0-2 */ +# define DS323X_ALARM2_10HOUR24_MASK (3 << DS323X_ALARM2_10HOUR24_SHIFT) +# define DS323X_ALARM2_10HOUR24(n) ((uint8_t)(n) << DS323X_ALARM2_10HOUR24_SHIFT) +# define DS323X_ALARM2_HOUR12_BCDMASK (DS323X_ALARM2_HOUR_MASK | DS323X_ALARM2_10HOUR12_MASK) +# define DS323X_ALARM2_HOUR24_BCDMASK (DS323X_ALARM2_HOUR_MASK | DS323X_ALARM2_10HOUR24_MASK) +# define DS323X_ALARM2_AMPM_SHIFT 5 /* Bit 5: AM/PM Indication */ +# define DS323X_ALARM2_AMPM_MASK (1 << DS323X_ALARM2_AMPM_SHIFT) +# define DS323X_ALARM2_AM ((uint8_t)(0) << DS323X_ALARM2_AMPM_SHIFT) +# define DS323X_ALARM2_PM ((uint8_t)(1) << DS323X_ALARM2_AMPM_SHIFT) +# define DS323X_ALARM2_1224_SHIFT 6 /* Bit 6: 12/24 Indication */ +# define DS323X_ALARM2_1224_MASK (1 << DS323X_ALARM2_1224_SHIFT) +# define DS323X_ALARM2_12 ((uint8_t)(0) << DS323X_ALARM2_1224_SHIFT) +# define DS323X_ALARM2_24 ((uint8_t)(1) << DS323X_ALARM2_1224_SHIFT) +# define DS323X_ALARM2_A2M3_SHIFT 7 /* Bits 7: A2M3 mask */ +# define DS323X_ALARM2_A2M3_MASK (1 << DS323X_ALARM2_A2M3_SHIFT) +# define DS323X_ALARM2_A2M3(n) ((uint8_t)(n) << DS323X_ALARM2_A2M3_SHIFT) + +# define DS323X_ALARM2_DAYDATER 0x0d /* Alarm2 date / day of the week register */ +# define DS323X_ALARM2_DAY_SHIFT 0 /* Bits 0-3: Day of the week, range 1-7 */ +# define DS323X_ALARM2_DAY_MASK (7 << DS323X_ALARM2_DAY_SHIFT) +# define DS323X_ALARM2_DAY(n) ((uint8_t)(n) << DS323X_ALARM2_DAY_SHIFT) +# define DS323X_ALARM2_DATE_SHIFT 0 /* Bits 0-3: Days, range 0-9 */ +# define DS323X_ALARM2_DATE_MASK (15 << DS323X_ALARM2_DATE_SHIFT) +# define DS323X_ALARM2_DATE(n) ((uint8_t)(n) << DS323X_ALARM2_DATE_SHIFT) +# define DS323X_ALARM2_10DATE_SHIFT 4 /* Bits 4-5: 10 days, range 0-5 */ +# define DS323X_ALARM2_10DATE_MASK (3 << DS323X_ALARM2_10DATE_SHIFT) +# define DS323X_ALARM2_10DATE(n) ((uint8_t)(n) << DS323X_ALARM2_10DATE_SHIFT) +# define DS323X_ALARM2_DATE_BCDMASK (DS323X_ALARM2_DATE_MASK | DS323X_ALARM2_10DATE_MASK) +# define DS323X_ALARM2_DYDT_SHIFT 6 /* Bits 6: DY/DT */ +# define DS323X_ALARM2_DYDT_MASK (1 << DS323X_ALARM2_DYDT_SHIFT) +# define DS323X_ALARM2_DYDT_DATE ((uint8_t)(0) << DS323X_ALARM2_DYDT_SHIFT) +# define DS323X_ALARM2_DYDT_DAY ((uint8_t)(1) << DS323X_ALARM2_DYDT_SHIFT) +# define DS323X_ALARM2_A2M4_SHIFT 7 /* Bits 7: A2M4 mask */ +# define DS323X_ALARM2_A2M4_MASK (1 << DS323X_ALARM2_A2M4_SHIFT) +# define DS323X_ALARM2_A2M4(n) ((uint8_t)(n) << DS3231_ALARM2_A2M4_SHIFT) + +# define DS323X_CR 0x0e /* Control register */ +# define DS323X_CR_A1IE (1 << 0) /* Bit 0: Alarm 1 interrupt enable */ +# define DS323X_CR_A2IE (1 << 1) /* Bit 1: Alarm 2 interrupt enable */ +# define DS323X_CR_INTCN (1 << 2) /* Bit 2: Interrupt control */ +# define DS323X_CR_RS_SHIFT (3) /* Bits 3-4: Rate selection */ +# define DS323X_CR_RS_MASK (3 << DS323X_CR_RS_SHIFT) +# define DS323X_CR_RS_1HZ (0 << DS323X_CR_RS_SHIFT) /* 1Hz */ +# define DS323X_CR_RS_1KHZ (1 << DS323X_CR_RS_SHIFT) /* 1.024kHz */ +# define DS323X_CR_RS_4KHZ (2 << DS323X_CR_RS_SHIFT) /* 4.096kHz */ +# define DS323X_CR_RS_8KHZ (3 << DS323X_CR_RS_SHIFT) /* 8.192kHz */ +# define DS323X_CR_CONV (1 << 5) /* Bit 5: Convert temperature */ +# define DS323X_CR_BBSQW (1 << 6) /* Bit 6: Battery backed square wave enable */ +# define DS323X_CR_EOSC (1 << 7) /* Bit 7: Enable oscillator */ + +# define DS323X_CSR 0x0f /* Control/status register */ +# define DS323X_CSR_A1F (1 << 0) /* Bit 0: Alarm 1 flag */ +# define DS323X_CSR_A2F (1 << 1) /* Bit 1: Alarm 2 flag */ +# define DS323X_CSR_BSY (1 << 2) /* Bit 2: Busy */ +# define DS323X_CSR_EN32kHz (1 << 3) /* Bit 3: Enable 32kHz output */ +# if defined(CONFIG_RTC_DS3232) || defined(CONFIG_RTC_DS3234) +# define DS323x_CSR_CRATE_SHIFT (4) /* Bits 4-5: Conversion rate */ +# define DS323x_CSR_CRATE_MASK (3 << DS323x_CSR_CRATE_SHIFT) +# define DS323x_CSR_CRATE_64SEC (0 << DS323x_CSR_CRATE_SHIFT) +# define DS323x_CSR_CRATE_128SEC (1 << DS323x_CSR_CRATE_SHIFT) +# define DS323x_CSR_CRATE_256SEC (2 << DS323x_CSR_CRATE_SHIFT) +# define DS323x_CSR_CRATE_512SEC (3 << DS323x_CSR_CRATE_SHIFT) +# define DS323x_CSR_BB32KHZ (1 << 6) /* Bit 6: Battery-Backed 32kHz Output */ +# endif +# define DS323X_CSR_OSF (1 << 7) /* Bit 7: Oscillator stop flag */ + +# define DS323X_AGINGR 0x10 /* Aging offset register (8-bit, 2's complement) */ + +# define DS323X_TMPMR 0x11 /* MSB of temp register (8-bit, 2's complement) */ + +# define DS323X_TMPLR 0x12 /* LSB of temp register (2-bits) */ +# define DS323X_TMPLR_MASK 0xc0 /* Bits 6-7: LSB of temp register (2-bits) */ +#endif /* CONFIG_RTC_DS3231 || CONFIG_RTC_DS3232 || CONFIG_RTC_DS3234 */ + +#ifdef CONFIG_RTC_DS3232 +# define DS3232_SRAM_BASER 0x14 /* 0x14-0xff: SRAM */ +#endif /* CONFIG_RTC_DS3232 */ + +#ifdef CONFIG_RTC_DS3234 +# define DS3234_SRAM_ADDRR 0x98 /* SRAM address register */ +# define DS3234_SRAM_DATAR 0x99 /* SRAM data register */ +#endif /* CONFIG_RTC_DS3234 */ + +#endif /* __DRIVERS_TIMERS_DS3231_H */ diff --git a/drivers/timers/pcf85263.c b/drivers/timers/pcf85263.c new file mode 100644 index 0000000000000000000000000000000000000000..0128e354f23d60251225f82cf5ace6346ef756fd --- /dev/null +++ b/drivers/timers/pcf85263.c @@ -0,0 +1,531 @@ +/************************************************************************************ + * drivers/timers/pcf85263.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "pcf85263.h" + +#ifdef CONFIG_RTC_PCF85263 + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* This RTC implementation supports only date/time RTC hardware */ + +#ifndef CONFIG_RTC_DATETIME +# error CONFIG_RTC_DATETIME must be set to use this driver +#endif + +#ifdef CONFIG_RTC_HIRES +# error CONFIG_RTC_HIRES must NOT be set with this driver +#endif + +#ifndef CONFIG_PCF85263_I2C_FREQUENCY +# error CONFIG_PCF85263_I2C_FREQUENCY is not configured +# define CONFIG_PCF85263_I2C_FREQUENCY 400000 +#endif + +#if CONFIG_PCF85263_I2C_FREQUENCY > 400000 +# error CONFIG_PCF85263_I2C_FREQUENCY is out of range +#endif + +#define PCF85263_I2C_ADDRESS 0x51 + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_RTC +#endif + +/* Debug ****************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +# define rtcdbg dbg +# define rtcvdbg vdbg +# define rtclldbg lldbg +# define rtcllvdbg llvdbg +#else +# define rtcdbg(x...) +# define rtcvdbg(x...) +# define rtclldbg(x...) +# define rtcllvdbg(x...) +#endif + +/************************************************************************************ + * Priviate Types + ************************************************************************************/ +/* This structure describes the state of the PCF85263 chip. Only a single RTC is + * supported. + */ + +struct pcf85263_dev_s +{ + FAR struct i2c_master_s *i2c; /* Contained reference to the I2C bus driver */ +}; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* g_rtc_enabled is set true after the RTC has successfully initialized */ + +volatile bool g_rtc_enabled = false; + +/************************************************************************************ + * Private Data + ************************************************************************************/ +/* The state of the PCF85263 chip. Only a single RTC is supported */ + +static struct pcf85263_dev_s g_pcf85263; + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: rtc_dumptime + * + * Description: + * Show the broken out time. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_RTC +static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg) +{ + rtclldbg("%s:\n", msg); + rtclldbg(" tm_sec: %08x\n", tp->tm_sec); + rtclldbg(" tm_min: %08x\n", tp->tm_min); + rtclldbg(" tm_hour: %08x\n", tp->tm_hour); + rtclldbg(" tm_mday: %08x\n", tp->tm_mday); + rtclldbg(" tm_mon: %08x\n", tp->tm_mon); + rtclldbg(" tm_year: %08x\n", tp->tm_year); +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + rtclldbg(" tm_wday: %08x\n", tp->tm_wday); + rtclldbg(" tm_yday: %08x\n", tp->tm_yday); + rtclldbg(" tm_isdst: %08x\n", tp->tm_isdst); +#endif +} +#else +# define rtc_dumptime(tp, msg) +#endif + +/************************************************************************************ + * Name: rtc_bin2bcd + * + * Description: + * Converts a 2 digit binary to BCD format + * + * Input Parameters: + * value - The byte to be converted. + * + * Returned Value: + * The value in BCD representation + * + ************************************************************************************/ + +static uint8_t rtc_bin2bcd(int value) +{ + uint8_t msbcd = 0; + + while (value >= 10) + { + msbcd++; + value -= 10; + } + + return (msbcd << 4) | value; +} + +/************************************************************************************ + * Name: rtc_bcd2bin + * + * Description: + * Convert from 2 digit BCD to binary. + * + * Input Parameters: + * value - The BCD value to be converted. + * + * Returned Value: + * The value in binary representation + * + ************************************************************************************/ + +static int rtc_bcd2bin(uint8_t value) +{ + int tens = ((int)value >> 4) * 10; + return tens + (value & 0x0f); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: pcf85263_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence by board-specific logic. + * + * After pcf85263_rtc_initialize() is called, the OS function clock_synchronize() + * should also be called to synchronize the system timer to a hardware RTC. That + * operation is normally performed automatically by the system during clock + * initialization. However, when an external RTC is used, the board logic will + * need to explicitly re-synchronize the system timer to the RTC when the RTC + * becomes available. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int pcf85263_rtc_initialize(FAR struct i2c_master_s *i2c) +{ + /* Remember the i2c device and claim that the RTC is enabled */ + + g_pcf85263.i2c = i2c; + g_rtc_enabled = true; + return OK; +} + +/************************************************************************************ + * Name: up_rtc_getdatetime + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That + * sub-second accuracy is lost in this interface. However, since the system time + * is reinitialized on each power-up/reset, there will be no timing inaccuracy in + * the long run. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_getdatetime(FAR struct tm *tp) +{ + struct i2c_msg_s msg[4]; + uint8_t secaddr; + uint8_t buffer[7]; + uint8_t seconds; + int ret; + + /* If this function is called before the RTC has been initialized (and it will be), + * then just return the data/time of the epoch, 12:00 am, Jan 1, 1970. + */ + + if (!g_rtc_enabled) + { + tp->tm_sec = 0; + tp->tm_min = 0; + tp->tm_hour = 0; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* Jan 1, 1970 was a Thursday */ + + tp->tm_wday = 4; +#endif + + tp->tm_mday = 1; + tp->tm_mon = 0; + tp->tm_year = 70; + return -EAGAIN; + } + + /* Select to begin reading at the seconds register */ + + secaddr = PCF85263_RTC_SECONDS; + + msg[0].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[0].addr = PCF85263_I2C_ADDRESS; + msg[0].flags = 0; + msg[0].buffer = &secaddr; + msg[0].length = 1; + + /* Set up to read 7 registers: secondss, minutes, hour, day-of-week, date, + * month, year + */ + + msg[1].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[1].addr = PCF85263_I2C_ADDRESS; + msg[1].flags = I2C_M_READ; + msg[1].buffer = buffer; + msg[1].length = 7; + + /* Read the seconds register again */ + + msg[2].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[2].addr = PCF85263_I2C_ADDRESS; + msg[2].flags = 0; + msg[2].buffer = &secaddr; + msg[2].length = 1; + + msg[3].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[3].addr = PCF85263_I2C_ADDRESS; + msg[3].flags = I2C_M_READ; + msg[3].buffer = &seconds; + msg[3].length = 1; + + /* Perform the transfer. The transfer may be performed repeatedly of the + * seconds values decreases, meaning that that was a rollover in the seconds. + */ + + do + { + ret = I2C_TRANSFER(g_pcf85263.i2c, msg, 4); + if (ret < 0) + { + rtcdbg("ERROR: I2C_TRANSFER failed: %d\n", ret) + return ret; + } + } + while ((buffer[0] & PCF85263_RTC_SECONDS_MASK) > + (seconds & PCF85263_RTC_SECONDS_MASK)); + + /* Format the return time */ + /* Return seconds (0-61) */ + + tp->tm_sec = rtc_bcd2bin(buffer[0] & PCF85263_RTC_SECONDS_MASK); + + /* Return minutes (0-59) */ + + tp->tm_min = rtc_bcd2bin(buffer[1] & PCF85263_RTC_MINUTES_MASK); + + /* Return hour (0-23). This assumes 24-hour time was set. */ + + tp->tm_hour = rtc_bcd2bin(buffer[2] & PCF85263_RTC_HOURS24_MASK); + + /* Return the day of the month (1-31) */ + + tp->tm_mday = rtc_bcd2bin(buffer[3] & PCF85263_RTC_DAYS_MASK); + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* Return the day of the week (0-6) */ + + tp->tm_wday = (rtc_bcd2bin(buffer[4]) & PCF85263_RTC_WEEKDAYS_MASK); +#endif + + /* Return the month (0-11) */ + + tp->tm_mon = rtc_bcd2bin(buffer[5] & PCF85263_RTC_MONTHS_MASK) - 1; + + /* Return the years since 1900. The RTC will hold years since 1968 (a leap year + * like 2000). + */ + + tp->tm_year = rtc_bcd2bin(buffer[6]) + 68; + + rtc_dumptime(tp, "Returning"); + return OK; +} + +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + struct i2c_msg_s msg[3]; + struct tm newtm; + time_t newtime; + uint8_t buffer[9]; + uint8_t cmd; + uint8_t seconds; + int ret; + + /* If this function is called before the RTC has been initialized then just return + * an error. + */ + + if (!g_rtc_enabled) + { + return -EAGAIN; + } + + rtc_dumptime(tp, "Setting time"); + + /* Get the broken out time */ + + newtime = (time_t)tp->tv_sec; + if (tp->tv_nsec >= 500000000) + { + /* Round up */ + + newtime++; + } + + #ifdef CONFIG_LIBC_LOCALTIME + if (localtime_r(&newtime, &newtm) == NULL) + { + rtcdbg("ERROR: localtime_r failed\n") + return -EINVAL; + } +#else + if (gmtime_r(&newtime, &newtm) == NULL) + { + rtcdbg("ERROR: gmtime_r failed\n") + return -EINVAL; + } +#endif + + rtc_dumptime(&tm, "New time"); + + /* Construct the message */ + /* Write starting with the 100ths of seconds register */ + + buffer[0] = PCF85263_RTC_100TH_SECONDS; + + /* Clear the 100ths of seconds */ + + buffer[1] = 0; + + /* Save seconds (0-59) converted to BCD */ + + buffer[2] = rtc_bin2bcd(newtm.tm_sec); + + /* Save minutes (0-59) converted to BCD */ + + buffer[3] = rtc_bin2bcd(newtm.tm_min); + + /* Save hour (0-23) with 24-hour time indication */ + + buffer[4] = rtc_bin2bcd(newtm.tm_hour); + + /* Save the day of the month (1-31) */ + + buffer[5] = rtc_bin2bcd(newtm.tm_mday); + + /* Save the day of the week (1-7) */ + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + buffer[6] = rtc_bin2bcd(newtm.tm_wday); +#else + buffer[6] = 0; +#endif + + /* Save the month (1-12) */ + + buffer[7] = rtc_bin2bcd(newtm.tm_mon + 1); + + /* Save the year. Use years since 1968 (a leap year like 2000) */ + + buffer[8] = rtc_bin2bcd(newtm.tm_year - 68); + + /* Setup the I2C message */ + + msg[0].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[0].addr = PCF85263_I2C_ADDRESS; + msg[0].flags = 0; + msg[0].buffer = buffer; + msg[0].length = 9; + + /* Read back the seconds register */ + + cmd = PCF85263_RTC_SECONDS; + + msg[1].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[1].addr = PCF85263_I2C_ADDRESS; + msg[1].flags = 0; + msg[1].buffer = &cmd; + msg[1].length = 1; + + msg[2].frequency = CONFIG_PCF85263_I2C_FREQUENCY; + msg[2].addr = PCF85263_I2C_ADDRESS; + msg[2].flags = I2C_M_READ; + msg[2].buffer = &seconds; + msg[2].length = 1; + + /* Perform the transfer. This transfer will be repeated if the seconds + * count rolls over to a smaller value while writing. + */ + + do + { + ret = I2C_TRANSFER(g_pcf85263.i2c, msg, 3); + if (ret < 0) + { + rtcdbg("ERROR: I2C_TRANSFER failed: %d\n", ret) + return ret; + } + } + while ((buffer[2] & PCF85263_RTC_SECONDS_MASK) > + (seconds & PCF85263_RTC_SECONDS_MASK)); + + return OK; +} + +#endif /* CONFIG_RTC_PCF85263 */ diff --git a/drivers/timers/pcf85263.h b/drivers/timers/pcf85263.h new file mode 100644 index 0000000000000000000000000000000000000000..344a3f287328cd6004d49b314457539e46de7b39 --- /dev/null +++ b/drivers/timers/pcf85263.h @@ -0,0 +1,471 @@ +/**************************************************************************** + * drivers/timers/pcf85263.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __DRIVERS_TIMERS_PCF85263_H +#define __DRIVERS_TIMERS_PCF85263_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RTC time and date registers */ + +#define PCF85263_RTC_100TH_SECONDS 0x00 /* RTC 100ths of seconds register */ + /* Bits 0-7: 100ths of seconds register (0-99 BCD) */ + +#define PCF85263_RTC_SECONDS 0x01 /* RTC seconds register */ +# define PCF85263_RTC_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ +# define PCF85263_RTC_SECONDS_OS (1 << 7) /* Bit 7: Oscillator stop */ + +#define PCF85263_RTC_MINUTES 0x02 /* RTC minutes register */ +# define PCF85263_RTC_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ +# define PCF85263_RTC_MINUTES_EMON (1 << 7) /* Bit 7: Event monitor */ + +#define PCF85263_RTC_HOURS 0x03 /* RTC hours register */ +# define PCF85263_RTC_HOURS12_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_AMPM (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_HOURS24_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_DAYS 0x04 /* RTC days register */ +# define PCF85263_RTC_DAYS_MASK 0x3f /* Bit 0-5: Day of the month (1-31 BCD) */ + +#define PCF85263_RTC_WEEKDAYS 0x05 /* RTC day-of-week register */ +# define PCF85263_RTC_WEEKDAYS_MASK 0x07 /* Bits 0-2: Day of the week (0-6) */ + +#define PCF85263_RTC_MONTHS 0x06 /* RTC month register */ +# define PCF85263_RTC_MONTHS_MASK 0x1f /* Bits 0-4: Month (1-12 BCD) */ + +#define PCF85263_RTC_YEARS 0x07 /* RTC year register */ + /* Bits 0-7: Year (0-99 BCD) */ + +/* RTC alarm1 */ + +#define PCF85263_RTC_SECOND_ALARM1 0x08 /* RTC alarm1 seconds register */ +# define PCF85263_RTC_SECOND_ALARM1_MASK 0x7f /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_RTC_MINUTE_ALARM1 0x09 /* RTC alarm1 minutes register */ +# define PCF85263_RTC_MINUTE_ALARM1_MASK 0x7f /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_RTC_HOUR_ALARM1 0x0a /* RTC alarm1 hours register */ +# define PCF85263_RTC_HOURS12_ALARM1_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_AMPM_ALARM1 (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_HOURS24_ALARM1_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_DAY_ALARM1 0x0b /* RTC alarm1 days register */ +# define PCF85263_RTC_DAY_ALARM1_MASK 0x3f /* Bits 0-5: Days (1-31 BCD) */ + +#define PCF85263_RTC_MONTH_ALARM1 0x0c /* RTC alarm1 month register */ +# define PCF85263_RTC_MONTH_ALARM1_MASK 0x1f /* Bits 0-4: Month (1-12 BCD) */ + +/* RTC alarm2 */ + +#define PCF85263_RTC_MINUTE_ALARM2 0x0d /* RTC alarm2 seconds register */ +# define PCF85263_RTC_MINUTE_ALARM2_MASK 0x7f /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_RTC_HOUR_ALARM2 0x0e /* RTC alarm1 minutes register */ +# define PCF85263_RTC_HOURS12_ALARM2_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_AMPM_ALARM2 (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_HOURS24_ALARM2_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_WEEKDAY_ALARM 0x0f /* RTC alarm1 day-of-week register */ +# define PCF85263_RTC_WEEKDAY_ALARM_MASK 0x07 /* Bits 0-2: Day-of-week (0-6) */ + +/* RTC alarm enables */ + +#define PCF85263_RTC_ALARM_ENABLES 0x10 /* RTC alarem enables */ +# define PCF85263_RTC_ALARM_SEC_A1E (1 << 0) /* Second alarm1 enable */ +# define PCF85263_RTC_ALARM_MIN_A1E (1 << 1) /* Minute alarm1 enable */ +# define PCF85263_RTC_ALARM_HR_A1E (1 << 2) /* Hour alarm1 enable */ +# define PCF85263_RTC_ALARM_DAY_A1E (1 << 3) /* Day alarm1 enable */ +# define PCF85263_RTC_ALARM_MON_A1E (1 << 4) /* Month alarm1 enable */ +# define PCF85263_RTC_ALARM_MIN_A2E (1 << 5) /* Minute alarm2 enable */ +# define PCF85263_RTC_ALARM_HR_A2E (1 << 6) /* Hour alarm2 enable */ +# define PCF85263_RTC_ALARM_WDAY_A2E (1 << 7) /* Day-of-week alarm2 enable */ + +/* RTC timestamp1 (TSR1) */ + +#define PCF85263_RTC_TSR1_SECONDS 0x11 /* TSR1 seconds register */ +# define PCF85263_RTC_TSR1_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ +# define PCF85263_RTC_SECONDS_OS (1 << 7) /* Bit 7: Oscillator stop */ + +#define PCF85263_RTC_TSR1_MINUTES 0x12 /* TSR1 minutes register */ +# define PCF85263_RTC_TSR1_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_RTC_TSR1_HOURS 0x13 /* TSR1 hours register */ +# define PCF85263_RTC_TSR1_HOURS12_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_TSR1_AMPM (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_TSR1_HOURS24_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_TSR1_DAYS 0x14 /* TSR1 days register */ +# define PCF85263_RTC_TSR1_DAYS_MASK 0x3f /* Bits 0-5: Day of the month (1-31 BCD) */ + +#define PCF85263_RTC_TSR1_MONTHS 0x15 /* TSR1 month register */ +# define PCF85263_RTC_TSR1_MONTHS_MASK 0x1f /* Bits 0-4: Month (1-12 BCD) */ + +#define PCF85263_RTC_TSR1_YEARS 0x16 /* TSR1 year register */ + /* Bits 0-7: Year (0-99 BCD) */ + +/* RTC timestamp2 (TSR2) */ + +#define PCF85263_RTC_TSR2_SECONDS 0x17 /* TSR2 seconds register */ +# define PCF85263_RTC_TSR2_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_RTC_TSR2_MINUTES 0x18 /* TSR2 minutes register */ +# define PCF85263_RTC_TSR2_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_RTC_TSR2_HOURS 0x19 /* TSR2 hours register */ +# define PCF85263_RTC_TSR2_HOURS12_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_TSR2_AMPM (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_TSR2_HOURS24_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_TSR2_DAYS 0x1a /* TSR2 days register */ +# define PCF85263_RTC_TSR2_DAYS_MASK 0x3f /* Bits 0-5: Day of the month (1-31 BCD) */ + +#define PCF85263_RTC_TSR2_MONTHS 0x1b /* TSR2 month register */ +# define PCF85263_RTC_TSR2_MONTHS_MASK 0x1f /* Bits 0-4: Month (1-12 BCD) */ + +#define PCF85263_RTC_TSR2_YEARS 0x1c /* TSR2 year register */ + /* Bits 0-7: Year (0-99 BCD) */ + +/* RTC timestamp3 (TSR3) */ + +#define PCF85263_RTC_TSR3_SECONDS 0x1d /* TSR3 seconds register */ +# define PCF85263_RTC_TSR3_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_RTC_TSR3_MINUTES 0x1e /* TSR3 minutes register */ +# define PCF85263_RTC_TSR3_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_RTC_TSR3_HOURS 0x1f /* TSR3 hours register */ +# define PCF85263_RTC_TSR3_HOURS12_MASK 0x1f /* Bits 0-4: Hours (1-12 BCD) */ +# define PCF85263_RTC_TSR3_AMPM (1 << 5) /* Bit 5: AM/PM */ +# define PCF85263_RTC_TSR3_HOURS24_MASK 0x3f /* Bits 0-5: Hours (0-23 BCD) */ + +#define PCF85263_RTC_TSR3_DAYS 0x20 /* TSR3 days register */ +# define PCF85263_RTC_TSR3_DAYS_MASK 0x3f /* Bits 0-5: Day of the month (1-31 BCD) */ + +#define PCF85263_RTC_TSR3_MONTHS 0x21 /* TSR3 month register */ +# define PCF85263_RTC_TSR3_MONTHS_MASK 0x1f /* Bits 0-4: Month (1-12 BCD) */ + +#define PCF85263_RTC_TSR3_YEARS 0x22 /* TSR3 year register */ + /* Bits 0-7: Year (0-99 BCD) */ + +/* RTC timestamp mode control */ + +#define PCF85263_RTC_TSR_MODE 0x23 /* Timestamp mode control register */ +# define PCF85263_RTC_TSR_TSR1M_SHIFT (0) /* Bit 0-1: Timestamp register 1 mode */ +# define PCF85263_RTC_TSR_TSR1M_MASK (3 << PCF85263_RTC_TSR_TSR1M_SHIFT) +# define PCF85263_RTC_TSR_TSR1M_NONE (0 << PCF85263_RTC_TSR_TSR1M_SHIFT) /* No timestamp */ +# define PCF85263_RTC_TSR_TSR1M_FE (1 << PCF85263_RTC_TSR_TSR1M_SHIFT) /* Record First TS pin Event */ +# define PCF85263_RTC_TSR_TSR1M_LE (2 << PCF85263_RTC_TSR_TSR1M_SHIFT) /* Record Last TS pin Event */ +# define PCF85263_RTC_TSR_TSR2M_SHIFT (2) /* Bit 2-4: Timestamp register 2 mode */ +# define PCF85263_RTC_TSR_TSR2M_MASK (7 << PCF85263_RTC_TSR_TSR2M_SHIFT) +# define PCF85263_RTC_TSR_TSR2M_NONE (0 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* No timestamp */ +# define PCF85263_RTC_TSR_TSR2M_FB (1 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* Record First time switch to Battery event */ +# define PCF85263_RTC_TSR_TSR2M_LB (2 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* Record Last time switch to Battery event */ +# define PCF85263_RTC_TSR_TSR2M_LV (3 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* Record Last time switch to VDD event */ +# define PCF85263_RTC_TSR_TSR2M_FE (4 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* Record First TS pin Event */ +# define PCF85263_RTC_TSR_TSR2M_LE (5 << PCF85263_RTC_TSR_TSR2M_SHIFT) /* Record Last TS pin Event */ +# define PCF85263_RTC_TSR_TSR3M_SHIFT (6) /* Bit 6-7: Timestamp register 3 mode */ +# define PCF85263_RTC_TSR_TSR3M_MASK (3 << PCF85263_RTC_TSR_TSR3M_SHIFT) +# define PCF85263_RTC_TSR_TSR3M_NONE (0 << PCF85263_RTC_TSR_TSR3M_SHIFT) /* No timestamp */ +# define PCF85263_RTC_TSR_TSR3M_FB (1 << PCF85263_RTC_TSR_TSR3M_SHIFT) /* Record First time switch to Battery event */ +# define PCF85263_RTC_TSR_TSR3M_LB (2 << PCF85263_RTC_TSR_TSR3M_SHIFT) /* Record Last time switch to Battery event */ +# define PCF85263_RTC_TSR_TSR3M_LV (3 << PCF85263_RTC_TSR_TSR3M_SHIFT) /* Record Last time switch to VDD event */ + +/* Stop-watch time registers */ + +#define PCF85263_STW_100TH_SECONDS 0x00 /* Stopwatch 100ths of seconds register */ + /* Bits 0-7: 100ths of seconds register (0-99 BCD) */ +#define PCF85263_STW_SECONDS 0x01 /* Stopwatch seconds register */ +# define PCF85263_STW_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ +# define PCF85263_STW_SECONDS_OS (1 << 7) /* Bit 7: Oscillator stop */ + +#define PCF85263_STW_MINUTES 0x02 /* Stopwatch minutes register */ +# define PCF85263_STW_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_HOURS_XX_XX_00 0x03 /* Stopwatch hours register xx_xx_00 */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_HOURS_XX_00_XX 0x04 /* Stopwatch hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_HOURS_00_XX_XX 0x05 /* Stopwatch hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch alarm1 */ + +#define PCF85263_STW_SECOND_ALM1 0x08 /* Stopwatch alarm1 seconds register */ +# define PCF85263_STW_SECOND_ALM1_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_STW_MINUTE_ALM1 0x09 /* Stopwatch alarm1 minutes register */ +# define PCF85263_STW_MINUTE_ALM1_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_HR_XX_XX_00_ALM1 0x0a /* Stopwatch alarm1 hours register xx_xx_00 */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_HR_XX_00_XX_ALM1 0x0b /* Stopwatch alarm1 hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_HR_00_XX_XX_ALM1 0x0c /* Stopwatch alarm1 hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch alarm2 */ + +#define PCF85263_STW_MINUTE_ALM2 0x0d /* Stopwatch alarm2 minutes register */ +# define PCF85263_STW_MINUTE_ALM2_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_HR_XX_00_ALM2 0x0e /* Stopwatch alarm2 hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_HR_00_XX_ALM2 0x0f /* Stopwatch alarm2 hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch alarm enables */ + +#define PCF85263_STW_ALARM_ENABLES 0x10 /* Alarm enable control register */ +# define PCF85263_STW_SEC_A1E (1 << 0) /* Bit 0: Second alarm1 enable */ +# define PCF85263_STW_MIN_A1E (1 << 1) /* Bit 1: Minute alarm1 enable */ +# define PCF85263_STW_HR_XX_XX_00_A1E (1 << 2) /* Bit 2: Tens of hour alarm1 enable */ +# define PCF85263_STW_HR_XX_00_XX_A1E (1 << 3) /* Bit 3: Thousands of hours alarm1 enable */ +# define PCF85263_STW_HR_00_XX_XX_A1E (1 << 4) /* Bit 4: 100 thousands of hours alarm1 enable */ +# define PCF85263_STW_MIN_A2E (1 << 5) /* Bit 5: Minute alarm2 enable */ +# define PCF85263_STW_HR_XX_00_A2E (1 << 6) /* Bit 6: Tens of hours alarm2 enable */ +# define PCF85263_STW_HR_00_XX_A2E (1 << 7) /* Bit 7: Thousands of hours alarm2 enable */ + +/* Stop-watch timestamp1 (TSR1) */ + +#define PCF85263_STW_TSR1_SECONDS 0x11 /* TSR1 seconds register */ +# define PCF85263_STW_TSR1_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_STW_TSR1_MINUTES 0x12 /* TSR1 minutes register */ +# define PCF85263_STW_TSR1_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_TSR1_HR_XX_XX_00 0x13 /* Stopwatch TSR1 hours register xx_xx_00 */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR1_HR_XX_00_XX 0x14 /* Stopwatch TSR1 hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR1_HR_00_XX_XX 0x15 /* Stopwatch TSR1 hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch timestamp2 (TSR2) */ + +#define PCF85263_STW_TSR2_SECONDS 0x17 /* TSR2 seconds register */ +# define PCF85263_STW_TSR2_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_STW_TSR2_MINUTES 0x18 /* TSR2 minutes register */ +# define PCF85263_RTC_TSR2_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_TSR2_HR_XX_XX_00 0x19 /* Stopwatch TSR2 hours register xx_xx_00 */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR2_HR_XX_00_XX 0x1a /* Stopwatch TSR2 hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR2_HR_00_XX_XX 0x1b /* Stopwatch TSR2 hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch timestamp3 (TSR3) */ + +#define PCF85263_STW_TSR3_SECONDS 0x1d /* TSR3 seconds register */ +# define PCF85263_STW_TSR3_SECONDS_MASK (0x7f) /* Bits 0-6: Seconds (0-59 BCD) */ + +#define PCF85263_STW_TSR3_MINUTES 0x1e /* TSR3 minutes register */ +# define PCF85263_RTC_TSR3_MINUTES_MASK (0x7f) /* Bits 0-6: Minutes (0-59 BCD) */ + +#define PCF85263_STW_TSR3_HR_XX_XX_00 0x1f /* Stopwatch TSR3 hours register xx_xx_00 */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR3_HR_XX_00_XX 0x20 /* Stopwatch TSR3 hours register xx_00_xx */ + /* Bits 0-7: hours (0-99 BCD) */ +#define PCF85263_STW_TSR3_HR_00_XX_XX 0x21 /* Stopwatch TSR3 hours register 00_xx_xx */ + /* Bits 0-7: hours (0-99 BCD) */ + +/* Stop-watch timestamp mode control */ + +#define PCF85263_STW_TSR_MODE 0x23 /* Timestamp mode control register */ +# define PCF85263_STW_TSR_TSR1M_SHIFT (0) /* Bit 0-1: Timestamp register 1 mode */ +# define PCF85263_STW_TSR_TSR1M_MASK (3 << PCF85263_STW_TSR_TSR1M_SHIFT) +# define PCF85263_STW_TSR_TSR1M_NONE (0 << PCF85263_STW_TSR_TSR1M_SHIFT) /* No timestamp */ +# define PCF85263_STW_TSR_TSR1M_FE (1 << PCF85263_STW_TSR_TSR1M_SHIFT) /* Record First TS pin Event */ +# define PCF85263_STW_TSR_TSR1M_LE (2 << PCF85263_STW_TSR_TSR1M_SHIFT) /* Record Last TS pin Event */ +# define PCF85263_STW_TSR_TSR2M_SHIFT (2) /* Bit 2-4: Timestamp register 2 mode */ +# define PCF85263_STW_TSR_TSR2M_MASK (7 << PCF85263_STW_TSR_TSR2M_SHIFT) +# define PCF85263_STW_TSR_TSR2M_NONE (0 << PCF85263_STW_TSR_TSR2M_SHIFT) /* No timestamp */ +# define PCF85263_STW_TSR_TSR2M_FB (1 << PCF85263_STW_TSR_TSR2M_SHIFT) /* Record First time switch to Battery event */ +# define PCF85263_STW_TSR_TSR2M_LB (2 << PCF85263_STW_TSR_TSR2M_SHIFT) /* Record Last time switch to Battery event */ +# define PCF85263_STW_TSR_TSR2M_LV (3 << PCF85263_STW_TSR_TSR2M_SHIFT) /* Record Last time switch to VDD event */ +# define PCF85263_STW_TSR_TSR2M_FE (4 << PCF85263_STW_TSR_TSR2M_SHIFT) /* Record First TS pin Event */ +# define PCF85263_STW_TSR_TSR2M_LE (5 << PCF85263_STW_TSR_TSR2M_SHIFT) /* Record Last TS pin Event */ +# define PCF85263_STW_TSR_TSR3M_SHIFT (6) /* Bit 6-7: Timestamp register 3 mode */ +# define PCF85263_STW_TSR_TSR3M_MASK (3 << PCF85263_STW_TSR_TSR3M_SHIFT) +# define PCF85263_STW_TSR_TSR3M_NONE (0 << PCF85263_STW_TSR_TSR3M_SHIFT) /* No timestamp */ +# define PCF85263_STW_TSR_TSR3M_FB (1 << PCF85263_STW_TSR_TSR3M_SHIFT) /* Record First time switch to Battery event */ +# define PCF85263_STW_TSR_TSR3M_LB (2 << PCF85263_STW_TSR_TSR3M_SHIFT) /* Record Last time switch to Battery event */ +# define PCF85263_STW_TSR_TSR3M_LV (3 << PCF85263_STW_TSR_TSR3M_SHIFT) /* Record Last time switch to VDD event */ + +/* Offset register */ + +#define PCF85263_CTL_OFFSET 0x24 /* Offset regsiter */ + /* Bits 0-7: Offset value */ + +/* Control registers */ + +#define PCF85263_CTL_OSCILLATOR 0x25 /* Oscillator control register */ +# define PCF85263_CTL_OSC_CL_SHIFT (0) /* Bits 0-1: Quartz oscillator load capacitance */ +# define PCF85263_CTL_OSC_CL_MASK (3 << PCF85263_CTL_OSC_CL_SHIFT) +# define PCF85263_CTL_OSC_CL_7PF (0 << PCF85263_CTL_OSC_CL_SHIFT) /* 7.0 pF */ +# define PCF85263_CTL_OSC_CL_6PF (1 << PCF85263_CTL_OSC_CL_SHIFT) /* 6.0 pF */ +# define PCF85263_CTL_OSC_CL_12p5PF (2 << PCF85263_CTL_OSC_CL_SHIFT) /* 12.5 pF */ +# define PCF85263_CTL_OSC_OSCD_SHIFT (2) /* Bits 1-2: Oscillator driver bits */ +# define PCF85263_CTL_OSC_OSCD_MASK (3 << PCF85263_CTL_OSC_OSCD_SHIFT) +# define PCF85263_CTL_OSC_OSCD_NORMAL (0 << PCF85263_CTL_OSC_OSCD_SHIFT) /* Normal drive; RS(max): 100 kohm */ +# define PCF85263_CTL_OSC_OSCD_LOW (1 << PCF85263_CTL_OSC_OSCD_SHIFT) /* Low drive; RS(max): 60 kohm; reduced IDD */ +# define PCF85263_CTL_OSC_OSCD_HIGH (2 << PCF85263_CTL_OSC_OSCD_SHIFT) /* High drive; RS(max): 500 kohm; increased IDD */ +# define PCF85263_CTL_OSC_LOWJ (1 << 4) /* Bit 4: Low jitter mode */ +# define PCF85263_CTL_OSC_12_24 (1 << 5) /* Bit 5: 12-/24-hour mode */ +# define PCF85263_CTL_OSC_OFFM (1 << 6) /* Bit 6: Offset calibration mode */ +# define PCF85263_CTL_OSC_CLKIV (1 << 7) /* Bit 7: Output clock inversion */ + +#define PCF85263_CTL_BATTERY_SWITCH 0x26 /* Battery switch control register */ +# define PCF85263_CTL_BATTERY_BSTH (1 << 0) /* Bit 0: Threshold voltage control */ +# define PCF85263_CTL_BATTERY_BSM_SHIFT (1) /* Bits 1-2: Battery switch mode bits */ +# define PCF85263_CTL_BATTERY_BSM_MASK (3 << PCF85263_CTL_BATTERY_BSM_SHIFT) +# define PCF85263_CTL_BATTERY_BSM_VTH (0 << PCF85263_CTL_BATTERY_BSM_SHIFT) /* Switching at the Vth level */ +# define PCF85263_CTL_BATTERY_BSM_VBAT (1 << PCF85263_CTL_BATTERY_BSM_SHIFT) /* Switching at the VBAT level */ +# define PCF85263_CTL_BATTERY_BSM_MAX (2 << PCF85263_CTL_BATTERY_BSM_SHIFT) /* Switching at the higher level of Vth or VBAT */ +# define PCF85263_CTL_BATTERY_BSM_MIN (3 << PCF85263_CTL_BATTERY_BSM_SHIFT) /* Switching at the lower level of Vth or VBAT */ +# define PCF85263_CTL_BATTERY_BSRR (1 << 3) /* Bit 3: Battery switch refresh rate */ +# define PCF85263_CTL_BATTERY_BSOFF (1 << 4) /* Bit 4: Battery switch on/off */ + +#define PCF85263_CTL_PIN_IO 0x27 /* Pin input/output control register */ +# define PCF85263_CTL_INTAPM_SHIFT (0) /* Bits 0-1: INTA pin mode */ +# define PCF85263_CTL_INTAPM_MASK (3 << PCF85263_CTL_INTAPM_SHIFT) +# define PCF85263_CTL_INTAPM_CLK (0 << PCF85263_CTL_INTAPM_SHIFT) /* CLK output mode */ +# define PCF85263_CTL_INTAPM_BAT (1 << PCF85263_CTL_INTAPM_SHIFT) /* Battery mode indication */ +# define PCF85263_CTL_INTAPM_INTA (2 << PCF85263_CTL_INTAPM_SHIFT) /* INTA output */ +# define PCF85263_CTL_INTAPM_HIZ (3 << PCF85263_CTL_INTAPM_SHIFT) /* Hi-Z */ +# define PCF85263_CTL_TSPM_SHIFT (2) /* Bits 2-3: TS pin I/O control */ +# define PCF85263_CTL_TSPM_MASK (3 << PCF85263_CTL_TSPM_SHIFT) +# define PCF85263_CTL_TSPM_DISABLED (0 << PCF85263_CTL_TSPM_SHIFT) /* Disabled; input can be left floating */ +# define PCF85263_CTL_TSPM_INTB (1 << PCF85263_CTL_TSPM_SHIFT) /* INTB output; push-pull */ +# define PCF85263_CTL_TSPM_CLK (2 << PCF85263_CTL_TSPM_SHIFT) /* CLK output; push-pull */ +# define PCF85263_CTL_TSPM_INPUT (3 << PCF85263_CTL_TSPM_SHIFT) /* Input mode */ +# define PCF85263_CTL_TSIM (1 << 4) /* Bit 4: TS pin input mode */ +# define PCF85263_CTL_TSL (1 << 5) /* Bit 5: TS pin input sense */ +# define PCF85263_CTL_TSPULL (1 << 6) /* Bit 6: TS pin pull-up resistor value */ +# define PCF85263_CTL_CLKPM (1 << 7) /* Bit 7: CLK pin mode */ + +#define PCF85263_CTL_FUNCTION 0x28 /* Function control register */ +# define PCF85263_CTL_FUNC_COF_SHIFT (0) /* Bits 0-2: Clock output frequency */ +# define PCF85263_CTL_FUNC_COF_MASK (7 << PCF85263_CTL_FUNC_COF_SHIFT) /* CLK pin TS pin INTA pin */ +# define PCF85263_CTL_FUNC_COF_32KHZ (0 << PCF85263_CTL_FUNC_COF_SHIFT) /* 32768 32768 32768 */ +# define PCF85263_CTL_FUNC_COF_16KHZ (1 << PCF85263_CTL_FUNC_COF_SHIFT) /* 16384 16384 16384 */ +# define PCF85263_CTL_FUNC_COF_8KHZ (2 << PCF85263_CTL_FUNC_COF_SHIFT) /* 8192 8192 8192 */ +# define PCF85263_CTL_FUNC_COF_4KHZ (3 << PCF85263_CTL_FUNC_COF_SHIFT) /* 4096 4096 4096 */ +# define PCF85263_CTL_FUNC_COF_2KHZ (4 << PCF85263_CTL_FUNC_COF_SHIFT) /* 2048 2048 2048 */ +# define PCF85263_CTL_FUNC_COF_1KHZ (5 << PCF85263_CTL_FUNC_COF_SHIFT) /* 1024 1024 1024 */ +# define PCF85263_CTL_FUNC_COF_1HZ (6 << PCF85263_CTL_FUNC_COF_SHIFT) /* 1 1 1 */ +# define PCF85263_CTL_FUNC_COF_LOW (7 << PCF85263_CTL_FUNC_COF_SHIFT) /* static LOW static LOW Hi-Z */ +# define PCF85263_CTL_FUNC_STOPM (1 << 3) /* Bit 3: STOP mode */ +# define PCF85263_CTL_FUNC_RTCM (1 << 4) /* Bit 4: RTC mode */ +# define PCF85263_CTL_FUNC_PI_SHIFT (5) /* Bits 5-6: Periodic interrupt */ +# define PCF85263_CTL_FUNC_PI_MASK (3 << PCF85263_CTL_FUNC_PI_SHIFT) +# define PCF85263_CTL_FUNC_PI_NONE (0 << PCF85263_CTL_FUNC_PI_SHIFT) /* No periodic interrupt */ +# define PCF85263_CTL_FUNC_PI_SEC (1 << PCF85263_CTL_FUNC_PI_SHIFT) /* Once per second */ +# define PCF85263_CTL_FUNC_PI_MIN (2 << PCF85263_CTL_FUNC_PI_SHIFT) /* Once per minute */ +# define PCF85263_CTL_FUNC_PI_HOUR (3 << PCF85263_CTL_FUNC_PI_SHIFT) /* Once per hour */ +# define PCF85263_CTL_FUNC_100TH (1 << 7) /* Bit 7: 100th seconds mode */ + +#define PCF85263_CTL_INTA_ENABLE 0x29 /* Interrupt A control bits */ +# define PCF85263_CTL_INTA_WDIEA (1 << 0) /* Bit 0: Watchdog interrupt enable */ +# define PCF85263_CTL_INTA_BSIEA (1 << 1) /* Bit 1: Battery switch interrupt enable */ +# define PCF85263_CTL_INTA_TSRIEA (1 << 2) /* Bit 2: Timestamp register interrupt enable */ +# define PCF85263_CTL_INTA_A2IEA (1 << 3) /* Bit 3: Alarm2 interrupt enable */ +# define PCF85263_CTL_INTA_A1IEA (1 << 4) /* Bit 4: Alarm1 interrupt enable */ +# define PCF85263_CTL_INTA_OIEA (1 << 5) /* Bit 5: Offset correction interrupt enable */ +# define PCF85263_CTL_INTA_PIEA (1 << 6) /* Bit 6: Periodic interrupt enable */ +# define PCF85263_CTL_INTA_ILPA (1 << 7) /* Bit 7: Interrupt generates a pulse */ + +#define PCF85263_CTL_INTB_ENABLE 0x2a /* Interrupt B control bits */ +# define PCF85263_CTL_INTB_WDIEB (1 << 0) /* Bit 0: Watchdog interrupt enable */ +# define PCF85263_CTL_INTB_BSIEB (1 << 1) /* Bit 1: Battery switch interrupt enable */ +# define PCF85263_CTL_INTB_TSRIEB (1 << 2) /* Bit 2: Timestamp register interrupt enable */ +# define PCF85263_CTL_INTB_A2IEB (1 << 3) /* Bit 3: Alarm2 interrupt enable */ +# define PCF85263_CTL_INTB_A1IEB (1 << 4) /* Bit 4: Alarm1 interrupt enable */ +# define PCF85263_CTL_INTB_OIEB (1 << 5) /* Bit 5: Offset correction interrupt enable */ +# define PCF85263_CTL_INTB_PIEB (1 << 6) /* Bit 6: Periodic interrupt enable */ +# define PCF85263_CTL_INTB_ILPB (1 << 7) /* Bit 7: Interrupt generates a pulse */ + +#define PCF85263_CTL_FLAGS 0x2b /* Flag status register */ +# define PCF85263_CTL_FLAGS_TSR1F (1 << 0) /* Bit 0: Timestamp register 1 event flag */ +# define PCF85263_CTL_FLAGS_TSR2F (1 << 1) /* Bit 1: Timestamp register 2 event flag */ +# define PCF85263_CTL_FLAGS_TSR3F (1 << 2) /* Bit 2: Timestamp register 3 event flag */ +# define PCF85263_CTL_FLAGS_BSF (1 << 3) /* Bit 3: Battery switch flag */ +# define PCF85263_CTL_FLAGS_WDF (1 << 4) /* Bit 4: Watchdog flag */ +# define PCF85263_CTL_FLAGS_A1F (1 << 5) /* Bit 5: Alarm1 flag */ +# define PCF85263_CTL_FLAGS_A2F (1 << 6) /* Bit 6: Alarm2 flag */ +# define PCF85263_CTL_FLAGS_PIF (1 << 7) /* Bit 7: Periodic interrupt flag */ + +/* RAM byte */ + +#define PCF85263_CTL_RAM_BYTE 0x2c /* RAM byte register */ + /* Bits 0-7: RAM data */ + +/* Watchdog registers */ + +#define PCF85263_CTL_WATCHDOG 0x2d /* Watchdog control and status register */ +# define PCF85263_CTL_WDS_SHIFT (0) /* Bits 0-1: Watchdog step size (source clock) */ +# define PCF85263_CTL_WDS_MASK (3 << PCF85263_CTL_WDS_SHIFT) +# define PCF85263_CTL_WDS_4SEC (0 << PCF85263_CTL_WDS_SHIFT) /* 4 seconds (0.25 Hz) */ +# define PCF85263_CTL_WDS_1SEC (1 << PCF85263_CTL_WDS_SHIFT) /* 1 second (1 Hz) */ +# define PCF85263_CTL_WDS_250MSEC (2 << PCF85263_CTL_WDS_SHIFT) /* 1⁄4 second (4 Hz) */ +# define PCF85263_CTL_WDS_67MSEC (3 << PCF85263_CTL_WDS_SHIFT) /* 1⁄16 second (16 Hz) */ +# define PCF85263_CTL_WDR_SHIFT (2) /* Bits 2-6: Watchdog register bits */ +# define PCF85263_CTL_WDR_MASK (31 << PCF85263_CTL_WDR_SHIFT) +# define PCF85263_CTL_WDR(n) ((uint9_t)(n) << PCF85263_CTL_WDR_SHIFT) +# define PCF85263_CTL_WDM (1 << 7) /* Bit 7: Watchdog mode */ + +/* Stop */ + +#define PCF85263_CTL_STOP_ENABLE 0x2e /* Stop enable register */ +# define PCF85263_CTL_STOP (1 << 0) /* Bit 0: Stop bit */ + +/* Reset */ + +#define PCF85263_CTL_RESETS 0x2f /* Software reset control register */ +# define PCF85263_CTL_CTS (1 << 0) /* Bit 0: Clear timestamp */ +# define PCF85263_CTL_SR (1 << 3) /* Bit 3: Software reset */ +# define PCF85263_CTL_CPR (1 << 7) /* Bit 7: Clear prescaler */ +# define PCF85263_CTL_RESETS_BITS 0x24 /* Fixed register bits */ + +#endif /* __DRIVERS_TIMERS_PCF85263_H */ diff --git a/drivers/timers/rtc.c b/drivers/timers/rtc.c index 6d39b6c99a2212cfbe973346a12c6a8c242807dd..6c76e449b83e2d57c55ebd180fc5413582315a18 100644 --- a/drivers/timers/rtc.c +++ b/drivers/timers/rtc.c @@ -79,7 +79,8 @@ static int rtc_open(FAR struct file *filep); static int rtc_close(FAR struct file *filep); #endif -static ssize_t rtc_read(FAR struct file *filep, FAR char *, size_t); +static ssize_t rtc_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); static ssize_t rtc_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg); diff --git a/drivers/timers/timer.c b/drivers/timers/timer.c index 57c2c0eca9bb2d844a36c3e1e405520fb1d6b4ee..4e4e4d94f8efdaa6e3d035b8d998a408b06f15de 100644 --- a/drivers/timers/timer.c +++ b/drivers/timers/timer.c @@ -84,11 +84,10 @@ struct timer_upperhalf_s { uint8_t crefs; /* The number of times the device has been opened */ -//sem_t exclsem; /* Supports mutual exclusion */ FAR char *path; /* Registration path */ /* The contained lower-half driver */ - + FAR struct timer_lowerhalf_s *lower; }; @@ -143,15 +142,6 @@ static int timer_open(FAR struct file *filep) tmrvdbg("crefs: %d\n", upper->crefs); - /* Get exclusive access to the device structures */ - - ret = 1; //sem_wait(&upper->exclsem); - if (ret < 0) - { - ret = -get_errno(); - goto errout; - } - /* Increment the count of references to the device. If this the first * time that the driver has been opened for this device, then initialize * the device. @@ -163,7 +153,7 @@ static int timer_open(FAR struct file *filep) /* More than 255 opens; uint8_t overflows to zero */ ret = -EMFILE; - goto errout_with_sem; + goto errout; } /* Save the new open count */ @@ -171,9 +161,6 @@ static int timer_open(FAR struct file *filep) upper->crefs = tmp; ret = OK; -errout_with_sem: -// sem_post(&upper->exclsem); - errout: return ret; } @@ -188,21 +175,11 @@ errout: static int timer_close(FAR struct file *filep) { - FAR struct inode *inode = filep->f_inode; + FAR struct inode *inode = filep->f_inode; FAR struct timer_upperhalf_s *upper = inode->i_private; - int ret; tmrvdbg("crefs: %d\n", upper->crefs); - /* Get exclusive access to the device structures */ - - ret = 1; //sem_wait(&upper->exclsem); - if (ret < 0) - { - ret = -get_errno(); - goto errout; - } - /* Decrement the references to the driver. If the reference count will * decrement to 0, then uninitialize the driver. */ @@ -212,11 +189,7 @@ static int timer_close(FAR struct file *filep) upper->crefs--; } - //sem_post(&upper->exclsem); - ret = OK; - -errout: - return ret; + return OK; } /************************************************************************************ @@ -254,7 +227,7 @@ static ssize_t timer_write(FAR struct file *filep, FAR const char *buffer, * Description: * The standard ioctl method. This is where ALL of the timer work is * done. - * + * ************************************************************************************/ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) @@ -267,14 +240,6 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) tmrvdbg("cmd: %d arg: %ld\n", cmd, arg); DEBUGASSERT(upper && lower); - /* Get exclusive access to the device structures */ - - ret = 1; //sem_wait(&upper->exclsem); - if (ret < 0) - { - return ret; - } - /* Handle built-in ioctl commands */ switch (cmd) @@ -288,7 +253,7 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { /* Start the timer, resetting the time to the current timeout */ - if(lower->ops->start) + if (lower->ops->start) { ret = lower->ops->start(lower); } @@ -308,7 +273,7 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { /* Stop the timer */ - if(lower->ops->start) + if (lower->ops->start) { ret = lower->ops->stop(lower); } @@ -435,7 +400,6 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } - //sem_post(&upper->exclsem); return ret; } @@ -492,7 +456,6 @@ FAR void *timer_register(FAR const char *path, * by kmm_zalloc()). */ - //sem_init(&upper->exclsem, 0, 1); upper->lower = lower; /* Copy the registration path */ @@ -519,7 +482,6 @@ errout_with_path: kmm_free(upper->path); errout_with_upper: - //sem_destroy(&upper->exclsem); kmm_free(upper); errout: @@ -566,7 +528,6 @@ void timer_unregister(FAR void *handle) /* Then free all of the driver resources */ kmm_free(upper->path); - //sem_destroy(&upper->exclsem); kmm_free(upper); } diff --git a/drivers/usbdev/Kconfig b/drivers/usbdev/Kconfig index a284917ee60c3f10fe956886d9e6e7f2740ab8b8..427091d79905b022d55d93a1b4186b757588e6a1 100644 --- a/drivers/usbdev/Kconfig +++ b/drivers/usbdev/Kconfig @@ -102,7 +102,7 @@ config USBDEV_TRACE_NRECORDS Number of trace entries to remember config USBDEV_TRACE_STRINGS -bool "Decode device controller events" + bool "Decode device controller events" default n depends on USBDEV_TRACE || DEBUG_USB ---help--- @@ -116,6 +116,15 @@ bool "Decode device controller events" extern const struct trace_msg_t g_usb_trace_strings_intdecode[]; #endif +config USBDEV_TRACE_INITIALIDSET + bool "Initial enable bits" + default 0 + depends on USBDEV_TRACE + ---help--- + This is the set of initial USB features that are enabled at boot + time. See the event ID class bit definitions in + include/nuttx/usbdev_trace.h. + comment "USB Device Class Driver Options" config USBDEV_COMPOSITE @@ -235,17 +244,31 @@ config PL2303_BULKIN_REQLEN on the other hand, request buffer size is always the same as the maxpacket size. + There is also no reason from PL2303_BULKIN_REQLEN to be greater + than PL2303_TXBUFSIZE-1, since a request larger than the TX + buffer can never be sent. + config PL2303_RXBUFSIZE int "Receive buffer size" - default 256 + default 513 if USBDEV_DUALSPEED + default 257 if !USBDEV_DUALSPEED ---help--- - Size of the serial receive/transmit buffers + Size of the serial receive buffers. The actual amount of data that + can be held in the buffer is this number minus one due to the way + that the circular buffer is managed. So an RX buffer size of 257 + will hold four full-speed, 64 byte packets; a buffer size of 513 + will hold one high-speed, 512 byte packet. config PL2303_TXBUFSIZE int "Transmit buffer size" - default 256 + default 769 if USBDEV_DUALSPEED + default 193 if !USBDEV_DUALSPEED ---help--- - Size of the serial receive/transmit buffers + Size of the serial transmit buffers. The actual amount of data that + can be held in the buffer is this number minus one due to the way + that the circular buffer is managed. So a TX buffer size of 769 + will hold one request of size 768; a buffer size of 193 will hold + two requests of size 96 bytes. config PL2303_VENDORID hex "Vendor ID" @@ -410,17 +433,31 @@ config CDCACM_BULKIN_REQLEN on the other hand, request buffer size is always the same as the maxpacket size. + There is also no reason from CDCACM_BULKIN_REQLEN to be greater + than CDCACM_TXBUFSIZE-1, since a request larger than the TX + buffer can never be sent. + config CDCACM_RXBUFSIZE int "Receive buffer size" - default 256 + default 513 if USBDEV_DUALSPEED + default 257 if !USBDEV_DUALSPEED ---help--- - Size of the serial receive/transmit buffers + Size of the serial receive buffers. The actual amount of data that + can be held in the buffer is this number minus one due to the way + that the circular buffer is managed. So an RX buffer size of 257 + will hold four full-speed, 64 byte packets; a buffer size of 513 + will hold one high-speed, 512 byte packet. config CDCACM_TXBUFSIZE int "Transmit buffer size" - default 256 - ---help--- - Size of the serial receive/transmit buffers + default 769 if USBDEV_DUALSPEED + default 193 if !USBDEV_DUALSPEED + ---help--- + Size of the serial transmit buffers. The actual amount of data that + can be held in the buffer is this number minus one due to the way + that the circular buffer is managed. So a TX buffer size of 769 + will hold one request of size 768; a buffer size of 193 will hold + two requests of size 96 bytes. config CDCACM_VENDORID hex "Vendor ID" diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c index d57eb5aa419f515d01115c8e8104a459b6851a65..b4b5173678bed47f5cb2b9aa5e6164698ecfb4a7 100644 --- a/drivers/usbdev/cdcacm.c +++ b/drivers/usbdev/cdcacm.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/cdcacm.c * - * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -68,10 +69,6 @@ # include "composite.h" #endif -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -92,7 +89,7 @@ struct cdcacm_dev_s FAR struct usbdev_s *usbdev; /* usbdev driver pointer */ uint8_t config; /* Configuration number */ - uint8_t nwrq; /* Number of queue write requests (in reqlist)*/ + uint8_t nwrq; /* Number of queue write requests (in reqlist) */ uint8_t nrdq; /* Number of queue read requests (in epbulkout) */ uint8_t minor; /* The device minor number */ bool rxenabled; /* true: UART RX "interrupts" enabled */ @@ -201,7 +198,8 @@ static int cdcuart_setup(FAR struct uart_dev_s *dev); static void cdcuart_shutdown(FAR struct uart_dev_s *dev); static int cdcuart_attach(FAR struct uart_dev_s *dev); static void cdcuart_detach(FAR struct uart_dev_s *dev); -static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg); +static int cdcuart_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable); #ifdef CONFIG_SERIAL_IFLOWCONTROL static bool cdcuart_rxflowcontrol(FAR struct uart_dev_s *dev, @@ -211,7 +209,7 @@ static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable); static bool cdcuart_txempty(FAR struct uart_dev_s *dev); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /* USB class device *********************************************************/ @@ -281,7 +279,7 @@ static uint16_t cdcacm_fillrequest(FAR struct cdcacm_dev_s *priv, uint8_t *reqbu /* Disable interrupts */ - flags = irqsave(); + flags = enter_critical_section(); /* Transfer bytes while we have bytes available and there is room in the request */ @@ -316,7 +314,7 @@ static uint16_t cdcacm_fillrequest(FAR struct cdcacm_dev_s *priv, uint8_t *reqbu uart_datasent(serdev); } - irqrestore(flags); + leave_critical_section(flags); return nbytes; } @@ -349,7 +347,7 @@ static int cdcacm_sndpacket(FAR struct cdcacm_dev_s *priv) } #endif - flags = irqsave(); + flags = enter_critical_section(); /* Use our IN endpoint for the transfer */ @@ -403,7 +401,7 @@ static int cdcacm_sndpacket(FAR struct cdcacm_dev_s *priv) } } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -645,7 +643,7 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config) int i; int ret = 0; -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (priv == NULL) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -829,11 +827,11 @@ static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep, /* Extract references to private data */ - priv = (FAR struct cdcacm_dev_s*)ep->priv; + priv = (FAR struct cdcacm_dev_s *)ep->priv; /* Process the received data unless this is some unusual condition */ - flags = irqsave(); + flags = enter_critical_section(); switch (req->result) { case 0: /* Normal completion */ @@ -844,7 +842,7 @@ static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep, case -ESHUTDOWN: /* Disconnection */ usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0); priv->nrdq--; - irqrestore(flags); + leave_critical_section(flags); return; default: /* Some other error occurred */ @@ -861,7 +859,7 @@ static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep, usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result); } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -897,10 +895,10 @@ static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep, /* Return the write request to the free list */ - flags = irqsave(); - sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->reqlist); priv->nwrq++; - irqrestore(flags); + leave_critical_section(flags); /* Send the next packet unless this was some unusual termination * condition @@ -944,7 +942,7 @@ static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep, static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { - FAR struct cdcacm_dev_s *priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + FAR struct cdcacm_dev_s *priv = ((FAR struct cdcacm_driver_s *)driver)->dev; FAR struct cdcacm_req_s *reqcontainer; irqstate_t flags; uint16_t reqlen; @@ -1078,10 +1076,10 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver, reqcontainer->req->priv = reqcontainer; reqcontainer->req->callback = cdcacm_wrcomplete; - flags = irqsave(); - sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->reqlist); priv->nwrq++; /* Count of write requests available */ - irqrestore(flags); + leave_critical_section(flags); } /* Report if we are selfpowered (unless we are part of a composite device) */ @@ -1132,7 +1130,7 @@ static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + priv = ((FAR struct cdcacm_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -1207,7 +1205,7 @@ static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver, * of them) */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGASSERT(priv->nwrq == CONFIG_CDCACM_NWRREQS); while (!sq_empty(&priv->reqlist)) { @@ -1220,7 +1218,7 @@ static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver, } DEBUGASSERT(priv->nwrq == 0); - irqrestore(flags); + leave_critical_section(flags); /* Clear out all data in the circular buffer */ @@ -1261,7 +1259,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ usbtrace(TRACE_CLASSSETUP, ctrl->req); - priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + priv = ((FAR struct cdcacm_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv || !priv->ctrlreq) @@ -1387,7 +1385,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, { if (ctrl->type == USB_DIR_IN) { - *(uint8_t*)ctrlreq->buf = priv->config; + *(FAR uint8_t *)ctrlreq->buf = priv->config; ret = 1; } } @@ -1412,13 +1410,13 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, case USB_REQ_GETINTERFACE: { - if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) && priv->config == CDCACM_CONFIGIDNONE) { if ((index == CDCACM_NOTIFID && value == CDCACM_NOTALTIFID) || (index == CDCACM_DATAIFID && value == CDCACM_DATAALTIFID)) { - *(uint8_t*) ctrlreq->buf = value; + *(FAR uint8_t *) ctrlreq->buf = value; ret = 1; } else @@ -1449,7 +1447,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, case ACM_GET_LINE_CODING: { - if (ctrl->type == (USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) && index == CDCACM_NOTIFID) { /* Return the current line status from the private data structure */ @@ -1470,7 +1468,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, case ACM_SET_LINE_CODING: { - if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) && len == SIZEOF_CDC_LINECODING && /* dataout && len == outlen && */ index == CDCACM_NOTIFID) { @@ -1511,7 +1509,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, case ACM_SET_CTRL_LINE_STATE: { - if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) && index == CDCACM_NOTIFID) { /* Save the control line state in the private data structure. Only bits @@ -1537,11 +1535,11 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver, } break; - /* Sends special carrier*/ + /* Sends special carrier */ case ACM_SEND_BREAK: { - if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) && index == CDCACM_NOTIFID) { /* If there is a registered callback to handle the SendBreak request, @@ -1633,7 +1631,7 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + priv = ((FAR struct cdcacm_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -1647,7 +1645,7 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver, * connection. */ - flags = irqsave(); + flags = enter_critical_section(); #ifdef CONFIG_SERIAL_REMOVABLE uart_connected(&priv->serdev, false); #endif @@ -1661,7 +1659,7 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver, priv->serdev.xmit.head = 0; priv->serdev.xmit.tail = 0; priv->rxhead = 0; - irqrestore(flags); + leave_critical_section(flags); /* Perform the soft connect function so that we will we can be * re-enumerated (unless we are part of a composite device) @@ -1698,7 +1696,7 @@ static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + priv = ((FAR struct cdcacm_driver_s *)driver)->dev; /* And let the "upper half" driver now that we are suspended */ @@ -1732,7 +1730,7 @@ static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct cdcacm_driver_s*)driver)->dev; + priv = ((FAR struct cdcacm_driver_s *)driver)->dev; /* Are we still configured? */ @@ -1765,7 +1763,7 @@ static int cdcuart_setup(FAR struct uart_dev_s *dev) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -1775,7 +1773,7 @@ static int cdcuart_setup(FAR struct uart_dev_s *dev) /* Extract reference to private data */ - priv = (FAR struct cdcacm_dev_s*)dev->priv; + priv = (FAR struct cdcacm_dev_s *)dev->priv; /* Check if we have been configured */ @@ -1806,7 +1804,7 @@ static void cdcuart_shutdown(FAR struct uart_dev_s *dev) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -1832,8 +1830,8 @@ static int cdcuart_attach(FAR struct uart_dev_s *dev) * Name: cdcuart_detach * * Description: -* Does not apply to the USB serial class device - * + * Does not apply to the USB serial class device + * ****************************************************************************/ static void cdcuart_detach(FAR struct uart_dev_s *dev) @@ -1849,7 +1847,7 @@ static void cdcuart_detach(FAR struct uart_dev_s *dev) * ****************************************************************************/ -static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) +static int cdcuart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { struct inode *inode = filep->f_inode; struct cdcacm_dev_s *priv = inode->i_private; @@ -1933,7 +1931,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) * 1. Format and send a request header with: * * bmRequestType: - * USB_REQ_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE + * USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE * bRequest: ACM_SERIAL_STATE * wValue: 0 * wIndex: 0 @@ -1949,7 +1947,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) #ifdef CONFIG_SERIAL_TERMIOS case TCGETS: { - struct termios *termiosp = (struct termios*)arg; + struct termios *termiosp = (FAR struct termios *)arg; if (!termiosp) { @@ -1967,7 +1965,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) case TCSETS: { - struct termios *termiosp = (struct termios*)arg; + struct termios *termiosp = (FAR struct termios *)arg; if (!termiosp) { @@ -1987,7 +1985,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) case FIONREAD: { int count; - irqstate_t state = irqsave(); + irqstate_t flags = enter_critical_section(); /* Determine the number of bytes available in the buffer. */ @@ -2000,7 +1998,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) count = serdev->recv.size - (serdev->recv.tail - serdev->recv.head); } - irqrestore(state); + leave_critical_section(flags); *(int *)arg = count; ret = 0; @@ -2010,7 +2008,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) case FIONWRITE: { int count; - irqstate_t state = irqsave(); + irqstate_t flags = enter_critical_section(); /* Determine the number of bytes free in the buffer. */ @@ -2023,7 +2021,7 @@ static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg) count = serdev->xmit.size - (serdev->xmit.head - serdev->xmit.tail) - 1; } - irqrestore(state); + leave_critical_section(flags); *(int *)arg = count; ret = 0; @@ -2065,7 +2063,7 @@ static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2075,29 +2073,29 @@ static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable) /* Extract reference to private data */ - priv = (FAR struct cdcacm_dev_s*)dev->priv; + priv = (FAR struct cdcacm_dev_s *)dev->priv; serdev = &priv->serdev; /* We need exclusive access to the RX buffer and private structure * in the following. */ - flags = irqsave(); + flags = enter_critical_section(); if (enable) { - /* RX "interrupts" are enabled. Is this a transition from disabled - * to enabled state? - */ + /* RX "interrupts" are enabled. Is this a transition from disabled + * to enabled state? + */ - if (!priv->rxenabled) - { - /* Yes. During the time that RX interrupts are disabled, the - * the serial driver will be extracting data from the circular - * buffer and modifying recv.tail. During this time, we - * should avoid modifying recv.head; When interrupts are restored, - * we can update the head pointer for all of the data that we - * put into circular buffer while "interrupts" were disabled. - */ + if (!priv->rxenabled) + { + /* Yes. During the time that RX interrupts are disabled, the + * the serial driver will be extracting data from the circular + * buffer and modifying recv.tail. During this time, we + * should avoid modifying recv.head; When interrupts are restored, + * we can update the head pointer for all of the data that we + * put into circular buffer while "interrupts" were disabled. + */ if (priv->rxhead != serdev->recv.head) { @@ -2131,7 +2129,7 @@ static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable) priv->rxhead = serdev->recv.head; priv->rxenabled = false; } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -2194,7 +2192,7 @@ static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable) /* Sanity checks */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2202,9 +2200,9 @@ static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable) } #endif - /* Extract references to private data */ + /* Extract references to private data */ - priv = (FAR struct cdcacm_dev_s*)dev->priv; + priv = (FAR struct cdcacm_dev_s *)dev->priv; /* If the new state is enabled and if there is data in the XMIT buffer, * send the next packet now. @@ -2233,11 +2231,11 @@ static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable) static bool cdcuart_txempty(FAR struct uart_dev_s *dev) { - FAR struct cdcacm_dev_s *priv = (FAR struct cdcacm_dev_s*)dev->priv; + FAR struct cdcacm_dev_s *priv = (FAR struct cdcacm_dev_s *)dev->priv; usbtrace(CDCACM_CLASSAPI_TXEMPTY, 0); -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2287,7 +2285,7 @@ int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev) /* Allocate the structures needed */ - alloc = (FAR struct cdcacm_alloc_s*)kmm_malloc(sizeof(struct cdcacm_alloc_s)); + alloc = (FAR struct cdcacm_alloc_s *)kmm_malloc(sizeof(struct cdcacm_alloc_s)); if (!alloc) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0); @@ -2414,7 +2412,7 @@ int cdcacm_initialize(int minor, FAR void **handle) if (handle) { - *handle = (FAR void*)drvr; + *handle = (FAR void *)drvr; } return ret; diff --git a/drivers/usbdev/cdcacm_desc.c b/drivers/usbdev/cdcacm_desc.c index a2d2446ad400185be4b2e9ef59bbfd4da7fe5bd8..221734a71e557f97a18a3f6fa3b6fdb2ea36d5ee 100644 --- a/drivers/usbdev/cdcacm_desc.c +++ b/drivers/usbdev/cdcacm_desc.c @@ -602,7 +602,7 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf) { cdcacm_cpepdesc((FAR const struct usb_epdesc_s *)group->desc, group->hsepsize, - (FAR struct usb_epdesc_s*)dest); + (FAR struct usb_epdesc_s *)dest); } else #endif diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c index e3ff43a19d1d84586bb54845e919f529d69a4acc..b0f0c95c9c915dfae01065d660774252425c3ce4 100644 --- a/drivers/usbdev/composite.c +++ b/drivers/usbdev/composite.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/composite.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -55,10 +56,6 @@ #ifdef CONFIG_USBDEV_COMPOSITE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -146,7 +143,7 @@ const char g_compvendorstr[] = CONFIG_COMPOSITE_VENDORSTR; const char g_compproductstr[] = CONFIG_COMPOSITE_PRODUCTSTR; const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR; - /**************************************************************************** +/**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** @@ -267,7 +264,7 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep, static int composite_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { - FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s*)driver)->dev; + FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s *)driver)->dev; int ret; usbtrace(TRACE_CLASSBIND, 0); @@ -352,7 +349,7 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct composite_driver_s*)driver)->dev; + priv = ((FAR struct composite_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -368,7 +365,7 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver, { /* Unbind the constituent class drivers */ - flags = irqsave(); + flags = enter_critical_section(); CLASS_UNBIND(priv->dev1, dev); CLASS_UNBIND(priv->dev2, dev); @@ -380,7 +377,7 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver, composite_freereq(dev->ep0, priv->ctrlreq); priv->ctrlreq = NULL; } - irqrestore(flags); + leave_critical_section(flags); } } @@ -417,7 +414,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, /* Extract a reference to private data */ usbtrace(TRACE_CLASSSETUP, ctrl->req); - priv = ((FAR struct composite_driver_s*)driver)->dev; + priv = ((FAR struct composite_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -562,7 +559,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver, case USB_REQ_GETINTERFACE: { - if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) && priv->config == COMPOSITE_CONFIGIDNONE) { ret = composite_classsetup(priv, dev, ctrl, dataout, outlen); @@ -651,7 +648,7 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct composite_driver_s*)driver)->dev; + priv = ((FAR struct composite_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -665,11 +662,11 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver, * the disconnection. */ - flags = irqsave(); + flags = enter_critical_section(); priv->config = COMPOSITE_CONFIGIDNONE; CLASS_DISCONNECT(priv->dev1, dev); CLASS_DISCONNECT(priv->dev2, dev); - irqrestore(flags); + leave_critical_section(flags); /* Perform the soft connect function so that we will we can be * re-enumerated. @@ -704,7 +701,7 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct composite_driver_s*)driver)->dev; + priv = ((FAR struct composite_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -716,10 +713,10 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver, /* Forward the suspend event to the constituent devices */ - flags = irqsave(); + flags = enter_critical_section(); CLASS_SUSPEND(priv->dev1, priv->usbdev); CLASS_SUSPEND(priv->dev2, priv->usbdev); - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -746,7 +743,7 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct composite_driver_s*)driver)->dev; + priv = ((FAR struct composite_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -758,10 +755,10 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver, /* Forward the resume event to the constituent devices */ - flags = irqsave(); + flags = enter_critical_section(); CLASS_RESUME(priv->dev1, priv->usbdev); CLASS_RESUME(priv->dev2, priv->usbdev); - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -798,7 +795,7 @@ FAR void *composite_initialize(void) /* Allocate the structures needed */ - alloc = (FAR struct composite_alloc_s*)kmm_malloc(sizeof(struct composite_alloc_s)); + alloc = (FAR struct composite_alloc_s *)kmm_malloc(sizeof(struct composite_alloc_s)); if (!alloc) { usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCDEVSTRUCT), 0); @@ -872,7 +869,7 @@ errout_with_alloc: * Returned Value: * None * - ***************************************************************************/ + ****************************************************************************/ void composite_uninitialize(FAR void *handle) { diff --git a/drivers/usbdev/pl2303.c b/drivers/usbdev/pl2303.c index bb98a717ea7b76aa9af3f2ad822120a99be3a769..92285c01d155d94f677cd2df59259d79d2a1e095 100644 --- a/drivers/usbdev/pl2303.c +++ b/drivers/usbdev/pl2303.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/pl2303.c * - * Copyright (C) 2008-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This logic emulates the Prolific PL2303 serial/USB converter @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -256,7 +257,7 @@ struct pl2303_dev_s FAR struct usbdev_s *usbdev; /* usbdev driver pointer */ uint8_t config; /* Configuration number */ - uint8_t nwrq; /* Number of queue write requests (in reqlist)*/ + uint8_t nwrq; /* Number of queue write requests (in reqlist) */ uint8_t nrdq; /* Number of queue read requests (in epbulkout) */ bool rxenabled; /* true: UART RX "interrupts" enabled */ uint8_t linest[7]; /* Fake line status */ @@ -370,7 +371,7 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable); static bool usbser_txempty(FAR struct uart_dev_s *dev); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /* USB class device ********************************************************/ @@ -537,7 +538,7 @@ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *req /* Disable interrupts */ - flags = irqsave(); + flags = enter_critical_section(); /* Transfer bytes while we have bytes available and there is room in the request */ @@ -572,7 +573,7 @@ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *req uart_datasent(serdev); } - irqrestore(flags); + leave_critical_section(flags); return nbytes; } @@ -605,7 +606,7 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv) } #endif - flags = irqsave(); + flags = enter_critical_section(); /* Use our IN endpoint for the transfer */ @@ -659,7 +660,7 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv) } } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -926,7 +927,7 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) static int16_t usbclass_mkcfgdesc(uint8_t *buf) #endif { - FAR struct usb_cfgdesc_s *cfgdesc = (struct usb_cfgdesc_s*)buf; + FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf; #ifdef CONFIG_USBDEV_DUALSPEED bool hispeed = (speed == USB_SPEED_HIGH); uint16_t bulkmxpacket; @@ -975,9 +976,9 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf) bulkmxpacket = 64; } - usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, (struct usb_epdesc_s*)buf); + usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, (FAR struct usb_epdesc_s *)buf); buf += USB_SIZEOF_EPDESC; - usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, (struct usb_epdesc_s*)buf); + usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, (FAR struct usb_epdesc_s *)buf); #else memcpy(buf, &g_epbulkoutdesc, USB_SIZEOF_EPDESC); buf += USB_SIZEOF_EPDESC; @@ -1046,7 +1047,7 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) int i; int ret = 0; -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (priv == NULL) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -1212,11 +1213,11 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, /* Extract references to private data */ - priv = (FAR struct pl2303_dev_s*)ep->priv; + priv = (FAR struct pl2303_dev_s *)ep->priv; /* Process the received data unless this is some unusual condition */ - flags = irqsave(); + flags = enter_critical_section(); switch (req->result) { case 0: /* Normal completion */ @@ -1227,7 +1228,7 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, case -ESHUTDOWN: /* Disconnection */ usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0); priv->nrdq--; - irqrestore(flags); + leave_critical_section(flags); return; default: /* Some other error occurred */ @@ -1243,7 +1244,7 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result); } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -1279,10 +1280,10 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, /* Return the write request to the free list */ - flags = irqsave(); - sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->reqlist); priv->nwrq++; - irqrestore(flags); + leave_critical_section(flags); /* Send the next packet unless this was some unusual termination * condition @@ -1320,7 +1321,7 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { - FAR struct pl2303_dev_s *priv = ((FAR struct pl2303_driver_s*)driver)->dev; + FAR struct pl2303_dev_s *priv = ((FAR struct pl2303_driver_s *)driver)->dev; FAR struct pl2303_req_s *reqcontainer; irqstate_t flags; uint16_t reqlen; @@ -1448,10 +1449,10 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, reqcontainer->req->priv = reqcontainer; reqcontainer->req->callback = usbclass_wrcomplete; - flags = irqsave(); - sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->reqlist); priv->nwrq++; /* Count of write requests available */ - irqrestore(flags); + leave_critical_section(flags); } /* Report if we are selfpowered */ @@ -1498,7 +1499,7 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct pl2303_driver_s*)driver)->dev; + priv = ((FAR struct pl2303_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -1573,7 +1574,7 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, * of them */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGASSERT(priv->nwrq == CONFIG_PL2303_NWRREQS); while (!sq_empty(&priv->reqlist)) { @@ -1585,7 +1586,7 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, } } DEBUGASSERT(priv->nwrq == 0); - irqrestore(flags); + leave_critical_section(flags); } /* Clear out all data in the circular buffer */ @@ -1626,7 +1627,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ usbtrace(TRACE_CLASSSETUP, ctrl->req); - priv = ((FAR struct pl2303_driver_s*)driver)->dev; + priv = ((FAR struct pl2303_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv || !priv->ctrlreq) @@ -1722,7 +1723,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { if (ctrl->type == USB_DIR_IN) { - *(uint8_t*)ctrlreq->buf = priv->config; + *(FAR uint8_t *)ctrlreq->buf = priv->config; ret = 1; } } @@ -1746,7 +1747,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, case USB_REQ_GETINTERFACE: { - if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) && priv->config == PL2303_CONFIGIDNONE) { if (index != PL2303_INTERFACEID) @@ -1755,7 +1756,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, } else { - *(uint8_t*) ctrlreq->buf = PL2303_ALTINTERFACEID; + *(FAR uint8_t *) ctrlreq->buf = PL2303_ALTINTERFACEID; ret = 1; } } @@ -1817,7 +1818,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { if ((ctrl->type & USB_DIR_IN) != 0) { - *(uint32_t*)ctrlreq->buf = 0xdeadbeef; + *(FAR uint32_t *)ctrlreq->buf = 0xdeadbeef; ret = 4; } else @@ -1886,7 +1887,7 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct pl2303_driver_s*)driver)->dev; + priv = ((FAR struct pl2303_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -1900,7 +1901,7 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, * connection. */ - flags = irqsave(); + flags = enter_critical_section(); #ifdef CONFIG_SERIAL_REMOVABLE uart_connected(&priv->serdev, false); #endif @@ -1914,7 +1915,7 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, priv->serdev.xmit.head = 0; priv->serdev.xmit.tail = 0; priv->rxhead = 0; - irqrestore(flags); + leave_critical_section(flags); /* Perform the soft connect function so that we will we can be * re-enumerated. @@ -1949,7 +1950,7 @@ static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct pl2303_driver_s*)driver)->dev; + priv = ((FAR struct pl2303_driver_s *)driver)->dev; /* And let the "upper half" driver now that we are suspended */ @@ -1983,7 +1984,7 @@ static void usbclass_resume(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct pl2303_driver_s*)driver)->dev; + priv = ((FAR struct pl2303_driver_s *)driver)->dev; /* Are we still configured? */ @@ -2016,7 +2017,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2026,7 +2027,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev) /* Extract reference to private data */ - priv = (FAR struct pl2303_dev_s*)dev->priv; + priv = (FAR struct pl2303_dev_s *)dev->priv; /* Check if we have been configured */ @@ -2057,7 +2058,7 @@ static void usbser_shutdown(FAR struct uart_dev_s *dev) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2083,8 +2084,8 @@ static int usbser_attach(FAR struct uart_dev_s *dev) * Name: usbser_detach * * Description: -* Does not apply to the USB serial class device - * + * Does not apply to the USB serial class device + * ****************************************************************************/ static void usbser_detach(FAR struct uart_dev_s *dev) @@ -2119,7 +2120,7 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) /* Sanity check */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2129,29 +2130,29 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) /* Extract reference to private data */ - priv = (FAR struct pl2303_dev_s*)dev->priv; + priv = (FAR struct pl2303_dev_s *)dev->priv; serdev = &priv->serdev; /* We need exclusive access to the RX buffer and private structure * in the following. */ - flags = irqsave(); + flags = enter_critical_section(); if (enable) { - /* RX "interrupts" are enabled. Is this a transition from disabled - * to enabled state? - */ + /* RX "interrupts" are enabled. Is this a transition from disabled + * to enabled state? + */ - if (!priv->rxenabled) - { - /* Yes. During the time that RX interrupts are disabled, the - * the serial driver will be extracting data from the circular - * buffer and modifying recv.tail. During this time, we - * should avoid modifying recv.head; When interrupts are restored, - * we can update the head pointer for all of the data that we - * put into cicular buffer while "interrupts" were disabled. - */ + if (!priv->rxenabled) + { + /* Yes. During the time that RX interrupts are disabled, the + * the serial driver will be extracting data from the circular + * buffer and modifying recv.tail. During this time, we + * should avoid modifying recv.head; When interrupts are restored, + * we can update the head pointer for all of the data that we + * put into cicular buffer while "interrupts" were disabled. + */ if (priv->rxhead != serdev->recv.head) { @@ -2185,7 +2186,7 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) priv->rxhead = serdev->recv.head; priv->rxenabled = false; } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -2210,7 +2211,7 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) /* Sanity checks */ -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!dev || !dev->priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2218,9 +2219,9 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) } #endif - /* Extract references to private data */ + /* Extract references to private data */ - priv = (FAR struct pl2303_dev_s*)dev->priv; + priv = (FAR struct pl2303_dev_s *)dev->priv; /* If the new state is enabled and if there is data in the XMIT buffer, * send the next packet now. @@ -2249,11 +2250,11 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) static bool usbser_txempty(FAR struct uart_dev_s *dev) { - FAR struct pl2303_dev_s *priv = (FAR struct pl2303_dev_s*)dev->priv; + FAR struct pl2303_dev_s *priv = (FAR struct pl2303_dev_s *)dev->priv; usbtrace(PL2303_CLASSAPI_TXEMPTY, 0); -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!priv) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); @@ -2290,7 +2291,7 @@ int usbdev_serialinitialize(int minor) /* Allocate the structures needed */ - alloc = (FAR struct pl2303_alloc_s*)kmm_malloc(sizeof(struct pl2303_alloc_s)); + alloc = (FAR struct pl2303_alloc_s *)kmm_malloc(sizeof(struct pl2303_alloc_s)); if (!alloc) { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0); @@ -2315,7 +2316,7 @@ int usbdev_serialinitialize(int minor) priv->linest[3] = (115200 >> 24) & 0xff; priv->linest[4] = 0; /* One stop bit */ priv->linest[5] = 0; /* No parity */ - priv->linest[6] = 8; /*8 data bits */ + priv->linest[6] = 8; /* 8 data bits */ /* Initialize the serial driver sub-structure */ diff --git a/drivers/usbdev/usbdev_strings.c b/drivers/usbdev/usbdev_strings.c index 94771369b979af026b3503bc0e994a5747593d2a..9dc9afdc407fe99f1e53af5606532082e47ad687 100644 --- a/drivers/usbdev/usbdev_strings.c +++ b/drivers/usbdev/usbdev_strings.c @@ -49,7 +49,7 @@ * Public Data ****************************************************************************/ -/* Class API call strings that may be enabled for more desciptive USB trace +/* Class API call strings that may be enabled for more descriptive USB trace * output. */ @@ -72,7 +72,7 @@ const struct trace_msg_t g_usb_trace_strings_clsapi[] = TRACE_STR_END }; -/* Class state strings that may be enabled for more desciptive USB trace +/* Class state strings that may be enabled for more descriptive USB trace * output. */ @@ -97,7 +97,7 @@ const struct trace_msg_t g_usb_trace_strings_clsstate[] = TRACE_STR_END }; -/* Class error strings that may be enabled for more desciptive USB trace +/* Class error strings that may be enabled for more descriptive USB trace * output. */ diff --git a/drivers/usbdev/usbdev_trace.c b/drivers/usbdev/usbdev_trace.c index 24f18fe5cddbe35a51f0cb7e37ab10015d80b39a..be19863b1ba80c98ac7d73ba16e65c006d3728a6 100644 --- a/drivers/usbdev/usbdev_trace.c +++ b/drivers/usbdev/usbdev_trace.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #undef usbtrace @@ -113,7 +113,7 @@ static int usbtrace_syslog(const char *fmt, ...) * Public Functions ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_enable * * Description: @@ -129,7 +129,7 @@ static int usbtrace_syslog(const char *fmt, ...) * Assumptions: * - May be called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_USBDEV_TRACE) || \ (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB)) @@ -140,15 +140,15 @@ usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset) /* The following read and write must be atomic */ - flags = irqsave(); + flags = enter_critical_section(); ret = g_maskedidset; g_maskedidset = idset; - irqrestore(flags); + leave_critical_section(flags); return ret; } #endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace * * Description: @@ -157,7 +157,7 @@ usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset) * Assumptions: * May be called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB)) void usbtrace(uint16_t event, uint16_t value) @@ -166,7 +166,7 @@ void usbtrace(uint16_t event, uint16_t value) /* Check if tracing is enabled for this ID */ - flags = irqsave(); + flags = enter_critical_section(); if ((g_maskedidset & TRACE_ID2BIT(event)) != 0) { #ifdef CONFIG_USBDEV_TRACE @@ -196,11 +196,11 @@ void usbtrace(uint16_t event, uint16_t value) #endif } - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_enumerate * * Description: @@ -209,7 +209,7 @@ void usbtrace(uint16_t event, uint16_t value) * Assumptions: * NEVER called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_USBDEV_TRACE int usbtrace_enumerate(trace_callback_t callback, void *arg) diff --git a/drivers/usbdev/usbdev_trprintf.c b/drivers/usbdev/usbdev_trprintf.c index 7616a15d7ced2ba36c591eea4c016681f5b8b262..58b4c57d61670f386972cf9f8023086b8ccc0675 100644 --- a/drivers/usbdev/usbdev_trprintf.c +++ b/drivers/usbdev/usbdev_trprintf.c @@ -65,13 +65,13 @@ * Private Functions ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: get_trstring * * Description: * Search the driver string data to find the string matching the provided ID. * - *******************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_USBDEV_TRACE_STRINGS static FAR const char *get_trstring(FAR const struct trace_msg_t *array, @@ -95,13 +95,13 @@ static FAR const char *get_trstring(FAR const struct trace_msg_t *array, * Public Functions ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_trprintf * * Description: * Print the trace record using the supplied printing function * - *******************************************************************************/ + ****************************************************************************/ void usbtrace_trprintf(trprintf_t trprintf, uint16_t event, uint16_t value) { diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index 941563494c62eeb36dbf8d3649fe52feec796a88..9e646c9509231a7fc797ef943329d9bbe89a1ba1 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/usbmsc.c * - * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Mass storage class device. Bulk-only with SCSI subclass. @@ -71,6 +71,7 @@ #include #include +#include #include #include #include @@ -255,7 +256,7 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req) static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { - FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s*)driver)->dev; + FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s *)driver)->dev; FAR struct usbmsc_req_s *reqcontainer; irqstate_t flags; int ret = OK; @@ -360,9 +361,9 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver, reqcontainer->req->priv = reqcontainer; reqcontainer->req->callback = usbmsc_wrcomplete; - flags = irqsave(); - sq_addlast((sq_entry_t*)reqcontainer, &priv->wrreqlist); - irqrestore(flags); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->wrreqlist); + leave_critical_section(flags); } /* Report if we are selfpowered (unless we are part of a composite device) */ @@ -413,7 +414,7 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver, /* Extract reference to private data */ - priv = ((FAR struct usbmsc_driver_s*)driver)->dev; + priv = ((FAR struct usbmsc_driver_s *)driver)->dev; #ifdef CONFIG_DEBUG if (!priv) @@ -477,7 +478,7 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver, * of them */ - flags = irqsave(); + flags = enter_critical_section(); while (!sq_empty(&priv->wrreqlist)) { reqcontainer = (struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist); @@ -495,7 +496,7 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver, priv->epbulkin = NULL; } - irqrestore(flags); + leave_critical_section(flags); } } @@ -699,7 +700,7 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver, case USB_REQ_GETINTERFACE: { - if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) && + if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) && priv->config == USBMSC_CONFIGIDNONE) { if (index != USBMSC_INTERFACEID) @@ -868,14 +869,14 @@ static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver, /* Reset the configuration */ - flags = irqsave(); + flags = enter_critical_section(); usbmsc_resetconfig(priv); /* Signal the worker thread */ priv->theventset |= USBMSC_EVENT_DISCONNECT; usbmsc_scsi_signal(priv); - irqrestore(flags); + leave_critical_section(flags); /* Perform the soft connect function so that we will we can be * re-enumerated (unless we are part of a composite device) @@ -934,7 +935,7 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config) int i; int ret = 0; -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (priv == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETCONFIGINVALIDARGS), 0); @@ -1083,14 +1084,14 @@ void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) /* Extract references to private data */ - priv = (FAR struct usbmsc_dev_s*)ep->priv; + priv = (FAR struct usbmsc_dev_s *)ep->priv; privreq = (FAR struct usbmsc_req_s *)req->priv; /* Return the write request to the free list */ - flags = irqsave(); - sq_addlast((sq_entry_t*)privreq, &priv->wrreqlist); - irqrestore(flags); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)privreq, &priv->wrreqlist); + leave_critical_section(flags); /* Process the received data unless this is some unusual condition */ @@ -1144,7 +1145,7 @@ void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) /* Extract references to private data */ - priv = (FAR struct usbmsc_dev_s*)ep->priv; + priv = (FAR struct usbmsc_dev_s *)ep->priv; privreq = (FAR struct usbmsc_req_s *)req->priv; /* Process the received data unless this is some unusual condition */ @@ -1157,9 +1158,9 @@ void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) /* Add the filled read request from the rdreqlist */ - flags = irqsave(); - sq_addlast((sq_entry_t*)privreq, &priv->rdreqlist); - irqrestore(flags); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)privreq, &priv->rdreqlist); + leave_critical_section(flags); /* Signal the worker thread that there is received data to be processed */ @@ -1326,7 +1327,7 @@ int usbmsc_configure(unsigned int nluns, void **handle) /* Allocate the structures needed */ - alloc = (FAR struct usbmsc_alloc_s*)kmm_malloc(sizeof(struct usbmsc_alloc_s)); + alloc = (FAR struct usbmsc_alloc_s *)kmm_malloc(sizeof(struct usbmsc_alloc_s)); if (!alloc) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCDEVSTRUCT), 0); @@ -1347,7 +1348,9 @@ int usbmsc_configure(unsigned int nluns, void **handle) /* Allocate the LUN table */ - priv->luntab = (struct usbmsc_lun_s*)kmm_malloc(priv->nluns*sizeof(struct usbmsc_lun_s)); + priv->luntab = (FAR struct usbmsc_lun_s *) + kmm_malloc(priv->nluns*sizeof(struct usbmsc_lun_s)); + if (!priv->luntab) { ret = -ENOMEM; @@ -1369,7 +1372,7 @@ int usbmsc_configure(unsigned int nluns, void **handle) /* Return the handle and success */ - *handle = (FAR void*)alloc; + *handle = (FAR void *)alloc; return OK; errout: @@ -1489,7 +1492,7 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, if (!priv->iobuffer) { - priv->iobuffer = (uint8_t*)kmm_malloc(geo.geo_sectorsize); + priv->iobuffer = (FAR uint8_t *)kmm_malloc(geo.geo_sectorsize); if (!priv->iobuffer) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize); @@ -1501,14 +1504,14 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, else if (priv->iosize < geo.geo_sectorsize) { void *tmp; - tmp = (uint8_t*)kmm_realloc(priv->iobuffer, geo.geo_sectorsize); + tmp = (FAR uint8_t *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize); if (!tmp) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize); return -ENOMEM; } - priv->iobuffer = (uint8_t*)tmp; + priv->iobuffer = (FAR uint8_t *)tmp; priv->iosize = geo.geo_sectorsize; } @@ -1679,10 +1682,10 @@ int usbmsc_exportluns(FAR void *handle) /* Signal to start the thread */ uvdbg("Signalling for the SCSI worker thread\n"); - flags = irqsave(); + flags = enter_critical_section(); priv->theventset |= USBMSC_EVENT_READY; usbmsc_scsi_signal(priv); - irqrestore(flags); + leave_critical_section(flags); errout_with_lock: usbmsc_scsi_unlock(priv); @@ -1701,7 +1704,6 @@ errout_with_lock: * * Returned Value: * 0 on success; a negated errno on failure - * ****************************************************************************/ @@ -1791,10 +1793,10 @@ void usbmsc_uninitialize(FAR void *handle) { /* Yes.. Ask the thread to stop */ - flags = irqsave(); + flags = enter_critical_section(); priv->theventset |= USBMSC_EVENT_TERMINATEREQUEST; usbmsc_scsi_signal(priv); - irqrestore(flags); + leave_critical_section(flags); } usbmsc_scsi_unlock(priv); diff --git a/drivers/usbdev/usbmsc_desc.c b/drivers/usbdev/usbmsc_desc.c index e958392f4ef39795b4771bf2a7ac9add25a0b17b..1a97da822430f4e677614fa72122eff7a7fbf7d3 100644 --- a/drivers/usbdev/usbmsc_desc.c +++ b/drivers/usbdev/usbmsc_desc.c @@ -260,7 +260,7 @@ int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc) return 4; } - case USBMSC_MANUFACTURERSTRID: + case USBMSC_MANUFACTURERSTRID: str = g_mscvendorstr; break; diff --git a/drivers/usbdev/usbmsc_scsi.c b/drivers/usbdev/usbmsc_scsi.c index fd8a5340aed0044842e3b2c8c7bc2cc3e3291b23..a8b0f4004feb29aaeaa5cb5fbf09b2b02afa7253 100644 --- a/drivers/usbdev/usbmsc_scsi.c +++ b/drivers/usbdev/usbmsc_scsi.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbdev/usbmsc_scsi.c * - * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2010, 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Mass storage class device. Bulk-only with SCSI subclass. @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -379,7 +380,7 @@ static void usbmsc_scsi_wait(FAR struct usbmsc_dev_s *priv) * enabled while we wait for the event. */ - flags = irqsave(); + flags = enter_critical_section(); priv->thwaiting = true; /* Relinquish our lock on the SCSI state data */ @@ -399,7 +400,7 @@ static void usbmsc_scsi_wait(FAR struct usbmsc_dev_s *priv) /* Re-acquire our lock on the SCSI state data */ usbmsc_scsi_lock(priv); - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -482,7 +483,7 @@ static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv, memset(response, 0, SCSIRESP_FIXEDSENSEDATA_SIZEOF); - response->code = SCSIRESP_SENSEDATA_RESPVALID|SCSIRESP_SENSEDATA_CURRENTFIXED; + response->code = SCSIRESP_SENSEDATA_RESPVALID | SCSIRESP_SENSEDATA_CURRENTFIXED; response->flags = (uint8_t)(sd >> 16); usbmsc_putbe32(response->info, sdinfo); response->len = SCSIRESP_FIXEDSENSEDATA_SIZEOF - 7; @@ -506,7 +507,7 @@ static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv, static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv) { - FAR struct scsicmd_read6_s *read6 = (FAR struct scsicmd_read6_s*)priv->cdb; + FAR struct scsicmd_read6_s *read6 = (FAR struct scsicmd_read6_s *)priv->cdb; FAR struct usbmsc_lun_s *lun = priv->lun; int ret; @@ -647,7 +648,7 @@ static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv, { if (!priv->lun) { - response->qualtype = SCSIRESP_INQUIRYPQ_NOTCAPABLE|SCSIRESP_INQUIRYPD_UNKNOWN; + response->qualtype = SCSIRESP_INQUIRYPQ_NOTCAPABLE | SCSIRESP_INQUIRYPD_UNKNOWN; } else if ((inquiry->flags != 0) || (inquiry->pagecode != 0)) { @@ -994,7 +995,7 @@ static int inline usbmsc_cmdreadcapacity10(FAR struct usbmsc_dev_s *priv, static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv) { - struct scsicmd_read10_s *read10 = (struct scsicmd_read10_s*)priv->cdb; + struct scsicmd_read10_s *read10 = (struct scsicmd_read10_s *)priv->cdb; FAR struct usbmsc_lun_s *lun = priv->lun; int ret; @@ -1009,7 +1010,7 @@ static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv) /* Verify that we can support this read command */ - if ((read10->flags & ~(SCSICMD_READ10FLAGS_DPO|SCSICMD_READ10FLAGS_FUA)) != 0) + if ((read10->flags & ~(SCSICMD_READ10FLAGS_DPO | SCSICMD_READ10FLAGS_FUA)) != 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ10FLAGS), 0); lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA; @@ -1071,7 +1072,7 @@ static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv) /* Verify that we can support this write command */ - if ((write10->flags & ~(SCSICMD_WRITE10FLAGS_DPO|SCSICMD_WRITE10FLAGS_FUA)) != 0) + if ((write10->flags & ~(SCSICMD_WRITE10FLAGS_DPO | SCSICMD_WRITE10FLAGS_FUA)) != 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10FLAGS), 0); lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA; @@ -1315,7 +1316,7 @@ static int inline usbmsc_cmdmodesense10(FAR struct usbmsc_dev_s *priv, static inline int usbmsc_cmdread12(FAR struct usbmsc_dev_s *priv) { - struct scsicmd_read12_s *read12 = (struct scsicmd_read12_s*)priv->cdb; + struct scsicmd_read12_s *read12 = (struct scsicmd_read12_s *)priv->cdb; FAR struct usbmsc_lun_s *lun = priv->lun; int ret; @@ -1330,7 +1331,7 @@ static inline int usbmsc_cmdread12(FAR struct usbmsc_dev_s *priv) /* Verify that we can support this read command */ - if ((read12->flags & ~(SCSICMD_READ12FLAGS_DPO|SCSICMD_READ12FLAGS_FUA)) != 0) + if ((read12->flags & ~(SCSICMD_READ12FLAGS_DPO | SCSICMD_READ12FLAGS_FUA)) != 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ12FLAGS), 0); lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA; @@ -1392,7 +1393,7 @@ static inline int usbmsc_cmdwrite12(FAR struct usbmsc_dev_s *priv) /* Verify that we can support this write command */ - if ((write12->flags & ~(SCSICMD_WRITE12FLAGS_DPO|SCSICMD_WRITE12FLAGS_FUA)) != 0) + if ((write12->flags & ~(SCSICMD_WRITE12FLAGS_DPO | SCSICMD_WRITE12FLAGS_FUA)) != 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12FLAGS), 0); lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA; @@ -1631,9 +1632,9 @@ static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv) /* Take a request from the rdreqlist */ - flags = irqsave(); + flags = enter_critical_section(); privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->rdreqlist); - irqrestore(flags); + leave_critical_section(flags); /* Has anything been received? If not, just return an error. * This will cause us to remain in the IDLE state. When a USB request is @@ -1652,7 +1653,7 @@ static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv) /* Handle the CBW */ - usbmsc_dumpdata("SCSCI CBW", (uint8_t*)cbw, USBMSC_CBW_SIZEOF - USBMSC_MAXCDBLEN); + usbmsc_dumpdata("SCSCI CBW", (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF - USBMSC_MAXCDBLEN); usbmsc_dumpdata(" CDB", cbw->cdb, MIN(cbw->cdblen, USBMSC_MAXCDBLEN)); /* Check for properly formatted CBW? */ @@ -2178,9 +2179,9 @@ static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv) * that is it not NULL */ - flags = irqsave(); + flags = enter_critical_section(); privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist); - irqrestore(flags); + leave_critical_section(flags); /* And submit the request to the bulk IN endpoint */ @@ -2281,7 +2282,7 @@ static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv) xfrd = req->xfrd; priv->nreqbytes = xfrd; - /* Now loop until all of the data in the read request has been tranferred + /* Now loop until all of the data in the read request has been transferred * to the block driver OR all of the request data has been transferred. */ @@ -2413,9 +2414,9 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv) * that is it not NULL) */ - flags = irqsave(); + flags = enter_critical_section(); privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist); - irqrestore(flags); + leave_critical_section(flags); /* Send the write request */ @@ -2463,7 +2464,7 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv) { /* Did the host stop sending unexpectedly early? */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->shortpacket) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHSHORTPKT), (uint16_t)priv->residue); @@ -2478,7 +2479,7 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv) } priv->theventset |= USBMSC_EVENT_ABORTBULKOUT; - irqrestore(flags); + leave_critical_section(flags); } break; @@ -2524,9 +2525,9 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv) /* Take a request from the wrreqlist */ - flags = irqsave(); + flags = enter_critical_section(); privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist); - irqrestore(flags); + leave_critical_section(flags); /* If there no request structures available, then just return an error. * This will cause us to remain in the CMDSTATUS status. When a request is @@ -2541,7 +2542,7 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv) } req = privreq->req; - csw = (struct usbmsc_csw_s*)req->buf; + csw = (FAR struct usbmsc_csw_s *)req->buf; /* Extract the sense data from the LUN structure */ @@ -2578,7 +2579,7 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv) usbmsc_putle32(csw->residue, priv->residue); csw->status = status; - usbmsc_dumpdata("SCSCI CSW", (uint8_t*)csw, USBMSC_CSW_SIZEOF); + usbmsc_dumpdata("SCSCI CSW", (FAR uint8_t *)csw, USBMSC_CSW_SIZEOF); req->len = USBMSC_CSW_SIZEOF; req->callback = usbmsc_wrcomplete; @@ -2589,9 +2590,9 @@ static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv) if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDSTATUSSUBMIT), (uint16_t)-ret); - flags = irqsave(); - (void)sq_addlast((sq_entry_t*)privreq, &priv->wrreqlist); - irqrestore(flags); + flags = enter_critical_section(); + (void)sq_addlast((FAR sq_entry_t *)privreq, &priv->wrreqlist); + leave_critical_section(flags); } /* Return to the IDLE state */ @@ -2663,7 +2664,7 @@ int usbmsc_scsi_main(int argc, char *argv[]) */ usbmsc_scsi_lock(priv); - flags = irqsave(); + flags = enter_critical_section(); if (priv->theventset == USBMSC_EVENT_NOEVENTS) { usbmsc_scsi_wait(priv); @@ -2701,8 +2702,8 @@ int usbmsc_scsi_main(int argc, char *argv[]) * drive the state machine. */ - if ((eventset & (USBMSC_EVENT_DISCONNECT|USBMSC_EVENT_RESET|USBMSC_EVENT_CFGCHANGE| - USBMSC_EVENT_IFCHANGE|USBMSC_EVENT_ABORTBULKOUT)) != 0) + if ((eventset & (USBMSC_EVENT_DISCONNECT | USBMSC_EVENT_RESET | USBMSC_EVENT_CFGCHANGE | + USBMSC_EVENT_IFCHANGE | USBMSC_EVENT_ABORTBULKOUT)) != 0) { /* These events require that the current configuration be reset */ @@ -2720,7 +2721,7 @@ int usbmsc_scsi_main(int argc, char *argv[]) /* These events required that we send a deferred EP0 setup response */ - if ((eventset & (USBMSC_EVENT_RESET|USBMSC_EVENT_CFGCHANGE|USBMSC_EVENT_IFCHANGE)) != 0) + if ((eventset & (USBMSC_EVENT_RESET | USBMSC_EVENT_CFGCHANGE | USBMSC_EVENT_IFCHANGE)) != 0) { usbmsc_deferredresponse(priv, false); } @@ -2730,7 +2731,7 @@ int usbmsc_scsi_main(int argc, char *argv[]) priv->thstate = USBMSC_STATE_IDLE; } - irqrestore(flags); + leave_critical_section(flags); /* Loop processing each SCSI command state. Each state handling * function will do the following: @@ -2810,14 +2811,14 @@ void usbmsc_scsi_signal(FAR struct usbmsc_dev_s *priv) * of the semaphore count are atomic. */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->thwaiting) { priv->thwaiting = false; sem_post(&priv->thwaitsem); } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** diff --git a/drivers/usbhost/hid_parser.c b/drivers/usbhost/hid_parser.c index d20a080f64d3fa55c5497e4335f4990b39f0e4ca..59198faa93749bddb80b54f6360b17630794e7b8 100644 --- a/drivers/usbhost/hid_parser.c +++ b/drivers/usbhost/hid_parser.c @@ -139,9 +139,7 @@ int hid_parsereport(FAR const uint8_t *report, int rptlen, return -E2BIG; } - memcpy((currstate + 1), - currstate, sizeof(struct hid_rptitem_s)); - + memcpy((currstate + 1), currstate, sizeof(struct hid_state_s)); currstate++; break; diff --git a/drivers/usbhost/usbhost_cdcacm.c b/drivers/usbhost/usbhost_cdcacm.c index ee639603942028948872de3d2ab65b9b8cb63303..0c35d61bf49c71433186a1f7017573979ad303a0 100644 --- a/drivers/usbhost/usbhost_cdcacm.c +++ b/drivers/usbhost/usbhost_cdcacm.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_cdcacm.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -248,7 +249,7 @@ struct usbhost_cdcacm_s bool rxena; /* True: RX "interrupts" enabled */ #ifdef CONFIG_SERIAL_IFLOWCONTROL bool iflow; /* True: Input flow control (RTS) enabled */ - bool rts; /* True: Input flow control is effect */ + bool rts; /* True: Input flow control is in effect */ #endif #ifdef CONFIG_SERIAL_OFLOWCONTROL bool oflow; /* True: Output flow control (CTS) enabled */ @@ -503,15 +504,15 @@ static FAR struct usbhost_cdcacm_s *usbhost_allocclass(void) * our pre-allocated class instances from the free list. */ - flags = irqsave(); + flags = enter_critical_section(); entry = g_freelist; if (entry) { g_freelist = entry->flink; } - irqrestore(flags); - uvdbg("Allocated: %p\n", entry);; + leave_critical_section(flags); + uvdbg("Allocated: %p\n", entry); return (FAR struct usbhost_cdcacm_s *)entry; } #else @@ -525,7 +526,7 @@ static FAR struct usbhost_cdcacm_s *usbhost_allocclass(void) DEBUGASSERT(!up_interrupt_context()); priv = (FAR struct usbhost_cdcacm_s *)kmm_malloc(sizeof(struct usbhost_cdcacm_s)); - uvdbg("Allocated: %p\n", priv);; + uvdbg("Allocated: %p\n", priv); return priv; } #endif @@ -555,10 +556,10 @@ static void usbhost_freeclass(FAR struct usbhost_cdcacm_s *usbclass) /* Just put the pre-allocated class structure back on the freelist */ - flags = irqsave(); + flags = enter_critical_section(); entry->flink = g_freelist; g_freelist = entry; - irqrestore(flags); + leave_critical_section(flags); } #else static void usbhost_freeclass(FAR struct usbhost_cdcacm_s *usbclass) @@ -569,7 +570,7 @@ static void usbhost_freeclass(FAR struct usbhost_cdcacm_s *usbclass) * from an interrupt handler. */ - uvdbg("Freeing: %p\n", usbclass);; + uvdbg("Freeing: %p\n", usbclass); sched_kfree(usbclass); } #endif @@ -587,7 +588,7 @@ static int usbhost_devno_alloc(FAR struct usbhost_cdcacm_s *priv) irqstate_t flags; int devno; - flags = irqsave(); + flags = enter_critical_section(); for (devno = 0; devno < 32; devno++) { uint32_t bitno = 1 << devno; @@ -595,12 +596,12 @@ static int usbhost_devno_alloc(FAR struct usbhost_cdcacm_s *priv) { g_devinuse |= bitno; priv->minor = devno; - irqrestore(flags); + leave_critical_section(flags); return OK; } } - irqrestore(flags); + leave_critical_section(flags); return -EMFILE; } @@ -618,9 +619,9 @@ static void usbhost_devno_free(FAR struct usbhost_cdcacm_s *priv) if (devno >= 0 && devno < 32) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); g_devinuse &= ~(1 << devno); - irqrestore(flags); + leave_critical_section(flags); } } @@ -850,8 +851,8 @@ static void usbhost_notification_callback(FAR void *arg, ssize_t nbytes) delay = USBHOST_CDCACM_NTDELAY; } - /* Make sure that the work structure available. There is a remote - * chance that this may collide with a device disconnection event. + /* Make sure that the work structure available. There is a remote + * chance that this may collide with a device disconnection event. */ if (work_available(&priv->ntwork)) @@ -1129,12 +1130,12 @@ static void usbhost_rxdata_work(FAR void *arg) rxbuf->head = nexthead; priv->rxndx = rxndx; - + /* Update the head point for for the next pass through the loop * handling. If nexthead incremented to rxbuf->tail, then the * RX buffer will and we will exit the loop at the top. */ - + if (++nexthead >= rxbuf->size) { nexthead = 0; @@ -1333,7 +1334,7 @@ static int usbhost_cfgdesc(FAR struct usbhost_cdcacm_s *priv, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -1723,11 +1724,11 @@ static int usbhost_alloc_buffers(FAR struct usbhost_cdcacm_s *priv) /* Allocate buffer for sending line coding data. */ ret = DRVR_IOALLOC(hport->drvr, &priv->linecode, - sizeof( struct cdc_linecoding_s)); + sizeof(struct cdc_linecoding_s)); if (ret < 0) { udbg("ERROR: DRVR_IOALLOC of line coding failed: %d (%d bytes)\n", - ret, sizeof( struct cdc_linecoding_s)); + ret, sizeof(struct cdc_linecoding_s)); goto errout; } @@ -1759,7 +1760,7 @@ static int usbhost_alloc_buffers(FAR struct usbhost_cdcacm_s *priv) ret, priv->pktsize); goto errout; } - + /* Allocate a TX buffer for Bulk IN transfers */ ret = DRVR_IOALLOC(hport->drvr, &priv->outbuf, priv->pktsize); @@ -2113,7 +2114,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) * is no longer available. */ - flags = irqsave(); + flags = enter_critical_section(); priv->disconnected = true; /* Let the upper half driver know that serial device is no longer @@ -2181,7 +2182,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) } } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -2213,11 +2214,11 @@ static int usbhost_setup(FAR struct uart_dev_s *uartdev) usbhost_takesem(&priv->exclsem); /* Check if the CDC/ACM device is still connected. We need to disable - * interrupts momentarily to assure that there are no asynchronous + * interrupts momentarily to assure that there are no asynchronous * isconnect events. */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->disconnected) { /* No... the block driver is no longer bound to the class. That means that @@ -2235,7 +2236,7 @@ static int usbhost_setup(FAR struct uart_dev_s *uartdev) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); usbhost_givesem(&priv->exclsem); return ret; } @@ -2275,7 +2276,7 @@ static void usbhost_shutdown(FAR struct uart_dev_s *uartdev) * no asynchronous disconnect events. */ - flags = irqsave(); + flags = enter_critical_section(); /* Check if the USB CDC/ACM device is still connected. If the * CDC/ACM device is not connected and the reference count just @@ -2291,7 +2292,7 @@ static void usbhost_shutdown(FAR struct uart_dev_s *uartdev) usbhost_destroy(priv); } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -2386,7 +2387,7 @@ static int usbhost_ioctl(FAR struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_SERIAL_TERMIOS case TCGETS: { - FAR struct termios *termiosp = (FAR struct termios*)arg; + FAR struct termios *termiosp = (FAR struct termios *)arg; if (!termiosp) { @@ -2432,7 +2433,7 @@ static int usbhost_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case TCSETS: { - FAR struct termios *termiosp = (FAR struct termios*)arg; + FAR struct termios *termiosp = (FAR struct termios *)arg; #ifdef CONFIG_SERIAL_IFLOWCONTROL bool iflow; #endif @@ -2561,7 +2562,7 @@ static void usbhost_rxint(FAR struct uart_dev_s *uartdev, bool enable) */ #ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts)) + if (priv->rts) #endif { ret = work_queue(LPWORK, &priv->rxwork, @@ -2592,7 +2593,7 @@ static void usbhost_rxint(FAR struct uart_dev_s *uartdev, bool enable) static bool usbhost_rxavailable(FAR struct uart_dev_s *uartdev) { - + FAR struct usbhost_cdcacm_s *priv; DEBUGASSERT(uartdev && uartdev->priv); @@ -2653,7 +2654,7 @@ static bool usbhost_rxflowcontrol(FAR struct uart_dev_s *uartdev, * RTS. */ - priv ->rts = false; + priv->rts = false; /* Cancel any pending RX data reception work */ @@ -2667,7 +2668,7 @@ static bool usbhost_rxflowcontrol(FAR struct uart_dev_s *uartdev, * RTS. */ - priv ->rts = true; + priv->rts = true; /* Restart RX data reception work flow unless RX reception is * disabled. diff --git a/drivers/usbhost/usbhost_devaddr.c b/drivers/usbhost/usbhost_devaddr.c index 578e2ea684a2372a66dc9fc6f77e71699edce6bd..e26513c540531baf4afe608a87fe8a8d0d7cfd8c 100644 --- a/drivers/usbhost/usbhost_devaddr.c +++ b/drivers/usbhost/usbhost_devaddr.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/**************************************************************************** * drivers/usbhost/usbhost_devaddr.c * Manage USB device addresses * @@ -32,11 +32,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Included Files - *******************************************************************************/ + ****************************************************************************/ #include @@ -48,13 +48,13 @@ #include #include -/******************************************************************************* +/**************************************************************************** * Pre-processor Definitions - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Private Functions - *******************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: usbhost_takesem and usbhost_givesem @@ -63,7 +63,7 @@ * This is just a wrapper to handle the annoying behavior of semaphore * waits that return due to the receipt of a signal. * - *******************************************************************************/ + ****************************************************************************/ static void usbhost_takesem(FAR struct usbhost_devaddr_s *devgen) { @@ -81,7 +81,7 @@ static void usbhost_takesem(FAR struct usbhost_devaddr_s *devgen) #define usbhost_givesem(devgen) sem_post(&devgen->exclsem) -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_allocate * * Description: @@ -90,7 +90,7 @@ static void usbhost_takesem(FAR struct usbhost_devaddr_s *devgen) * Assumptions: * Caller hold the exclsem * - *******************************************************************************/ + ****************************************************************************/ static int usbhost_devaddr_allocate(FAR struct usbhost_devaddr_s *devgen) { @@ -101,7 +101,7 @@ static int usbhost_devaddr_allocate(FAR struct usbhost_devaddr_s *devgen) /* Loop until we find a valid device address */ - for (;;) + for (; ; ) { /* Try the next device address */ @@ -140,7 +140,7 @@ static int usbhost_devaddr_allocate(FAR struct usbhost_devaddr_s *devgen) } } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_free * * Description: @@ -149,7 +149,7 @@ static int usbhost_devaddr_allocate(FAR struct usbhost_devaddr_s *devgen) * Assumptions: * Caller hold the exclsem * - *******************************************************************************/ + ****************************************************************************/ static void usbhost_devaddr_free(FAR struct usbhost_devaddr_s *devgen, uint8_t devaddr) @@ -173,13 +173,13 @@ static void usbhost_devaddr_free(FAR struct usbhost_devaddr_s *devgen, } } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_roothubport * * Description: * Find and return a reference the root hub port. * - *******************************************************************************/ + ****************************************************************************/ static inline FAR struct usbhost_roothubport_s * usbhost_roothubport(FAR struct usbhost_hubport_s *hport) @@ -203,14 +203,14 @@ usbhost_roothubport(FAR struct usbhost_hubport_s *hport) return (FAR struct usbhost_roothubport_s *)hport; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_gen * * Description: * Find root hub port and return a reference to the device function address * data set. * - *******************************************************************************/ + ****************************************************************************/ static FAR struct usbhost_devaddr_s * usbhost_devaddr_gen(FAR struct usbhost_hubport_s *hport) @@ -226,11 +226,11 @@ usbhost_devaddr_gen(FAR struct usbhost_hubport_s *hport) return NULL; } -/******************************************************************************* +/**************************************************************************** * Public Functions - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_initialize * * Description: @@ -244,7 +244,7 @@ usbhost_devaddr_gen(FAR struct usbhost_hubport_s *hport) * Returned Value: * None * - *******************************************************************************/ + ****************************************************************************/ void usbhost_devaddr_initialize(FAR struct usbhost_roothubport_s *rhport) { @@ -258,7 +258,7 @@ void usbhost_devaddr_initialize(FAR struct usbhost_roothubport_s *rhport) devgen->next = 1; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_create * * Description: @@ -272,7 +272,7 @@ void usbhost_devaddr_initialize(FAR struct usbhost_roothubport_s *rhport) * On success, a new device function address in the the range 0x01 to 0x7f * is returned. On failure, a negated errno value is returned. * - *******************************************************************************/ + ****************************************************************************/ int usbhost_devaddr_create(FAR struct usbhost_hubport_s *hport) { @@ -302,7 +302,7 @@ int usbhost_devaddr_create(FAR struct usbhost_hubport_s *hport) return devaddr; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_destroy * * Description: @@ -316,7 +316,7 @@ int usbhost_devaddr_create(FAR struct usbhost_hubport_s *hport) * Returned Value: * None * - *******************************************************************************/ + ****************************************************************************/ void usbhost_devaddr_destroy(FAR struct usbhost_hubport_s *hport, uint8_t devaddr) { diff --git a/drivers/usbhost/usbhost_enumerate.c b/drivers/usbhost/usbhost_enumerate.c index 8f60e5c0859835f8b96307a73ee8ef8f4d3e5c50..647d0ab7a99cb8c1dca2771c7115297e0ff0ac7a 100644 --- a/drivers/usbhost/usbhost_enumerate.c +++ b/drivers/usbhost/usbhost_enumerate.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/**************************************************************************** * drivers/usbhost/usbhost_enumerate.c * * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Included Files - *******************************************************************************/ + ****************************************************************************/ #include @@ -53,17 +53,17 @@ #include #include -/******************************************************************************* +/**************************************************************************** * Pre-processor Definitions - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Private Types - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Private Function Prototypes - *******************************************************************************/ + ****************************************************************************/ static inline uint16_t usbhost_getle16(const uint8_t *val); static void usbhost_putle16(uint8_t *dest, uint16_t val); @@ -77,17 +77,17 @@ static inline int usbhost_classbind(FAR struct usbhost_hubport_s *hport, FAR struct usbhost_id_s *id, FAR struct usbhost_class_s **devclass); -/******************************************************************************* +/**************************************************************************** * Private Data - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Public Data - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Private Functions - *******************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: usbhost_getle16 @@ -95,7 +95,7 @@ static inline int usbhost_classbind(FAR struct usbhost_hubport_s *hport, * Description: * Get a (possibly unaligned) 16-bit little endian value. * - *******************************************************************************/ + ****************************************************************************/ static inline uint16_t usbhost_getle16(const uint8_t *val) { @@ -108,7 +108,7 @@ static inline uint16_t usbhost_getle16(const uint8_t *val) * Description: * Put a (possibly unaligned) 16-bit little endian value. * - *******************************************************************************/ + ****************************************************************************/ static void usbhost_putle16(uint8_t *dest, uint16_t val) { @@ -116,14 +116,14 @@ static void usbhost_putle16(uint8_t *dest, uint16_t val) dest[1] = val >> 8; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devdesc * * Description: * A configuration descriptor has been obtained from the device. Find the * ID information for the class that supports this device. * - *******************************************************************************/ + ****************************************************************************/ static inline int usbhost_devdesc(FAR const struct usb_devdesc_s *devdesc, FAR struct usbhost_id_s *id) @@ -148,14 +148,14 @@ static inline int usbhost_devdesc(FAR const struct usb_devdesc_s *devdesc, return OK; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_configdesc * * Description: * A configuration descriptor has been obtained from the device. Find the * ID information for the class that supports this device. * - *******************************************************************************/ + ****************************************************************************/ static inline int usbhost_configdesc(const uint8_t *configdesc, int cfglen, struct usbhost_id_s *id) @@ -214,14 +214,14 @@ static inline int usbhost_configdesc(const uint8_t *configdesc, int cfglen, return -ENOENT; } -/******************************************************************************* +/**************************************************************************** * Name: usbhost_classbind * * Description: * A configuration descriptor has been obtained from the device. Try to * bind this configuration descriptor with a supported class. * - *******************************************************************************/ + ****************************************************************************/ static inline int usbhost_classbind(FAR struct usbhost_hubport_s *hport, const uint8_t *configdesc, int desclen, @@ -270,11 +270,11 @@ static inline int usbhost_classbind(FAR struct usbhost_hubport_s *hport, return ret; } -/******************************************************************************* +/**************************************************************************** * Public Functions - *******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: usbhost_enumerate * * Description: @@ -302,7 +302,7 @@ static inline int usbhost_classbind(FAR struct usbhost_hubport_s *hport, * - Called from a single thread so no mutual exclusion is required. * - Never called from an interrupt handler. * - *******************************************************************************/ + ****************************************************************************/ int usbhost_enumerate(FAR struct usbhost_hubport_s *hport, FAR struct usbhost_class_s **devclass) diff --git a/drivers/usbhost/usbhost_findclass.c b/drivers/usbhost/usbhost_findclass.c index d65b49c502fc95f3ad9d3476adf9ec5a71707e28..b544b60f484c1df2f67f02b40817b4e5aed681e5 100644 --- a/drivers/usbhost/usbhost_findclass.c +++ b/drivers/usbhost/usbhost_findclass.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_findclass.c * - * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,28 +44,12 @@ #include #include +#include #include #include -#include #include "usbhost_registry.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -167,7 +151,7 @@ const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id * protected by disabling interrupts. */ - flags = irqsave(); + flags = enter_critical_section(); /* Examine each register class in the linked list */ @@ -186,7 +170,7 @@ const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id { /* Yes.. restore interrupts and return the class info */ - irqrestore(flags); + leave_critical_section(flags); return usbclass; } } @@ -194,7 +178,7 @@ const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id /* Not found... restore interrupts and return NULL */ - irqrestore(flags); + leave_critical_section(flags); return NULL; } diff --git a/drivers/usbhost/usbhost_hidkbd.c b/drivers/usbhost/usbhost_hidkbd.c index f390289e04aa1508ab98a63fc9f5dfccd461414c..b36434dd31916e14ed54d5c61806be1bc8e63b77 100644 --- a/drivers/usbhost/usbhost_hidkbd.c +++ b/drivers/usbhost/usbhost_hidkbd.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_hidkbd.c * - * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -663,7 +664,7 @@ static inline FAR struct usbhost_state_s *usbhost_allocclass(void) DEBUGASSERT(!up_interrupt_context()); priv = (FAR struct usbhost_state_s *)kmm_malloc(sizeof(struct usbhost_state_s)); - uvdbg("Allocated: %p\n", priv);; + uvdbg("Allocated: %p\n", priv); return priv; } @@ -687,7 +688,7 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) /* Free the class instance. */ - uvdbg("Freeing: %p\n", usbclass);; + uvdbg("Freeing: %p\n", usbclass); sched_kfree(usbclass); } @@ -704,7 +705,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) irqstate_t flags; int devno; - flags = irqsave(); + flags = enter_critical_section(); for (devno = 0; devno < 26; devno++) { uint32_t bitno = 1 << devno; @@ -712,12 +713,12 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) { g_devinuse |= bitno; priv->devchar = 'a' + devno; - irqrestore(flags); + leave_critical_section(flags); return OK; } } - irqrestore(flags); + leave_critical_section(flags); return -EMFILE; } @@ -727,9 +728,9 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv) if (devno >= 0 && devno < 26) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); g_devinuse &= ~(1 << devno); - irqrestore(flags); + leave_critical_section(flags); } } @@ -921,7 +922,7 @@ static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier) /* Is either shift key pressed? */ - if ((modifier & (USBHID_MODIFER_LSHIFT|USBHID_MODIFER_RSHIFT)) != 0) + if ((modifier & (USBHID_MODIFER_LSHIFT | USBHID_MODIFER_RSHIFT)) != 0) { return ucmap[scancode]; } @@ -1062,7 +1063,7 @@ static int usbhost_kbdpoll(int argc, char *argv[]) */ ctrlreq = (struct usb_ctrlreq_s *)priv->tbuffer; - ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE; + ctrlreq->type = USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; ctrlreq->req = USBHID_REQUEST_GETREPORT; usbhost_putle16(ctrlreq->value, (USBHID_REPORTTYPE_INPUT << 8)); @@ -1155,7 +1156,7 @@ static int usbhost_kbdpoll(int argc, char *argv[]) * a valid, NUL character. */ - if ((rpt->modifier & (USBHID_MODIFER_LCTRL|USBHID_MODIFER_RCTRL)) != 0) + if ((rpt->modifier & (USBHID_MODIFER_LCTRL | USBHID_MODIFER_RCTRL)) != 0) { keycode &= 0x1f; } @@ -1268,7 +1269,7 @@ static int usbhost_kbdpoll(int argc, char *argv[]) udbg("Keyboard removed, polling halted\n"); - flags = irqsave(); + flags = enter_critical_section(); priv->polling = false; /* Decrement the reference count held by this thread. */ @@ -1303,7 +1304,7 @@ static int usbhost_kbdpoll(int argc, char *argv[]) usbhost_givesem(&priv->exclsem); } - irqrestore(flags); + leave_critical_section(flags); return 0; } @@ -1363,7 +1364,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -1712,7 +1713,7 @@ static void usbhost_putle16(uint8_t *dest, uint16_t val) static inline uint32_t usbhost_getle32(const uint8_t *val) { - /* Little endian means LS halfword first in byte stream */ + /* Little endian means LS halfword first in byte stream */ return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val); } @@ -2068,7 +2069,7 @@ static int usbhost_open(FAR struct file *filep) * events. */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->disconnected) { /* No... the driver is no longer bound to the class. That means that @@ -2086,7 +2087,7 @@ static int usbhost_open(FAR struct file *filep) priv->open = true; ret = OK; } - irqrestore(flags); + leave_critical_section(flags); usbhost_givesem(&priv->exclsem); return ret; @@ -2120,7 +2121,7 @@ static int usbhost_close(FAR struct file *filep) * asynchronous poll or disconnect events. */ - flags = irqsave(); + flags = enter_critical_section(); priv->crefs--; /* Check if the USB mouse device is still connected. If the device is @@ -2164,7 +2165,7 @@ static int usbhost_close(FAR struct file *filep) /* Skip giving the semaphore... it is no longer valid */ - irqrestore(flags); + leave_critical_section(flags); return OK; } else /* if (priv->crefs == 1) */ @@ -2180,7 +2181,7 @@ static int usbhost_close(FAR struct file *filep) } usbhost_givesem(&priv->exclsem); - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/drivers/usbhost/usbhost_hidmouse.c b/drivers/usbhost/usbhost_hidmouse.c index 62c659a5b154110be4fd895f038771bbc41ee0af..c61541d9c2a479d838cd8a6a16a8693a36b78932 100644 --- a/drivers/usbhost/usbhost_hidmouse.c +++ b/drivers/usbhost/usbhost_hidmouse.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_hidmouse.c * - * Copyright (C) 2014, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -523,7 +524,7 @@ static inline FAR struct usbhost_state_s *usbhost_allocclass(void) DEBUGASSERT(!up_interrupt_context()); priv = (FAR struct usbhost_state_s *)kmm_malloc(sizeof(struct usbhost_state_s)); - uvdbg("Allocated: %p\n", priv);; + uvdbg("Allocated: %p\n", priv); return priv; } @@ -547,7 +548,7 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) /* Free the class instance. */ - uvdbg("Freeing: %p\n", usbclass);; + uvdbg("Freeing: %p\n", usbclass); sched_kfree(usbclass); } @@ -564,7 +565,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) irqstate_t flags; int devno; - flags = irqsave(); + flags = enter_critical_section(); for (devno = 0; devno < 26; devno++) { uint32_t bitno = 1 << devno; @@ -572,12 +573,12 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) { g_devinuse |= bitno; priv->devno = devno; - irqrestore(flags); + leave_critical_section(flags); return OK; } } - irqrestore(flags); + leave_critical_section(flags); return -EMFILE; } @@ -587,9 +588,9 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv) if (devno >= 0 && devno < 26) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); g_devinuse &= ~(1 << devno); - irqrestore(flags); + leave_critical_section(flags); } } @@ -1234,7 +1235,7 @@ static int usbhost_mouse_poll(int argc, char *argv[]) udbg("Mouse removed, polling halted\n"); - flags = irqsave(); + flags = enter_critical_section(); priv->polling = false; /* Decrement the reference count held by this thread. */ @@ -1269,7 +1270,7 @@ static int usbhost_mouse_poll(int argc, char *argv[]) usbhost_givesem(&priv->exclsem); } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -1292,7 +1293,7 @@ static int usbhost_sample(FAR struct usbhost_state_s *priv, * from changing until it has been reported. */ - flags = irqsave(); + flags = enter_critical_section(); /* Is there new mouse data available? */ @@ -1300,7 +1301,7 @@ static int usbhost_sample(FAR struct usbhost_state_s *priv, { /* Return a copy of the sampled data. */ - memcpy(sample, &priv->sample, sizeof(struct mouse_sample_s )); + memcpy(sample, &priv->sample, sizeof(struct mouse_sample_s)); #ifdef CONFIG_HIDMOUSE_TSCIF /* Now manage state transitions */ @@ -1329,7 +1330,7 @@ static int usbhost_sample(FAR struct usbhost_state_s *priv, ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } @@ -1360,7 +1361,7 @@ static int usbhost_waitsample(FAR struct usbhost_state_s *priv, */ sched_lock(); - flags = irqsave(); + flags = enter_critical_section(); /* Now release the semaphore that manages mutually exclusive access to * the device structure. This may cause other tasks to become ready to @@ -1405,7 +1406,7 @@ static int usbhost_waitsample(FAR struct usbhost_state_s *priv, ivdbg("Sampled\n"); - /* Re-acquire the semaphore that manages mutually exclusive access to + /* Re-acquire the semaphore that manages mutually exclusive access to * the device structure. We may have to wait here. But we have our sample. * Interrupts and pre-emption will be re-enabled while we wait. */ @@ -1418,7 +1419,7 @@ errout: * have pre-emption disabled. */ - irqrestore(flags); + leave_critical_section(flags); /* Restore pre-emption. We might get suspended here but that is okay * because we already have our sample. Note: this means that if there @@ -1484,7 +1485,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -1783,7 +1784,7 @@ static void usbhost_putle16(uint8_t *dest, uint16_t val) static inline uint32_t usbhost_getle32(const uint8_t *val) { - /* Little endian means LS halfword first in byte stream */ + /* Little endian means LS halfword first in byte stream */ return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val); } @@ -2138,7 +2139,7 @@ static int usbhost_open(FAR struct file *filep) * events. */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->disconnected) { /* No... the driver is no longer bound to the class. That means that @@ -2178,7 +2179,7 @@ static int usbhost_open(FAR struct file *filep) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); usbhost_givesem(&priv->exclsem); return ret; @@ -2212,7 +2213,7 @@ static int usbhost_close(FAR struct file *filep) * asynchronous poll or disconnect events. */ - flags = irqsave(); + flags = enter_critical_section(); priv->crefs--; /* Check if the USB mouse device is still connected. If the device is @@ -2254,7 +2255,7 @@ static int usbhost_close(FAR struct file *filep) /* Skip giving the semaphore... it is no longer valid */ - irqrestore(flags); + leave_critical_section(flags); return OK; } else /* if (priv->crefs == 1) */ @@ -2270,7 +2271,7 @@ static int usbhost_close(FAR struct file *filep) } usbhost_givesem(&priv->exclsem); - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/drivers/usbhost/usbhost_hub.c b/drivers/usbhost/usbhost_hub.c index 7c98230c2e03138ca6485730e152c5878e98c896..34b37f9b2997fc401ce2dc96cc851b29d8537fbc 100644 --- a/drivers/usbhost/usbhost_hub.c +++ b/drivers/usbhost/usbhost_hub.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_hub.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Kaushal Parikh * Gregory Nutt * @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -356,7 +357,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -980,7 +981,7 @@ static void usbhost_hub_event(FAR void *arg) * removed. */ - flags = irqsave(); + flags = enter_critical_section(); if (!priv->disconnected) { /* Wait for the next hub event */ @@ -993,7 +994,7 @@ static void usbhost_hub_event(FAR void *arg) } } - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -1038,7 +1039,7 @@ static void usbhost_disconnect_event(FAR void *arg) * longer available. */ - flags = irqsave(); + flags = enter_critical_section(); /* Cancel any pending transfers on the interrupt IN pipe */ @@ -1098,7 +1099,7 @@ static void usbhost_disconnect_event(FAR void *arg) kmm_free(hubclass); hport->devclass = NULL; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -1463,7 +1464,7 @@ static int usbhost_disconnected(struct usbhost_class_s *hubclass) * any subsequent completions of asynchronous transfers. */ - flags = irqsave(); + flags = enter_critical_section(); priv->disconnected = true; /* Cancel any pending work. There may be pending HUB work associated with @@ -1476,7 +1477,7 @@ static int usbhost_disconnected(struct usbhost_class_s *hubclass) ret = work_queue(LPWORK, &priv->work, (worker_t)usbhost_disconnect_event, hubclass, 0); - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/drivers/usbhost/usbhost_registerclass.c b/drivers/usbhost/usbhost_registerclass.c index 09d7c7c10d8ae8f360c4a8b720ccf3589b75aca2..aaf61d0428a4616c5f5bf55fab90b2abec7ec219 100644 --- a/drivers/usbhost/usbhost_registerclass.c +++ b/drivers/usbhost/usbhost_registerclass.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include "usbhost_registry.h" @@ -104,14 +104,14 @@ int usbhost_registerclass(struct usbhost_registry_s *usbclass) * protected by disabling interrupts. */ - flags = irqsave(); + flags = enter_critical_section(); /* Add the new class ID info to the head of the list */ usbclass->flink = g_classregistry; g_classregistry = usbclass; - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/drivers/usbhost/usbhost_skeleton.c b/drivers/usbhost/usbhost_skeleton.c index 3c2879969a49c3d882c373af0ad3dee53750746c..9a7ed87de31833b946275daef35a46ea1f623886 100644 --- a/drivers/usbhost/usbhost_skeleton.c +++ b/drivers/usbhost/usbhost_skeleton.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_skeleton.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -250,7 +251,7 @@ static inline FAR struct usbhost_state_s *usbhost_allocclass(void) DEBUGASSERT(!up_interrupt_context()); priv = (FAR struct usbhost_state_s *)kmm_malloc(sizeof(struct usbhost_state_s)); - uvdbg("Allocated: %p\n", priv);; + uvdbg("Allocated: %p\n", priv); return priv; } @@ -276,7 +277,7 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) * executing from an interrupt handler. */ - uvdbg("Freeing: %p\n", usbclass);; + uvdbg("Freeing: %p\n", usbclass); kmm_free(usbclass); } @@ -293,7 +294,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) irqstate_t flags; int devno; - flags = irqsave(); + flags = enter_critical_section(); for (devno = 0; devno < 26; devno++) { uint32_t bitno = 1 << devno; @@ -301,12 +302,12 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) { g_devinuse |= bitno; priv->devchar = 'a' + devno; - irqrestore(flags); + leave_critical_section(flags); return OK; } } - irqrestore(flags); + leave_critical_section(flags); return -EMFILE; } @@ -316,9 +317,9 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv) if (devno >= 0 && devno < 26) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); g_devinuse &= ~(1 << devno); - irqrestore(flags); + leave_critical_section(flags); } } @@ -438,7 +439,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -742,7 +743,7 @@ static void usbhost_putle16(uint8_t *dest, uint16_t val) static inline uint32_t usbhost_getle32(const uint8_t *val) { - /* Little endian means LS halfword first in byte stream */ + /* Little endian means LS halfword first in byte stream */ return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val); } @@ -1003,7 +1004,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) * longer available. */ - flags = irqsave(); + flags = enter_critical_section(); priv->disconnected = true; /* Now check the number of references on the class instance. If it is one, @@ -1036,7 +1037,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) } } - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/drivers/usbhost/usbhost_storage.c b/drivers/usbhost/usbhost_storage.c index baefebb5163452193e81b877c50480ba84b56979..5d01a22b062edb60e3a478fb56bdcc23ffb80642 100644 --- a/drivers/usbhost/usbhost_storage.c +++ b/drivers/usbhost/usbhost_storage.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/usbhost/usbhost_storage.c * - * Copyright (C) 2010-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -368,15 +369,15 @@ static inline FAR struct usbhost_state_s *usbhost_allocclass(void) * our pre-allocated class instances from the free list. */ - flags = irqsave(); + flags = enter_critical_section(); entry = g_freelist; if (entry) { g_freelist = entry->flink; } - irqrestore(flags); - ullvdbg("Allocated: %p\n", entry);; + leave_critical_section(flags); + ullvdbg("Allocated: %p\n", entry); return (FAR struct usbhost_state_s *)entry; } #else @@ -390,7 +391,7 @@ static inline FAR struct usbhost_state_s *usbhost_allocclass(void) DEBUGASSERT(!up_interrupt_context()); priv = (FAR struct usbhost_state_s *)kmm_malloc(sizeof(struct usbhost_state_s)); - uvdbg("Allocated: %p\n", priv);; + uvdbg("Allocated: %p\n", priv); return priv; } #endif @@ -420,10 +421,10 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) /* Just put the pre-allocated class structure back on the freelist */ - flags = irqsave(); + flags = enter_critical_section(); entry->flink = g_freelist; g_freelist = entry; - irqrestore(flags); + leave_critical_section(flags); } #else static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) @@ -434,7 +435,7 @@ static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass) * from an interrupt handler. */ - uvdbg("Freeing: %p\n", usbclass);; + uvdbg("Freeing: %p\n", usbclass); sched_kfree(usbclass); } #endif @@ -452,7 +453,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) irqstate_t flags; int devno; - flags = irqsave(); + flags = enter_critical_section(); for (devno = 0; devno < 26; devno++) { uint32_t bitno = 1 << devno; @@ -460,12 +461,12 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv) { g_devinuse |= bitno; priv->sdchar = 'a' + devno; - irqrestore(flags); + leave_critical_section(flags); return OK; } } - irqrestore(flags); + leave_critical_section(flags); return -EMFILE; } @@ -475,9 +476,9 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv) if (devno >= 0 && devno < 26) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); g_devinuse &= ~(1 << devno); - irqrestore(flags); + leave_critical_section(flags); } } @@ -687,7 +688,7 @@ static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv) uvdbg("Request maximum logical unit number\n"); memset(req, 0, sizeof(struct usb_ctrlreq_s)); - req->type = USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE; + req->type = USB_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; req->req = USBMSC_REQ_GETMAXLUN; usbhost_putle16(req->len, 1); @@ -729,7 +730,7 @@ static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv) usbhost_testunitreadycbw(cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Receive the CSW */ @@ -767,7 +768,7 @@ static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv) usbhost_requestsensecbw(cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Receive the sense data response */ @@ -813,7 +814,7 @@ static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv) usbhost_readcapacitycbw(cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Receive the read capacity CBW IN response */ @@ -864,7 +865,7 @@ static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv) usbhost_inquirycbw(cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Receive the CBW IN response */ @@ -1019,7 +1020,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. - */ + */ remaining = (int)usbhost_getle16(cfgdesc->totallen); @@ -1481,7 +1482,7 @@ static void usbhost_putbe16(uint8_t *dest, uint16_t val) static inline uint32_t usbhost_getle32(const uint8_t *val) { - /* Little endian means LS halfword first in byte stream */ + /* Little endian means LS halfword first in byte stream */ return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val); } @@ -1820,7 +1821,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) * is no longer available. */ - flags = irqsave(); + flags = enter_critical_section(); priv->disconnected = true; /* Now check the number of references on the class instance. If it is one, @@ -1853,7 +1854,7 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass) } } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -1887,7 +1888,7 @@ static int usbhost_open(FAR struct inode *inode) * events. */ - flags = irqsave(); + flags = enter_critical_section(); if (priv->disconnected) { /* No... the block driver is no longer bound to the class. That means that @@ -1904,7 +1905,7 @@ static int usbhost_open(FAR struct inode *inode) priv->crefs++; ret = OK; } - irqrestore(flags); + leave_critical_section(flags); usbhost_givesem(&priv->exclsem); return ret; @@ -1943,7 +1944,7 @@ static int usbhost_close(FAR struct inode *inode) * no asynchronous disconnect events. */ - flags = irqsave(); + flags = enter_critical_section(); /* Check if the USB mass storage device is still connected. If the * storage device is not connected and the reference count just @@ -1959,7 +1960,7 @@ static int usbhost_close(FAR struct inode *inode) usbhost_destroy(priv); } - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -2028,7 +2029,7 @@ static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer, usbhost_readcbw(startsector, priv->blocksize, nsectors, cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Receive the user data */ @@ -2056,7 +2057,8 @@ static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer, } } } - } while (nbytes == -EAGAIN); + } + while (nbytes == -EAGAIN); } usbhost_givesem(&priv->exclsem); @@ -2126,13 +2128,13 @@ static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffe usbhost_writecbw(startsector, priv->blocksize, nsectors, cbw); nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)cbw, USBMSC_CBW_SIZEOF); + (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF); if (nbytes >= 0) { /* Send the user data */ nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout, - (uint8_t*)buffer, priv->blocksize * nsectors); + (FAR uint8_t *)buffer, priv->blocksize * nsectors); if (nbytes >= 0) { /* Receive the CSW */ diff --git a/drivers/usbhost/usbhost_trace.c b/drivers/usbhost/usbhost_trace.c index e99261b50eb8c13dc58140b8dec7a77be00daad5..cd1ef92c4fc0f17d5bfeda324d15b09e03e6aad5 100644 --- a/drivers/usbhost/usbhost_trace.c +++ b/drivers/usbhost/usbhost_trace.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include #undef usbtrace @@ -148,7 +148,7 @@ void usbhost_trace_common(uint32_t event) /* Check if tracing is enabled for this ID */ - flags = irqsave(); + flags = enter_critical_section(); if (!g_disabled) { /* Yes... save the new trace data at the head */ @@ -170,7 +170,7 @@ void usbhost_trace_common(uint32_t event) } } } - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_USBHOST_TRACE */ @@ -230,7 +230,7 @@ void usbhost_trace2(uint16_t id, uint8_t u7, uint16_t u16) #endif /* CONFIG_USBHOST_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_enumerate * * Description: @@ -239,7 +239,7 @@ void usbhost_trace2(uint16_t id, uint8_t u7, uint16_t u16) * Assumptions: * NEVER called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_USBHOST_TRACE int usbhost_trenumerate(usbhost_trcallback_t callback, FAR void *arg) diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 7256fbc202af37a71787eb4aa649f68855245318..ebf37f002cb055b4704e230d88ccc31a320328b2 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -53,7 +53,7 @@ #include #include -#include +#include #include /**************************************************************************** @@ -87,7 +87,8 @@ # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION #endif -#if defined(CONFIG_OV2640_QCIF_RESOLUTION) || defined(CONFIG_OV2640_JPEG_QCIF_RESOLUTION) +#if defined(CONFIG_OV2640_QCIF_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_QCIF_RESOLUTION) # define OV2460_IMAGE_WIDTH 176 # define OV2460_IMAGE_HEIGHT 144 @@ -107,7 +108,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_QVGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_QVGA_RESOLUTION) +#elif defined(CONFIG_OV2640_QVGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_QVGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 320 # define OV2460_IMAGE_HEIGHT 240 @@ -127,7 +129,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_CIF_RESOLUTION) || defined(CONFIG_OV2640_JPEG_CIF_RESOLUTION) +#elif defined(CONFIG_OV2640_CIF_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_CIF_RESOLUTION) # define OV2460_IMAGE_WIDTH 352 # define OV2460_IMAGE_HEIGHT 288 @@ -147,7 +150,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_VGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_VGA_RESOLUTION) +#elif defined(CONFIG_OV2640_VGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_VGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 640 # define OV2460_IMAGE_HEIGHT 480 @@ -167,7 +171,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_SVGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_SVGA_RESOLUTION) +#elif defined(CONFIG_OV2640_SVGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_SVGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 800 # define OV2460_IMAGE_HEIGHT 600 @@ -187,7 +192,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_XVGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_XVGA_RESOLUTION) +#elif defined(CONFIG_OV2640_XVGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_XVGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 1024 # define OV2460_IMAGE_HEIGHT 768 @@ -207,7 +213,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_SXGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_SXVGA_RESOLUTION) +#elif defined(CONFIG_OV2640_SXGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_SXVGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 1280 # define OV2460_IMAGE_HEIGHT 1024 @@ -227,7 +234,8 @@ # undef CONFIG_OV2640_UXGA_RESOLUTION # undef CONFIG_OV2640_JPEG_UXGA_RESOLUTION -#elif defined(CONFIG_OV2640_UXGA_RESOLUTION) || defined(CONFIG_OV2640_JPEG_UXGA_RESOLUTION) +#elif defined(CONFIG_OV2640_UXGA_RESOLUTION) || \ + defined(CONFIG_OV2640_JPEG_UXGA_RESOLUTION) # define OV2460_IMAGE_WIDTH 1600 # define OV2460_IMAGE_HEIGHT 1200 @@ -278,16 +286,16 @@ struct ovr2640_reg_s /* OV2640 register operations */ -static int ov2640_putreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr, +static int ov2640_putreg(FAR struct i2c_master_s *i2c, uint8_t regaddr, uint8_t regval); -static uint8_t ov2640_getreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr); -static int ov2640_putreglist(FAR struct i2c_dev_s *i2c, +static uint8_t ov2640_getreg(FAR struct i2c_master_s *i2c, uint8_t regaddr); +static int ov2640_putreglist(FAR struct i2c_master_s *i2c, FAR const struct ovr2640_reg_s *reglist, size_t nentries); /* Initialization */ -static int ovr2640_chipid(FAR struct i2c_dev_s *i2c); -static int ov2640_reset(FAR struct i2c_dev_s *i2c); +static int ovr2640_chipid(FAR struct i2c_master_s *i2c); +static int ov2640_reset(FAR struct i2c_master_s *i2c); /**************************************************************************** * Private Data @@ -662,6 +670,7 @@ static const struct ovr2640_reg_s g_ov2640_jpeg_uxga_resolution[] = /**************************************************************************** * Private Functions ****************************************************************************/ + /**************************************************************************** * Function: ov2640_putreg * @@ -679,9 +688,10 @@ static const struct ovr2640_reg_s g_ov2640_jpeg_uxga_resolution[] = * ****************************************************************************/ -static int ov2640_putreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr, +static int ov2640_putreg(FAR struct i2c_master_s *i2c, uint8_t regaddr, uint8_t regval) { + struct i2c_config_s config; uint8_t buffer[2]; int ret; @@ -694,12 +704,18 @@ static int ov2640_putreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr, buffer[0] = regaddr; /* Register address */ buffer[1] = regval; /* New register value */ + /* Set up the I2C configuration */ + + config.frequency = CONFIG_OV2640_FREQUENCY; + config.address = CONFIG_OV2640_I2CADDR; + config.addrlen = 7; + /* And do it */ - ret = I2C_WRITE(i2c, buffer, 2); + ret = i2c_write(i2c, &config, buffer, 2); if (ret < 0) { - gdbg("ERROR: I2C_WRITE failed: %d\n", ret); + gdbg("ERROR: i2c_write failed: %d\n", ret); return ret; } @@ -723,26 +739,33 @@ static int ov2640_putreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr, * ****************************************************************************/ -static uint8_t ov2640_getreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr) +static uint8_t ov2640_getreg(FAR struct i2c_master_s *i2c, uint8_t regaddr) { + struct i2c_config_s config; uint8_t regval; int ret; + /* Set up the I2C configuration */ + + config.frequency = CONFIG_OV2640_FREQUENCY; + config.address = CONFIG_OV2640_I2CADDR; + config.addrlen = 7; + /* Write the register address */ - ret = I2C_WRITE(i2c, ®addr, 1); + ret = i2c_write(i2c, &config, ®addr, 1); if (ret < 0) { - gdbg("ERROR: I2C_WRITE failed: %d\n", ret); + gdbg("ERROR: i2c_write failed: %d\n", ret); return 0; } /* Restart and read 8-bits from the register */ - ret = I2C_READ(i2c, ®val, 1); + ret = i2c_read(i2c, &config, ®val, 1); if (ret < 0) { - gdbg("ERROR: I2C_READ failed: %d\n", ret); + gdbg("ERROR: i2c_read failed: %d\n", ret); return 0; } #ifdef CONFIG_OV2640_REGDEBUG @@ -772,7 +795,7 @@ static uint8_t ov2640_getreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr) * ****************************************************************************/ -static int ov2640_putreglist(FAR struct i2c_dev_s *i2c, +static int ov2640_putreglist(FAR struct i2c_master_s *i2c, FAR const struct ovr2640_reg_s *reglist, size_t nentries) { @@ -807,11 +830,11 @@ static int ov2640_putreglist(FAR struct i2c_dev_s *i2c, * ****************************************************************************/ -static int ovr2640_chipid(FAR struct i2c_dev_s *i2c) +static int ovr2640_chipid(FAR struct i2c_master_s *i2c) { uint8_t pidl; uint8_t pidh; -#if CONFIG_DEBUG_GRAPHICS +#ifdef CONFIG_DEBUG_GRAPHICS uint8_t midh; uint8_t midl; #endif @@ -829,7 +852,7 @@ static int ovr2640_chipid(FAR struct i2c_dev_s *i2c) pidl = ov2640_getreg(i2c, 0x0a); /* Product ID (MS) */ pidh = ov2640_getreg(i2c, 0x0b); /* Product ID (LS) */ -#if CONFIG_DEBUG_GRAPHICS +#ifdef CONFIG_DEBUG_GRAPHICS midh = ov2640_getreg(i2c, 0x1c); /* Manufacturer ID (high) = 0x7f */ midl = ov2640_getreg(i2c, 0x1d); /* Manufacturer ID (low) = 0xa2 */ #endif @@ -862,7 +885,7 @@ static int ovr2640_chipid(FAR struct i2c_dev_s *i2c) * ****************************************************************************/ -static int ov2640_reset(FAR struct i2c_dev_s *i2c) +static int ov2640_reset(FAR struct i2c_master_s *i2c) { int ret; @@ -895,15 +918,10 @@ static int ov2640_reset(FAR struct i2c_dev_s *i2c) * ****************************************************************************/ -int ov2640_initialize(FAR struct i2c_dev_s *i2c) +int ov2640_initialize(FAR struct i2c_master_s *i2c) { int ret; - /* Configure I2C bus for the OV2640 */ - - I2C_SETADDRESS(i2c, CONFIG_OV2640_FREQUENCY, 7); - I2C_SETFREQUENCY(i2c, CONFIG_OV2640_I2CADDR); - /* Reset the OVR2640 */ ret = ov2640_reset(i2c); diff --git a/drivers/wireless/ISM1_868MHzGFSK100kbps.c b/drivers/wireless/ISM1_868MHzGFSK100kbps.c index a02b2838afbc679618709845ebf25c8ae943a0d5..88432196d5722c219af52a0489f88e2b8a7bdd12 100644 --- a/drivers/wireless/ISM1_868MHzGFSK100kbps.c +++ b/drivers/wireless/ISM1_868MHzGFSK100kbps.c @@ -84,40 +84,40 @@ const struct c1101_rfsettings_s cc1101_rfsettings_ISM1_868MHzGFSK100kbps = { - .FSCTRL1 = 0x08, /* FSCTRL1 Frequency Synthesizer Control */ - .FSCTRL0 = 0x00, /* FSCTRL0 Frequency Synthesizer Control */ + .FSCTRL1 = 0x08, /* FSCTRL1 Frequency Synthesizer Control */ + .FSCTRL0 = 0x00, /* FSCTRL0 Frequency Synthesizer Control */ - .FREQ2 = 0x20, /* FREQ2 Frequency Control Word, High Byte */ - .FREQ1 = 0x25, /* FREQ1 Frequency Control Word, Middle Byte */ - .FREQ0 = 0xED, /* FREQ0 Frequency Control Word, Low Byte */ + .FREQ2 = 0x20, /* FREQ2 Frequency Control Word, High Byte */ + .FREQ1 = 0x25, /* FREQ1 Frequency Control Word, Middle Byte */ + .FREQ0 = 0xED, /* FREQ0 Frequency Control Word, Low Byte */ - .MDMCFG4 = 0x8B, /* MDMCFG4 Modem Configuration */ - .MDMCFG3 = 0xE5, /* MDMCFG3 Modem Configuration */ - .MDMCFG2 = 0x13, /* MDMCFG2 Modem Configuration */ - .MDMCFG1 = 0x22, /* MDMCFG1 Modem Configuration */ - .MDMCFG0 = 0xE5, /* MDMCFG0 Modem Configuration */ + .MDMCFG4 = 0x8B, /* MDMCFG4 Modem Configuration */ + .MDMCFG3 = 0xE5, /* MDMCFG3 Modem Configuration */ + .MDMCFG2 = 0x13, /* MDMCFG2 Modem Configuration */ + .MDMCFG1 = 0x22, /* MDMCFG1 Modem Configuration */ + .MDMCFG0 = 0xE5, /* MDMCFG0 Modem Configuration */ - .DEVIATN = 0x46, /* DEVIATN Modem Deviation Setting */ + .DEVIATN = 0x46, /* DEVIATN Modem Deviation Setting */ - .FOCCFG = 0x1D, /* FOCCFG Frequency Offset Compensation Configuration */ + .FOCCFG = 0x1D, /* FOCCFG Frequency Offset Compensation Configuration */ - .BSCFG = 0x1C, /* BSCFG Bit Synchronization Configuration */ + .BSCFG = 0x1C, /* BSCFG Bit Synchronization Configuration */ - .AGCCTRL2= 0xC7, /* AGCCTRL2 AGC Control */ - .AGCCTRL1= 0x00, /* AGCCTRL1 AGC Control */ - .AGCCTRL0= 0xB2, /* AGCCTRL0 AGC Control */ + .AGCCTRL2 = 0xC7, /* AGCCTRL2 AGC Control */ + .AGCCTRL1 = 0x00, /* AGCCTRL1 AGC Control */ + .AGCCTRL0 = 0xB2, /* AGCCTRL0 AGC Control */ - .FREND1 = 0xB6, /* FREND1 Front End RX Configuration */ - .FREND0 = 0x10, /* FREND0 Front End TX Configuration */ + .FREND1 = 0xB6, /* FREND1 Front End RX Configuration */ + .FREND0 = 0x10, /* FREND0 Front End TX Configuration */ - .FSCAL3 = 0xEA, /* FSCAL3 Frequency Synthesizer Calibration */ - .FSCAL2 = 0x2A, /* FSCAL2 Frequency Synthesizer Calibration */ - .FSCAL1 = 0x00, /* FSCAL1 Frequency Synthesizer Calibration */ - .FSCAL0 = 0x1F, /* FSCAL0 Frequency Synthesizer Calibration */ + .FSCAL3 = 0xEA, /* FSCAL3 Frequency Synthesizer Calibration */ + .FSCAL2 = 0x2A, /* FSCAL2 Frequency Synthesizer Calibration */ + .FSCAL1 = 0x00, /* FSCAL1 Frequency Synthesizer Calibration */ + .FSCAL0 = 0x1F, /* FSCAL0 Frequency Synthesizer Calibration */ - .CHMIN = 0, /* Fix at 9th channel: 869.80 MHz +- 100 kHz RF Bandwidth */ - .CHMAX = 9, /* single channel */ + .CHMIN = 0, /* Fix at 9th channel: 869.80 MHz +- 100 kHz RF Bandwidth */ + .CHMAX = 9, /* single channel */ - .PAMAX = 8, /* 0 means power OFF, 8 represents PA[7] */ - .PA = {0x03, 0x0F, 0x1E, 0x27, 0x67, 0x50, 0x81, 0xC2} + .PAMAX = 8, /* 0 means power OFF, 8 represents PA[7] */ + .PA = {0x03, 0x0F, 0x1E, 0x27, 0x67, 0x50, 0x81, 0xC2} }; diff --git a/drivers/wireless/ISM2_905MHzGFSK250kbps.c b/drivers/wireless/ISM2_905MHzGFSK250kbps.c index c78cee5864bdebba85ef35cce7d6976e3b4b8cab..a416053b2c71b69f602931637c604d9039c13d30 100644 --- a/drivers/wireless/ISM2_905MHzGFSK250kbps.c +++ b/drivers/wireless/ISM2_905MHzGFSK250kbps.c @@ -82,40 +82,40 @@ const struct c1101_rfsettings_s cc1101_rfsettings_ISM2_905MHzGFSK250kbps = { - .FSCTRL1 = 0x0C, /* FSCTRL1 Frequency Synthesizer Control */ - .FSCTRL0 = 0x00, /* FSCTRL0 Frequency Synthesizer Control */ + .FSCTRL1 = 0x0C, /* FSCTRL1 Frequency Synthesizer Control */ + .FSCTRL0 = 0x00, /* FSCTRL0 Frequency Synthesizer Control */ - .FREQ2 = 0x22, /* FREQ2 Frequency Control Word, High Byte */ - .FREQ1 = 0xB1, /* FREQ1 Frequency Control Word, Middle Byte */ - .FREQ0 = 0x3B, /* FREQ0 Frequency Control Word, Low Byte */ + .FREQ2 = 0x22, /* FREQ2 Frequency Control Word, High Byte */ + .FREQ1 = 0xB1, /* FREQ1 Frequency Control Word, Middle Byte */ + .FREQ0 = 0x3B, /* FREQ0 Frequency Control Word, Low Byte */ - .MDMCFG4 = 0x2D, /* MDMCFG4 Modem Configuration */ - .MDMCFG3 = 0x3B, /* MDMCFG3 Modem Configuration */ - .MDMCFG2 = 0x13, /* MDMCFG2 Modem Configuration */ - .MDMCFG1 = 0x22, /* MDMCFG1 Modem Configuration */ - .MDMCFG0 = 0xF8, /* MDMCFG0 Modem Configuration */ + .MDMCFG4 = 0x2D, /* MDMCFG4 Modem Configuration */ + .MDMCFG3 = 0x3B, /* MDMCFG3 Modem Configuration */ + .MDMCFG2 = 0x13, /* MDMCFG2 Modem Configuration */ + .MDMCFG1 = 0x22, /* MDMCFG1 Modem Configuration */ + .MDMCFG0 = 0xF8, /* MDMCFG0 Modem Configuration */ - .DEVIATN = 0x62, /* DEVIATN Modem Deviation Setting */ + .DEVIATN = 0x62, /* DEVIATN Modem Deviation Setting */ - .FOCCFG = 0x1D, /* FOCCFG Frequency Offset Compensation Configuration */ + .FOCCFG = 0x1D, /* FOCCFG Frequency Offset Compensation Configuration */ - .BSCFG = 0x1C, /* BSCFG Bit Synchronization Configuration */ + .BSCFG = 0x1C, /* BSCFG Bit Synchronization Configuration */ - .AGCCTRL2= 0xC7, /* AGCCTRL2 AGC Control */ - .AGCCTRL1= 0x00, /* AGCCTRL1 AGC Control */ - .AGCCTRL0= 0xB0, /* AGCCTRL0 AGC Control */ + .AGCCTRL2 = 0xC7, /* AGCCTRL2 AGC Control */ + .AGCCTRL1 = 0x00, /* AGCCTRL1 AGC Control */ + .AGCCTRL0 = 0xB0, /* AGCCTRL0 AGC Control */ - .FREND1 = 0xB6, /* FREND1 Front End RX Configuration */ - .FREND0 = 0x10, /* FREND0 Front End TX Configuration */ + .FREND1 = 0xB6, /* FREND1 Front End RX Configuration */ + .FREND0 = 0x10, /* FREND0 Front End TX Configuration */ - .FSCAL3 = 0xEA, /* FSCAL3 Frequency Synthesizer Calibration */ - .FSCAL2 = 0x2A, /* FSCAL2 Frequency Synthesizer Calibration */ - .FSCAL1 = 0x00, /* FSCAL1 Frequency Synthesizer Calibration */ - .FSCAL0 = 0x1F, /* FSCAL0 Frequency Synthesizer Calibration */ + .FSCAL3 = 0xEA, /* FSCAL3 Frequency Synthesizer Calibration */ + .FSCAL2 = 0x2A, /* FSCAL2 Frequency Synthesizer Calibration */ + .FSCAL1 = 0x00, /* FSCAL1 Frequency Synthesizer Calibration */ + .FSCAL0 = 0x1F, /* FSCAL0 Frequency Synthesizer Calibration */ - .CHMIN = 0, /* VERIFY REGULATIONS! */ - .CHMAX = 0xFF, + .CHMIN = 0, /* VERIFY REGULATIONS! */ + .CHMAX = 0xFF, - .PAMAX = 8, /* 0 means power OFF, 8 represents PA[7] */ - .PA = {0x03, 0x0E, 0x1E, 0x27, 0x39, 0x8E, 0xCD, 0xC0} + .PAMAX = 8, /* 0 means power OFF, 8 represents PA[7] */ + .PA = {0x03, 0x0E, 0x1E, 0x27, 0x39, 0x8E, 0xCD, 0xC0} }; diff --git a/drivers/wireless/Kconfig b/drivers/wireless/Kconfig index 194cdd05f821c2f239440f0737ca982fb999e348..e978ef6e8213b07d3f4e2e0722722870447de384 100644 --- a/drivers/wireless/Kconfig +++ b/drivers/wireless/Kconfig @@ -3,6 +3,8 @@ # see the file kconfig-language.txt in the NuttX tools repository. # +if DRIVERS_WIRELESS + config WL_CC1101 bool "CC1101 RF transceiver support" default n @@ -15,6 +17,15 @@ menuconfig WL_CC3000 source drivers/wireless/cc3000/Kconfig +menuconfig DRIVERS_IEEE802154 + bool "IEEE 802.15.4 Device Support" + default n + depends on EXPERIMENTAL + ---help--- + This directory holds implementations of IEEE802.15.4 device drivers. + +source drivers/wireless/ieee802154/Kconfig + config WL_NRF24L01 bool "nRF24l01+ transceiver support" default n @@ -59,5 +70,37 @@ config WL_NRF24L01_RXFIFO_LEN Length of the software based fifo used to store content of received messages. -endif -endif +endif # WL_NRF24L01_RXSUPPORT +endif # WL_NRF24L01 + +config WL_PN532 + bool "pn532 NFC-chip support" + default n + select SPI + ---help--- + This options adds driver support for the PN532 NFC chip. + +if WL_PN532 + +config PN532_SPI_FREQ + int "SPI frequency for PN532" + default 1000000 + depends on WL_PN532 + +config WL_PN532_DEBUG + bool "Enable PN532 debug" + default n + depends on WL_PN532 + +config WL_PN532_DEBUG_TX + bool "trace TX frames" + default n + depends on WL_PN532_DEBUG + +config WL_PN532_DEBUG_RX + bool "trace RX frames" + default n + depends on WL_PN532_DEBUG + +endif # WL_PN532 +endif # DRIVERS_WIRELESS diff --git a/drivers/wireless/Make.defs b/drivers/wireless/Make.defs index b75c4876411f6714db4bb3eaf947717512d2186b..6322a5c0b0379a7fb7d224dad6e304cc6296a576 100644 --- a/drivers/wireless/Make.defs +++ b/drivers/wireless/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/wireless/Make.defs # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -33,7 +33,13 @@ # ############################################################################ -ifeq ($(CONFIG_WIRELESS),y) +ifeq ($(CONFIG_DRIVERS_WIRELESS),y) + +# Include IEEE 802.15.4 support + +ifeq ($(CONFIG_DRIVERS_IEEE802154),y) +include wireless$(DELIM)ieee802154$(DELIM)Make.defs +endif # Include wireless drivers @@ -49,6 +55,10 @@ ifeq ($(CONFIG_WL_CC3000),y) include wireless$(DELIM)cc3000$(DELIM)Make.defs endif +ifeq ($(CONFIG_WL_PN532),y) +CSRCS += pn532.c +endif + # Include wireless devices build support DEPPATH += --dep-path wireless diff --git a/drivers/wireless/cc1101.c b/drivers/wireless/cc1101.c index 16c1d33fbc4bc48cbfadf4873450212574915027..8d8958fc728a21ea42a436d6816979ceb213fe4d 100644 --- a/drivers/wireless/cc1101.c +++ b/drivers/wireless/cc1101.c @@ -220,8 +220,7 @@ #define CC1101_MCSM0_XOSC_FORCE_ON 0x01 -/* - * Chip Status Byte +/* Chip Status Byte */ /* Bit fields in the chip status byte */ @@ -273,9 +272,7 @@ #define CC1101_PARTNUM_VALUE 0x00 #define CC1101_VERSION_VALUE 0x04 -/* - * Others ... - */ +/* Others ... */ #define CC1101_LQI_CRC_OK_BM 0x80 #define CC1101_LQI_EST_BM 0x7F @@ -300,36 +297,47 @@ struct cc1101_dev_s uint8_t power; }; +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static volatile int cc1101_interrupt = 0; + /**************************************************************************** * Private Functions ****************************************************************************/ -void cc1101_access_begin(struct cc1101_dev_s * dev) +void cc1101_access_begin(FAR struct cc1101_dev_s * dev) { (void)SPI_LOCK(dev->spi, true); SPI_SELECT(dev->spi, SPIDEV_WIRELESS, true); SPI_SETMODE(dev->spi, SPIDEV_MODE0); /* CPOL=0, CPHA=0 */ SPI_SETBITS(dev->spi, 8); + (void)SPI_HWFEATURES(dev->spi, 0); } -void cc1101_access_end(struct cc1101_dev_s * dev) +void cc1101_access_end(FAR struct cc1101_dev_s * dev) { SPI_SELECT(dev->spi, SPIDEV_WIRELESS, false); (void)SPI_LOCK(dev->spi, false); } -/** CC1101 Access with Range Check +/* CC1101 Access with Range Check * - * \param dev CC1101 Private Structure - * \param addr CC1101 Address - * \param buf Pointer to buffer, either for read or write access - * \param length when >0 it denotes read access, when <0 it denotes write + * Input Paramters: + * dev CC1101 Private Structure + * addr CC1101 Address + * buf Pointer to buffer, either for read or write access + * length when >0 it denotes read access, when <0 it denotes write * access of -length. abs(length) greater of 1 implies burst mode, * however - * \return OK on success or errno is set. + * + * Returned Value: + * OK on success or errno is set. */ -int cc1101_access(struct cc1101_dev_s * dev, uint8_t addr, uint8_t *buf, int length) +int cc1101_access(FAR struct cc1101_dev_s * dev, uint8_t addr, + FAR uint8_t *buf, int length) { int stabyte; @@ -339,143 +347,160 @@ int cc1101_access(struct cc1101_dev_s * dev, uint8_t addr, uint8_t *buf, int len */ if ((addr & CC1101_READ_SINGLE) && length != 1) - return ERROR; + { + return ERROR; + } - /* Prepare SPI */ + /* Prepare SPI */ - cc1101_access_begin(dev); + cc1101_access_begin(dev); + + if (length > 1 || length < -1) + { + SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_BURST); + } + else + { + SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE); + } - if (length>1 || length < -1) - SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_BURST); - else SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE); + /* Transfer */ - /* Transfer */ + if (length <= 0) + { + /* 0 length are command strobes */ - if (length <= 0) { /* 0 length are command strobes */ - if (length < -1) - addr |= CC1101_WRITE_BURST; + if (length < -1) + { + addr |= CC1101_WRITE_BURST; + } - stabyte = SPI_SEND(dev->spi, addr); - if (length) { - SPI_SNDBLOCK(dev->spi, buf, -length); + stabyte = SPI_SEND(dev->spi, addr); + if (length) + { + SPI_SNDBLOCK(dev->spi, buf, -length); } } - else { - addr |= CC1101_READ_SINGLE; - if (length > 1) - addr |= CC1101_READ_BURST; + else + { + addr |= CC1101_READ_SINGLE; + if (length > 1) + { + addr |= CC1101_READ_BURST; + } - stabyte = SPI_SEND(dev->spi, addr); - SPI_RECVBLOCK(dev->spi, buf, length); + stabyte = SPI_SEND(dev->spi, addr); + SPI_RECVBLOCK(dev->spi, buf, length); } - cc1101_access_end(dev); + cc1101_access_end(dev); - return stabyte; + return stabyte; } - -/** Strobes command and returns chip status byte +/* Strobes command and returns chip status byte * * By default commands are send as Write. To a command, * CC1101_READ_SINGLE may be OR'ed to obtain the number of RX bytes * pending in RX FIFO. */ + inline uint8_t cc1101_strobe(struct cc1101_dev_s * dev, uint8_t command) { - uint8_t status; + uint8_t status; - cc1101_access_begin(dev); - SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE); + cc1101_access_begin(dev); + SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE); - status = SPI_SEND(dev->spi, command); + status = SPI_SEND(dev->spi, command); - cc1101_access_end(dev); + cc1101_access_end(dev); - return status; + return status; } - int cc1101_reset(struct cc1101_dev_s * dev) { - cc1101_strobe(dev, CC1101_SRES); - return OK; + cc1101_strobe(dev, CC1101_SRES); + return OK; } - int cc1101_checkpart(struct cc1101_dev_s * dev) { - uint8_t partnum, version; + uint8_t partnum; + uint8_t version; - if (cc1101_access(dev, CC1101_PARTNUM, &partnum, 1) < 0 || - cc1101_access(dev, CC1101_VERSION, &version, 1) < 0) - return ERROR; + if (cc1101_access(dev, CC1101_PARTNUM, &partnum, 1) < 0 || + cc1101_access(dev, CC1101_VERSION, &version, 1) < 0) + { + return ERROR; + } - if (partnum == CC1101_PARTNUM_VALUE && version == CC1101_VERSION_VALUE) - return OK; + if (partnum == CC1101_PARTNUM_VALUE && version == CC1101_VERSION_VALUE) + { + return OK; + } - return ERROR; + return ERROR; } - void cc1101_dumpregs(struct cc1101_dev_s * dev, uint8_t addr, uint8_t length) { - uint8_t buf[0x30], i; + uint8_t buf[0x30], i; - cc1101_access(dev, addr, buf, length); + cc1101_access(dev, addr, (FAR uint8_t *)buf, length); - printf("CC1101[%2x]: ", addr); - for (i=0; i RX, RX -> RX: 0x3F */ - values[2] = CC1101_MCSM0_VALUE; /* Calibrate on IDLE -> RX/TX, OSC Timeout = ~500 us - TODO: has XOSC_FORCE_ON */ - cc1101_access(dev, CC1101_MCSM2, values, -3); + /* Main Radio Control State Machine */ - /* Wake-On Radio Control */ + values[0] = 0x07; /* No time-out */ + values[1] = 0x00; /* Clear channel if RSSI < thr && !receiving; + * TX -> RX, RX -> RX: 0x3F */ + values[2] = CC1101_MCSM0_VALUE; /* Calibrate on IDLE -> RX/TX, OSC Timeout = ~500 us + * TODO: has XOSC_FORCE_ON */ + cc1101_access(dev, CC1101_MCSM2, values, -3); - // Not used yet. + /* Wake-On Radio Control */ + /* Not used yet. */ - // WOREVT1:WOREVT0 - 16-bit timeout register + /* WOREVT1:WOREVT0 - 16-bit timeout register */ } - /**************************************************************************** * Callbacks ****************************************************************************/ -volatile int cc1101_interrupt = 0; - -/** External line triggers this callback +/* External line triggers this callback * * The concept todo is: * - GPIO provides EXTI Interrupt @@ -612,7 +637,7 @@ int cc1101_setgdo(struct cc1101_dev_s * dev, uint8_t pin, uint8_t function) /* Force XOSC to stay active even in sleep mode */ int value = CC1101_MCSM0_VALUE | CC1101_MCSM0_XOSC_FORCE_ON; - cc1101_access(dev, CC1101_MCSM0, &value, -1); + cc1101_access(dev, CC1101_MCSM0, (FAR uint8_t *)&value, -1); dev->flags |= FLAGS_XOSCENABLED; } @@ -621,7 +646,7 @@ int cc1101_setgdo(struct cc1101_dev_s * dev, uint8_t pin, uint8_t function) /* Disable XOSC in sleep mode */ int value = CC1101_MCSM0_VALUE; - cc1101_access(dev, CC1101_MCSM0, &value, -1); + cc1101_access(dev, CC1101_MCSM0, (FAR uint8_t *)&value, -1); dev->flags &= ~FLAGS_XOSCENABLED; } @@ -634,24 +659,24 @@ int cc1101_setrf(struct cc1101_dev_s * dev, const struct c1101_rfsettings_s *set ASSERT(dev); ASSERT(settings); - if (cc1101_access(dev, CC1101_FSCTRL1, &settings->FSCTRL1, -11) < 0) + if (cc1101_access(dev, CC1101_FSCTRL1, (FAR uint8_t *)&settings->FSCTRL1, -11) < 0) { return ERROR; } - if (cc1101_access(dev, CC1101_FOCCFG, &settings->FOCCFG, -5) < 0) + if (cc1101_access(dev, CC1101_FOCCFG, (FAR uint8_t *)&settings->FOCCFG, -5) < 0) { return ERROR; } - if (cc1101_access(dev, CC1101_FREND1, &settings->FREND1, -6) < 0) + if (cc1101_access(dev, CC1101_FREND1, (FAR uint8_t *)&settings->FREND1, -6) < 0) { return ERROR; } /* Load Power Table */ - if (cc1101_access(dev, CC1101_PATABLE, settings->PA, -8) < 0) + if (cc1101_access(dev, CC1101_PATABLE, (FAR uint8_t *)settings->PA, -8) < 0) { return ERROR; } @@ -664,7 +689,7 @@ int cc1101_setrf(struct cc1101_dev_s * dev, const struct c1101_rfsettings_s *set cc1101_setchannel(dev, dev->channel); cc1101_setpower(dev, dev->power); - return OK; + return OK; } int cc1101_setchannel(struct cc1101_dev_s * dev, uint8_t channel) @@ -753,9 +778,9 @@ int cc1101_read(struct cc1101_dev_s * dev, uint8_t * buf, size_t size) { ASSERT(dev); - if (buf==NULL) + if (buf == NULL) { - if (size==0) + if (size == 0) { return 64; } @@ -823,7 +848,7 @@ int cc1101_write(struct cc1101_dev_s * dev, const uint8_t * buf, size_t size) } cc1101_access(dev, CC1101_TXFIFO, &packetlen, -1); - cc1101_access(dev, CC1101_TXFIFO, buf, -size); + cc1101_access(dev, CC1101_TXFIFO, (FAR uint8_t *)buf, -size); return 0; } diff --git a/drivers/wireless/cc3000/Kconfig b/drivers/wireless/cc3000/Kconfig index 038fd348f21e127f4c827dd74c17f0f014c8f1f3..c1e65c40997f0c3c1cd568b615a5c52cd0dbbaa7 100644 --- a/drivers/wireless/cc3000/Kconfig +++ b/drivers/wireless/cc3000/Kconfig @@ -8,6 +8,8 @@ config WL_CC3000 default n select SPI select ARCH_HAVE_NET + select CRYPTO + select CRYPTO_SW_AES ---help--- Enable support for the TI CC3000 Wifi Module diff --git a/drivers/wireless/cc3000/Make.defs b/drivers/wireless/cc3000/Make.defs index 8ab9cb9211b680b0e1556f5d366cde7cff703d73..9571d750ab5579a66ef1ec56f78830a94655d48e 100644 --- a/drivers/wireless/cc3000/Make.defs +++ b/drivers/wireless/cc3000/Make.defs @@ -38,7 +38,7 @@ ifeq ($(CONFIG_WL_CC3000),y) # Include cc3000 drivers CSRCS += cc3000.c cc3000_common.c cc3000drv.c evnt_handler.c hci.c netapp.c -CSRCS += nvmem.c security.c socket.c socket_imp.c wlan.c +CSRCS += nvmem.c socket.c socket_imp.c wlan.c # Include wireless devices build support diff --git a/drivers/wireless/cc3000/cc3000.c b/drivers/wireless/cc3000/cc3000.c index c11064e5afa87aa21a3f7e05922a3d078fa9a799..f309e968fbada15921d8aee381bbef68bdb05726 100644 --- a/drivers/wireless/cc3000/cc3000.c +++ b/drivers/wireless/cc3000/cc3000.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/wireless/cc3000.c * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * David_s5 * @@ -63,6 +63,7 @@ #include #include +#include #include #include #include @@ -211,27 +212,23 @@ uint8_t spi_readCommand[] = READ_COMMAND; * ****************************************************************************/ -static int cc3000_devtake(FAR struct cc3000_dev_s *priv) +static inline void cc3000_devtake(FAR struct cc3000_dev_s *priv) { - int rv; - /* Take the semaphore (perhaps waiting) */ - while ((rv = sem_wait(&priv->devsem)) != 0) + while (sem_wait(&priv->devsem) < 0) { - /* The only case that an error should occur here is if the wait was awakened - * by a signal. + /* The only case that an error should occur here is if the wait was + * awakened by a signal. */ - DEBUGASSERT(rv == OK || errno == EINTR); + DEBUGASSERT(errno == EINTR); } - - return rv; } -static inline int cc3000_devgive(FAR struct cc3000_dev_s *priv) +static inline void cc3000_devgive(FAR struct cc3000_dev_s *priv) { - return sem_post(&priv->devsem); + (void)sem_post(&priv->devsem); } /**************************************************************************** @@ -259,7 +256,8 @@ static inline void cc3000_configspi(FAR struct spi_dev_s *spi) SPI_SETMODE(spi, CONFIG_CC3000_SPI_MODE); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_CC3000_SPI_FREQUENCY); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_CC3000_SPI_FREQUENCY); } /**************************************************************************** @@ -282,15 +280,9 @@ static inline void cc3000_configspi(FAR struct spi_dev_s *spi) static void cc3000_lock_and_select(FAR struct spi_dev_s *spi) { -#ifndef CONFIG_SPI_OWNBUS - /* Lock the SPI bus because there are multiple devices competing for the - * SPI bus - */ - /* Lock the SPI bus so that we have exclusive access */ (void)SPI_LOCK(spi, true); -#endif /* We have the lock. Now make sure that the SPI bus is configured for the * CC3000 (it might have gotten configured for a different device while @@ -305,9 +297,8 @@ static void cc3000_lock_and_select(FAR struct spi_dev_s *spi) * Function: cc3000_unlock * * Description: - * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS - * undefined) then we need to un-lock the SPI bus for each transfer, - * possibly losing the current configuration. + * Un-lock the SPI bus after each transfer, possibly losing the current + * configuration if we are sharing the SPI bus with other devices. * * Parameters: * spi - Reference to the SPI driver structure @@ -325,11 +316,9 @@ static void cc3000_deselect_and_unlock(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_WIRELESS, false); -#ifndef CONFIG_SPI_OWNBUS /* Relinquish the SPI bus. */ (void)SPI_LOCK(spi, false); -#endif } /**************************************************************************** @@ -350,7 +339,7 @@ static void cc3000_deselect_and_unlock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -static int cc3000_wait(FAR struct cc3000_dev_s *priv, sem_t* psem) +static int cc3000_wait(FAR struct cc3000_dev_s *priv, sem_t *psem) { int ret; @@ -362,27 +351,16 @@ static int cc3000_wait(FAR struct cc3000_dev_s *priv, sem_t* psem) /* Wait on first psem to become signaled */ ret = sem_wait(psem); - if (ret >= 0) - { - /* Yes... then retake the mutual exclusion semaphore */ - - ret = cc3000_devtake(priv); - } - - sched_unlock(); - - /* Was the semaphore wait successful? Did we successful re-take the - * mutual exclusion semaphore? - */ - if (ret < 0) { - /* No.. One of the two sem_wait's failed. */ - - ret = -errno; + return -errno; } - return ret; + /* Then retake the mutual exclusion semaphore */ + + cc3000_devtake(priv); + sched_unlock(); + return OK; } /**************************************************************************** @@ -404,7 +382,7 @@ static int cc3000_wait(FAR struct cc3000_dev_s *priv, sem_t* psem) static inline int cc3000_wait_irq(FAR struct cc3000_dev_s *priv) { - return cc3000_wait(priv,&priv->irqsem); + return cc3000_wait(priv, &priv->irqsem); } /**************************************************************************** @@ -426,7 +404,7 @@ static inline int cc3000_wait_irq(FAR struct cc3000_dev_s *priv) static inline int cc3000_wait_ready(FAR struct cc3000_dev_s *priv) { - return cc3000_wait(priv,&priv->readysem); + return cc3000_wait(priv, &priv->readysem); } /**************************************************************************** @@ -531,7 +509,7 @@ static void * select_thread_func(FAR void *arg) { /* Release the waiting threads */ - waitlldbg("Closed Signaled %d\n",count); + waitlldbg("Closed Signaled %d\n", count); sem_post(&priv->sockets[s].semwait); } } @@ -631,12 +609,12 @@ static void * cc3000_worker(FAR void *arg) ASSERT(priv != NULL && priv->config != NULL); - /* We have started release our creator*/ + /* We have started, release our creator */ sem_post(&priv->readysem); while (1) { - PROBE(0,1); + PROBE(0, 1); CHECK_GUARD(priv); cc3000_devtake(priv); @@ -644,8 +622,8 @@ static void * cc3000_worker(FAR void *arg) if ((cc3000_wait_irq(priv) != -EINTR) && (priv->workertid != -1)) { - PROBE(0,0); - nllvdbg("State%d\n",priv->state); + PROBE(0, 0); + nllvdbg("State%d\n", priv->state); switch (priv->state) { case eSPI_STATE_POWERUP: @@ -672,7 +650,7 @@ static void * cc3000_worker(FAR void *arg) cc3000_lock_and_select(priv->spi); /* Assert CS */ priv->state = eSPI_STATE_READ_PROCEED; - SPI_EXCHANGE(priv->spi,spi_readCommand, priv->rx_buffer.pbuffer, + SPI_EXCHANGE(priv->spi, spi_readCommand, priv->rx_buffer.pbuffer, ARRAY_SIZE(spi_readCommand)); /* Extract Length bytes from Rx Buffer. Here we need to convert @@ -719,7 +697,8 @@ static void * cc3000_worker(FAR void *arg) priv->state = eSPI_STATE_READ_READY; priv->rx_buffer.len = data_to_recv; - ret = mq_send(priv->queue, &priv->rx_buffer, sizeof(priv->rx_buffer), 1); + ret = mq_send(priv->queue, (FAR const char *)&priv->rx_buffer, + sizeof(priv->rx_buffer), 1); DEBUGASSERT(ret >= 0); UNUSED(ret); @@ -737,7 +716,7 @@ static void * cc3000_worker(FAR void *arg) priv->state, priv->config->irq_read(priv->config)); sem_getvalue(&priv->irqsem, &count); - if (priv->config->irq_read(priv->config) && count==0) + if (priv->config->irq_read(priv->config) && count == 0) { sem_post(&priv->irqsem); } @@ -753,7 +732,7 @@ static void * cc3000_worker(FAR void *arg) break; default: - nllvdbg("default: State%d\n",priv->state); + nllvdbg("default: State%d\n", priv->state); break; } } @@ -786,9 +765,9 @@ static int cc3000_interrupt(int irq, FAR void *context) /* Run the worker thread */ - PROBE(1,0); + PROBE(1, 0); sem_post(&priv->irqsem); - PROBE(1,1); + PROBE(1, 1); /* Clear any pending interrupts and return success */ @@ -827,11 +806,7 @@ static int cc3000_open(FAR struct file *filep) /* Get exclusive access to the driver data structure */ - ret = cc3000_devtake(priv); - if (ret < 0) - { - return -ret; - } + cc3000_devtake(priv); /* Increment the reference count */ @@ -866,7 +841,7 @@ static int cc3000_open(FAR struct file *filep) } #endif - /* Ensure the power is off so we get the falling edge of IRQ*/ + /* Ensure the power is off so we get the falling edge of IRQ */ priv->config->power_enable(priv->config, false); @@ -886,7 +861,7 @@ static int cc3000_open(FAR struct file *filep) */ snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, priv->minor); - priv->queue = mq_open(queuename,O_WRONLY|O_CREAT, 0666, &attr); + priv->queue = mq_open(queuename, O_WRONLY | O_CREAT, 0666, &attr); if (priv->queue < 0) { ret = -errno; @@ -993,9 +968,8 @@ out_with_sem: static int cc3000_close(FAR struct file *filep) { - FAR struct inode *inode; + FAR struct inode *inode; FAR struct cc3000_dev_s *priv; - int ret; #ifdef CONFIG_CC3000_MT int s; #endif @@ -1012,11 +986,7 @@ static int cc3000_close(FAR struct file *filep) /* Get exclusive access to the driver data structure */ - ret = cc3000_devtake(priv); - if (ret < 0) - { - return -EINTR; - } + cc3000_devtake(priv); /* Decrement the reference count unless it would decrement a negative * value. When the count decrements to zero, there are no further @@ -1093,13 +1063,7 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len) /* Get exclusive access to the driver data structure */ - ret = cc3000_devtake(priv); - - if (ret < 0) - { - nread = -errno; - goto errout_without_sem; - } + cc3000_devtake(priv); /* Verify that the caller has provided a buffer large enough to receive * the maximum data. @@ -1159,7 +1123,7 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len) { /* Yes... then retake the mutual exclusion semaphore */ - ret = cc3000_devtake(priv); + cc3000_devtake(priv); } /* Was the semaphore wait successful? Did we successful re-take the @@ -1194,7 +1158,7 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len) if (nread > 0) { - memcpy(buffer,priv->rx_buffer.pbuffer,priv->rx_buffer.len); + memcpy(buffer, priv->rx_buffer.pbuffer, priv->rx_buffer.len); priv->rx_buffer.len = 0; } @@ -1234,7 +1198,7 @@ static ssize_t cc3000_write(FAR struct file *filep, FAR const char *usrbuffer, s size_t tx_len = (len & 1) ? len : len +1; - nllvdbg("buffer:%p len:%d tx_len:%d\n", buffer, len, tx_len ); + nllvdbg("buffer:%p len:%d tx_len:%d\n", buffer, len, tx_len); DEBUGASSERT(filep); inode = filep->f_inode; @@ -1246,15 +1210,7 @@ static ssize_t cc3000_write(FAR struct file *filep, FAR const char *usrbuffer, s /* Get exclusive access to the driver data structure */ - ret = cc3000_devtake(priv); - if (ret < 0) - { - /* This should only happen if the wait was canceled by an signal */ - - ndbg("sem_wait: %d\n", errno); - nwritten = -errno; - goto errout_without_sem; - } + cc3000_devtake(priv); /* Figure out the total length of the packet in order to figure out if there is padding or not */ @@ -1359,13 +1315,7 @@ static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* Get exclusive access to the driver data structure */ - ret = cc3000_devtake(priv); - if (ret < 0) - { - /* This should only happen if the wait was canceled by an signal */ - - return -errno; - } + cc3000_devtake(priv); /* Process the IOCTL by command */ @@ -1428,10 +1378,10 @@ static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg) DEBUGASSERT(psize != NULL); rv = priv->rx_buffer_max_len; - flags = irqsave(); + flags = enter_critical_section(); priv->rx_buffer_max_len = *psize; - priv->rx_buffer.pbuffer = kmm_realloc(priv->rx_buffer.pbuffer,*psize); - irqrestore(flags); + priv->rx_buffer.pbuffer = kmm_realloc(priv->rx_buffer.pbuffer, *psize); + leave_critical_section(flags); DEBUGASSERT(priv->rx_buffer.pbuffer); *psize = rv; break; @@ -1470,13 +1420,7 @@ static int cc3000_poll(FAR struct file *filep, FAR struct pollfd *fds, /* Are we setting up the poll? Or tearing it down? */ - ret = cc3000_devtake(priv); - if (ret < 0) - { - /* This should only happen if the wait was canceled by an signal */ - - return -errno; - } + cc3000_devtake(priv); if (setup) { @@ -1605,7 +1549,7 @@ int cc3000_register(FAR struct spi_dev_s *spi, sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ (void)snprintf(semname, SEM_NAMELEN, SEM_FORMAT, minor); - priv->wrkwaitsem = sem_open(semname,O_CREAT,0,0); /* Initialize Worker Wait semaphore */ + priv->wrkwaitsem = sem_open(semname, O_CREAT, 0, 0); /* Initialize Worker Wait semaphore */ #ifdef CONFIG_CC3000_MT pthread_mutex_init(&g_cc3000_mut, NULL); @@ -1645,7 +1589,7 @@ int cc3000_register(FAR struct spi_dev_s *spi, #ifdef CONFIG_CC3000_MULTIPLE priv->flink = g_cc3000list; g_cc3000list = priv; - irqrestore(flags); + leave_critical_section(flags); #endif /* And return success (?) */ @@ -1783,7 +1727,7 @@ static int cc3000_add_socket(FAR struct cc3000_dev_s *priv, int sd) return sd; } - flags = irqsave(); + flags = enter_critical_section(); for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++) { if (priv->sockets[s].sd == FREE_SLOT) @@ -1795,7 +1739,7 @@ static int cc3000_add_socket(FAR struct cc3000_dev_s *priv, int sd) } } - irqrestore(flags); + leave_critical_section(flags); return s >= CONFIG_WL_MAX_SOCKETS ? -1 : OK; } @@ -1826,7 +1770,7 @@ static int cc3000_remove_socket(FAR struct cc3000_dev_s *priv, int sd) return sd; } - flags = irqsave(); + flags = enter_critical_section(); if (priv->accepting_socket.acc.sd == sd) { priv->accepting_socket.acc.sd = CLOSE_SLOT; @@ -1845,7 +1789,7 @@ static int cc3000_remove_socket(FAR struct cc3000_dev_s *priv, int sd) } } - irqrestore(flags); + leave_critical_section(flags); if (ps) { sched_lock(); @@ -1885,7 +1829,7 @@ static int cc3000_remote_closed_socket(FAR struct cc3000_dev_s *priv, int sd) return sd; } - flags = irqsave(); + flags = enter_critical_section(); for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++) { if (priv->sockets[s].sd == sd) @@ -1894,7 +1838,7 @@ static int cc3000_remote_closed_socket(FAR struct cc3000_dev_s *priv, int sd) } } - irqrestore(flags); + leave_critical_section(flags); return s >= CONFIG_WL_MAX_SOCKETS ? -1 : OK; } diff --git a/drivers/wireless/cc3000/cc3000_common.c b/drivers/wireless/cc3000/cc3000_common.c index b23ea46bb65db9a3689c7fc40531f26e13050900..cca794a079c5c516c6f40d5d4d47b299768df587 100644 --- a/drivers/wireless/cc3000/cc3000_common.c +++ b/drivers/wireless/cc3000/cc3000_common.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * cc3000_common.c.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,15 +30,15 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ -/****************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Included files - *****************************************************************************/ + ****************************************************************************/ #include #include -/***************************************************************************** +/**************************************************************************** * Name:__error__ * * Description: @@ -51,9 +51,9 @@ * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: UINT32_TO_STREAM_f * * Description: @@ -67,7 +67,7 @@ * Returned Value: * Pointer to the new stream * - *****************************************************************************/ + ****************************************************************************/ uint8_t *UINT32_TO_STREAM_f(uint8_t *p, unsigned long u32) { @@ -78,7 +78,7 @@ uint8_t *UINT32_TO_STREAM_f(uint8_t *p, unsigned long u32) return p; } -/***************************************************************************** +/**************************************************************************** * Name: UINT16_TO_STREAM_f * * Description: @@ -92,7 +92,7 @@ uint8_t *UINT32_TO_STREAM_f(uint8_t *p, unsigned long u32) * Returned Value: * Pointer to the new stream * - *****************************************************************************/ + ****************************************************************************/ uint8_t *UINT16_TO_STREAM_f(uint8_t *p, uint16_t u16) { @@ -101,7 +101,7 @@ uint8_t *UINT16_TO_STREAM_f(uint8_t *p, uint16_t u16) return p; } -/***************************************************************************** +/**************************************************************************** * Name: STREAM_TO_UINT16_f * * Description: @@ -115,15 +115,15 @@ uint8_t *UINT16_TO_STREAM_f(uint8_t *p, uint16_t u16) * Returned Value: * Pointer to the new 16 bit * - *****************************************************************************/ + ****************************************************************************/ -uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset) +uint16_t STREAM_TO_UINT16_f(FAR char *p, uint16_t offset) { return (uint16_t)((uint16_t)((uint16_t) (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); } -/***************************************************************************** +/**************************************************************************** * Name: STREAM_TO_UINT32_f * * Description: @@ -137,9 +137,9 @@ uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset) * Returned Value: * Pointer to the new 32 bit * - *****************************************************************************/ + ****************************************************************************/ -unsigned long STREAM_TO_UINT32_f(char* p, uint16_t offset) +unsigned long STREAM_TO_UINT32_f(FAR char *p, uint16_t offset) { return (unsigned long)((unsigned long)((unsigned long) (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long) diff --git a/drivers/wireless/cc3000/cc3000_socket.h b/drivers/wireless/cc3000/cc3000_socket.h index 4287e9cf5d03d5f8c25c86acb80227440e9a5c13..0218221abc0eaa4b1f86c4e36aeafdd188c08d94 100644 --- a/drivers/wireless/cc3000/cc3000_socket.h +++ b/drivers/wireless/cc3000/cc3000_socket.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * drivers/wireless/cc3000_socket.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,7 +30,7 @@ * (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 __DRIVERS_WIRELESS_CC3000_SOCKET_H #define __DRIVERS_WIRELESS_CC3000_SOCKET_H @@ -43,9 +43,9 @@ #include #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define CC3000_HOSTNAME_MAX_LENGTH (230) /* 230 bytes + header shouldn't exceed 8 * bit value */ @@ -150,9 +150,9 @@ sockaddr.sa_data[4] = 0x0; \ sockaddr.sa_data[5] = 0xfb; -/***************************************************************************** +/**************************************************************************** * Public Types - *****************************************************************************/ + ****************************************************************************/ /* The fd_set member is required to be an array of longs. */ @@ -165,19 +165,19 @@ typedef struct __fd_mask fds_bits[CC3000_FD_SETSIZE / __NFDBITS]; } TICC3000fd_set; -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: cc3000_socket_impl * * Decription: @@ -198,11 +198,11 @@ extern "C" { * On success, socket handle that is used for consequent socket * operations. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_socket_impl(long domain, long type, long protocol); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_closesocket_impl * * Decription: @@ -214,11 +214,11 @@ int cc3000_socket_impl(long domain, long type, long protocol); * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_closesocket_impl(long sd); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_accept_impl * * Decription: @@ -261,11 +261,11 @@ long cc3000_closesocket_impl(long sd); * - On connection pending, SOC_IN_PROGRESS (-2) * - On failure, SOC_ERROR (-1) * - *****************************************************************************/ + ****************************************************************************/ long cc3000_accept_impl(long sd, struct sockaddr *addr, socklen_t *addrlen); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_bind_impl * * Decription: @@ -286,11 +286,11 @@ long cc3000_accept_impl(long sd, struct sockaddr *addr, socklen_t *addrlen); * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_bind_impl(long sd, FAR const struct sockaddr *addr, socklen_t addrlen); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_listen_impl * * Decription: @@ -312,11 +312,11 @@ long cc3000_bind_impl(long sd, FAR const struct sockaddr *addr, socklen_t addrle * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_listen_impl(long sd, long backlog); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_connect_impl * * Decription: @@ -344,11 +344,11 @@ long cc3000_listen_impl(long sd, long backlog); * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ long cc3000_connect_impl(long sd, FAR const struct sockaddr *addr, socklen_t addrlen); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_select_impl * * Decription: @@ -385,7 +385,7 @@ long cc3000_connect_impl(long sd, FAR const struct sockaddr *addr, socklen_t add * will return without delay. * *exceptfds - return the sockets which closed recently. * - *****************************************************************************/ + ****************************************************************************/ struct timeval; @@ -396,7 +396,7 @@ int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, #ifndef CC3000_TINY_DRIVER -/***************************************************************************** +/**************************************************************************** * Name: cc3000_setsockopt_impl * * Decription: @@ -442,12 +442,12 @@ int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_setsockopt_impl(long sd, long level, long optname, const void *optval, socklen_t optlen); #endif -/***************************************************************************** +/**************************************************************************** * Name: cc3000_getsockopt_impl * * Decription: @@ -493,12 +493,12 @@ int cc3000_setsockopt_impl(long sd, long level, long optname, const void *optval * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_getsockopt_impl(long sd, long level, long optname, void *optval, socklen_t *optlen); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_recv_impl * * Decription: @@ -518,11 +518,11 @@ int cc3000_getsockopt_impl(long sd, long level, long optname, void *optval, sock * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_recv_impl(long sd, void *buf, long len, long flags); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_recvfrom_impl * * Decription: @@ -549,12 +549,12 @@ int cc3000_recv_impl(long sd, void *buf, long len, long flags); * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_recvfrom_impl(long sd, void *buf, long len, long flags, struct sockaddr *from, socklen_t *fromlen); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_send_impl * * Decription: @@ -574,11 +574,11 @@ int cc3000_recvfrom_impl(long sd, void *buf, long len, long flags, * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_send_impl(long sd, const void *buf, long len, long flags); -/***************************************************************************** +/**************************************************************************** * Name: cc3000_sendto_impl * * Decription: @@ -602,13 +602,13 @@ int cc3000_send_impl(long sd, const void *buf, long len, long flags); * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_sendto_impl(long sd, FAR const void *buf, long len, long flags, FAR const struct sockaddr *to, socklen_t tolen); #ifndef CC3000_TINY_DRIVER -/***************************************************************************** +/**************************************************************************** * Name: cc3000_gethostbyname_impl * * Decription: @@ -629,13 +629,13 @@ int cc3000_sendto_impl(long sd, FAR const void *buf, long len, long flags, * Returned Value: * On success, positive is returned. On error, negative is returned * - *****************************************************************************/ + ****************************************************************************/ //struct hostent *gethostbyname(const char *name); int cc3000_gethostbyname_impl(char * hostname, uint16_t usNameLen, unsigned long* out_ip_addr); #endif -/***************************************************************************** +/**************************************************************************** * Name: cc3000_mdnsAdvertiser_impl * * Decription: @@ -651,7 +651,7 @@ int cc3000_gethostbyname_impl(char * hostname, uint16_t usNameLen, unsigned long * On success, zero is returned, return SOC_ERROR if socket was not * opened successfully, or if an error occurred. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_mdnsadvertiser_impl(uint16_t mdnsEnabled, char * deviceServiceName, uint16_t deviceServiceNameLength); diff --git a/drivers/wireless/cc3000/cc3000drv.c b/drivers/wireless/cc3000/cc3000drv.c index 712c2803eb22d7d217264a3e0f5ae6427de3dc83..e192dbf17563203409c9c7d94504e1154c97f998 100644 --- a/drivers/wireless/cc3000/cc3000drv.c +++ b/drivers/wireless/cc3000/cc3000drv.c @@ -1,6 +1,6 @@ -/************************************************************************** - * drivers/wireless/cc3000/cc3000drv.c - Driver wrapper functions to - * conntect nuttx to the TI CC3000 +/**************************************************************************** + * drivers/wireless/cc3000/cc3000drv.c + * Driver wrapper functions to conntect nuttx to the TI CC3000 * * Port to nuttx: * David Sidrane @@ -33,11 +33,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include @@ -57,9 +57,9 @@ #include #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #undef SPI_DEBUG /* Define to enable debug */ #undef SPI_VERBOSE /* Define to enable verbose debug */ @@ -77,9 +77,9 @@ # define spivdbg(x...) #endif -/***************************************************************************** +/**************************************************************************** * Private Types - *****************************************************************************/ + ****************************************************************************/ static struct { @@ -96,11 +96,11 @@ static struct -1, }; -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: cc3000_resume * * Description: @@ -112,7 +112,7 @@ static struct * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void cc3000_resume(void) { @@ -121,7 +121,7 @@ void cc3000_resume(void) nllvdbg("Done\n"); } -/***************************************************************************** +/**************************************************************************** * Name: cc3000_write * * Description: @@ -133,15 +133,15 @@ void cc3000_resume(void) * * Returned Value: * - *****************************************************************************/ + ****************************************************************************/ long cc3000_write(uint8_t *pUserBuffer, uint16_t usLength) { DEBUGASSERT(spiconf.cc3000fd >= 0); - return write(spiconf.cc3000fd,pUserBuffer,usLength) == usLength ? 0 : -errno; + return write(spiconf.cc3000fd, pUserBuffer, usLength) == usLength ? 0 : -errno; } -/***************************************************************************** +/**************************************************************************** * Name: cc3000_read * * Description: @@ -154,15 +154,15 @@ long cc3000_write(uint8_t *pUserBuffer, uint16_t usLength) * * Returned Value: * - *****************************************************************************/ + ****************************************************************************/ long cc3000_read(uint8_t *pUserBuffer, uint16_t usLength) { DEBUGASSERT(spiconf.cc3000fd >= 0); - return read(spiconf.cc3000fd,pUserBuffer,usLength); + return read(spiconf.cc3000fd, pUserBuffer, usLength); } -/***************************************************************************** +/**************************************************************************** * Name: cc3000_wait * * Description: @@ -173,17 +173,18 @@ long cc3000_read(uint8_t *pUserBuffer, uint16_t usLength) * * Returned Value: * - *****************************************************************************/ + ****************************************************************************/ uint8_t *cc3000_wait(void) { DEBUGASSERT(spiconf.cc3000fd >= 0); - mq_receive(spiconf.queue, &spiconf.rx_buffer, sizeof(spiconf.rx_buffer), 0); + mq_receive(spiconf.queue, (FAR char *)&spiconf.rx_buffer, + sizeof(spiconf.rx_buffer), 0); return spiconf.rx_buffer.pbuffer; } -/***************************************************************************** +/**************************************************************************** * Name: unsoliced_thread_func * * Description: @@ -195,7 +196,7 @@ uint8_t *cc3000_wait(void) * * Returned Value: * - *****************************************************************************/ + ****************************************************************************/ static void *unsoliced_thread_func(void *parameter) { @@ -206,23 +207,23 @@ static void *unsoliced_thread_func(void *parameter) ioctl(spiconf.cc3000fd, CC3000IOC_GETQUESEMID, (unsigned long)&minor); snprintf(buff, QUEUE_NAMELEN, QUEUE_FORMAT, minor); - spiconf.queue = mq_open(buff,O_RDONLY); + spiconf.queue = mq_open(buff, O_RDONLY); DEBUGASSERT(spiconf.queue != (mqd_t) -1); DEBUGASSERT(SEM_NAMELEN == QUEUE_NAMELEN); snprintf(buff, SEM_NAMELEN, SEM_FORMAT, minor); - spiconf.done = sem_open(buff,O_RDONLY); + spiconf.done = sem_open(buff, O_RDONLY); DEBUGASSERT(spiconf.done != (sem_t *)-1); sem_post(&spiconf.unsoliced_thread_wakesem); while (spiconf.run) { - memset(&spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer)); - nbytes = mq_receive(spiconf.queue, &spiconf.rx_buffer, + memset(&spiconf.rx_buffer, 0, sizeof(spiconf.rx_buffer)); + nbytes = mq_receive(spiconf.queue, (FAR char *)&spiconf.rx_buffer, sizeof(spiconf.rx_buffer), 0); if (nbytes > 0) { - nlldbg("%d Processed\n",nbytes); + nlldbg("%d Processed\n", nbytes); spiconf.pfRxHandler(spiconf.rx_buffer.pbuffer); } } @@ -233,7 +234,7 @@ static void *unsoliced_thread_func(void *parameter) return (pthread_addr_t)status; } -/***************************************************************************** +/**************************************************************************** * Name: cc3000_open * * Description: @@ -245,7 +246,7 @@ static void *unsoliced_thread_func(void *parameter) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void cc3000_open(gcSpiHandleRx pfRxHandler) { @@ -254,7 +255,7 @@ void cc3000_open(gcSpiHandleRx pfRxHandler) DEBUGASSERT(spiconf.cc3000fd == -1); - fd = open("/dev/wireless0",O_RDWR|O_BINARY); + fd = open("/dev/wireless0", O_RDWR | O_BINARY); if (fd >= 0) { spiconf.pfRxHandler = pfRxHandler; @@ -285,7 +286,7 @@ void cc3000_open(gcSpiHandleRx pfRxHandler) DEBUGASSERT(spiconf.cc3000fd >= 0); } -/***************************************************************************** +/**************************************************************************** * Name: cc3000_close * * Description: @@ -297,7 +298,7 @@ void cc3000_open(gcSpiHandleRx pfRxHandler) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void cc3000_close(void) { @@ -307,7 +308,7 @@ void cc3000_close(void) spiconf.run = false; pthread_cancel(spiconf.unsoliced_thread); - pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status); + pthread_join(spiconf.unsoliced_thread, (FAR pthread_addr_t *)&status); close(spiconf.cc3000fd); @@ -356,11 +357,8 @@ int cc3000_wait_data(int sockfd) * ****************************************************************************/ -int to_cc3000_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - int cc3000_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - //return to_cc3000_accept_socket(sockfd, addr,addrlen); DEBUGASSERT(spiconf.cc3000fd >= 0); cc3000_acceptcfg cfg; diff --git a/drivers/wireless/cc3000/cc3000drv.h b/drivers/wireless/cc3000/cc3000drv.h index f23eaf164a855d146b9f71c51fbe9ba8825b1970..4c67fa2fe40d3fe05eae473381b41fbcba590906 100644 --- a/drivers/wireless/cc3000/cc3000drv.h +++ b/drivers/wireless/cc3000/cc3000drv.h @@ -1,4 +1,4 @@ -/************************************************************************** +/**************************************************************************** * drivers/wireless/cc3000/cc3000drv.h - Driver wrapper functions to * connect nuttx to the TI CC3000 * @@ -33,31 +33,31 @@ * (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 __DRIVERS_WIRELESS_CC3000_CC3000DRV_H #define __DRIVERS_WIRELESS_CC3000_CC3000DRV_H -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include -/***************************************************************************** +/**************************************************************************** * Public Types - *****************************************************************************/ + ****************************************************************************/ typedef void (*gcSpiHandleRx)(void *p); -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus #define EXTERN extern "C" diff --git a/drivers/wireless/cc3000/evnt_handler.c b/drivers/wireless/cc3000/evnt_handler.c index 9a1a2eee8591c0b910983b539cc978b53ae5d185..b890a9a9b7c591b709f845a3a79a5bf02383ac9c 100644 --- a/drivers/wireless/cc3000/evnt_handler.c +++ b/drivers/wireless/cc3000/evnt_handler.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * evnt_handler.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -51,9 +51,9 @@ #include "cc3000drv.h" #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) #define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) @@ -103,23 +103,23 @@ #define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) #define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL; -/***************************************************************************** +/**************************************************************************** * Private Function Prototypes - *****************************************************************************/ + ****************************************************************************/ static long hci_event_unsol_flowcontrol_handler(char *pEvent); static void update_socket_active_status(char *resp_params); -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ -/***************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: hci_unsol_handle_patch_request * * Description: @@ -131,7 +131,7 @@ static void update_socket_active_status(char *resp_params); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void hci_unsol_handle_patch_request(char *event_hdr) { @@ -208,7 +208,7 @@ void hci_unsol_handle_patch_request(char *event_hdr) } } -/***************************************************************************** +/**************************************************************************** * Name: hci_event_handler * * Description: @@ -223,7 +223,7 @@ void hci_unsol_handle_patch_request(char *event_hdr) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) { @@ -237,7 +237,8 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) while (1) { - if (tSLInformation.usEventOrDataReceived != 0) { + if (tSLInformation.usEventOrDataReceived != 0) + { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) @@ -258,7 +259,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); - switch(usReceivedEventOpcode) + switch (usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { @@ -449,37 +450,37 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) /* Read IP address */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read subnet */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read default GW */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DHCP server */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DNS server */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read Mac address */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; /* Read SSID */ - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); + STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_SSID_LENGTH); break; default: @@ -552,7 +553,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) return NULL; } -/***************************************************************************** +/**************************************************************************** * Name: hci_unsol_event_handler * * Description: @@ -565,7 +566,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) * 1 if event supported and handled * 0 if event is not supported * - *****************************************************************************/ + ****************************************************************************/ long hci_unsol_event_handler(char *event_hdr) { @@ -574,7 +575,7 @@ long hci_unsol_event_handler(char *event_hdr) unsigned long NumberOfReleasedPackets; unsigned long NumberOfSentPackets; - STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); + STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET, event_type); if (event_type == HCI_EVNT_PATCHES_REQ) { @@ -583,7 +584,7 @@ long hci_unsol_event_handler(char *event_hdr) if (event_type & HCI_EVNT_UNSOL_BASE) { - switch(event_type) + switch (event_type) { case HCI_EVNT_DATA_UNSOL_FREE_BUFF: { @@ -607,7 +608,7 @@ long hci_unsol_event_handler(char *event_hdr) if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) { - switch(event_type) + switch (event_type) { case HCI_EVNT_WLAN_KEEPALIVE: case HCI_EVNT_WLAN_UNSOL_CONNECT: @@ -623,34 +624,34 @@ long hci_unsol_event_handler(char *event_hdr) case HCI_EVNT_WLAN_UNSOL_DHCP: { - uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status + uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; /* Extra byte is for the status */ uint8_t *recParams = params; - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; + data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; /* Read IP address */ - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); data += 4; /* Read subnet */ - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); data += 4; /* Read default GW */ - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); data += 4; /* Read DHCP server */ - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); data += 4; /* Read DNS server */ - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); /* Read the status */ @@ -666,7 +667,7 @@ long hci_unsol_event_handler(char *event_hdr) case HCI_EVNT_WLAN_ASYNC_PING_REPORT: { netapp_pingreport_args_t params; - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; + data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); @@ -684,7 +685,7 @@ long hci_unsol_event_handler(char *event_hdr) { int sockfd; - data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE; + data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, sockfd); data += 4; @@ -713,7 +714,7 @@ long hci_unsol_event_handler(char *event_hdr) long status; pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); - STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); + STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET, status); if (ERROR_SOCKET_INACTIVE == status) { @@ -737,7 +738,7 @@ long hci_unsol_event_handler(char *event_hdr) return 0; } -/***************************************************************************** +/**************************************************************************** * Name: hci_unsolicited_event_handler * * Description: @@ -750,7 +751,7 @@ long hci_unsol_event_handler(char *event_hdr) * Returned Value: * ESUCCESS if successful, EFAIL if an error occurred * - *****************************************************************************/ + ****************************************************************************/ long hci_unsolicited_event_handler(void) { @@ -782,7 +783,7 @@ long hci_unsolicited_event_handler(void) return res; } -/***************************************************************************** +/**************************************************************************** * Name: set_socket_active_status * * Description: @@ -796,7 +797,7 @@ long hci_unsolicited_event_handler(void) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void set_socket_active_status(long Sd, long Status) { @@ -807,7 +808,7 @@ void set_socket_active_status(long Sd, long Status) } } -/***************************************************************************** +/**************************************************************************** * Name: hci_event_unsol_flowcontrol_handler * * Description: @@ -821,16 +822,16 @@ void set_socket_active_status(long Sd, long Status) * Returned Value: * ESUCCESS if successful, EFAIL if an error occurred * - *****************************************************************************/ + ****************************************************************************/ long hci_event_unsol_flowcontrol_handler(char *pEvent) { long temp, value; uint16_t i; - uint16_t pusNumberOfHandles=0; + uint16_t pusNumberOfHandles = 0; char *pReadPayload; - STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); + STREAM_TO_UINT16((char *)pEvent, HCI_EVENT_HEADER_SIZE, pusNumberOfHandles); pReadPayload = ((char *)pEvent + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); temp = 0; @@ -848,7 +849,7 @@ long hci_event_unsol_flowcontrol_handler(char *pEvent) return(ESUCCESS); } -/***************************************************************************** +/**************************************************************************** * Name: get_socket_active_status * * Description: @@ -860,7 +861,7 @@ long hci_event_unsol_flowcontrol_handler(char *pEvent) * Returned Value: * Current status of the socket. * - *****************************************************************************/ + ****************************************************************************/ long get_socket_active_status(long Sd) { @@ -873,7 +874,7 @@ long get_socket_active_status(long Sd) return SOCKET_STATUS_INACTIVE; } -/***************************************************************************** +/**************************************************************************** * Name: update_socket_active_status * * Description: @@ -885,14 +886,14 @@ long get_socket_active_status(long Sd) * Returned Value: * Current status of the socket. * - *****************************************************************************/ + ****************************************************************************/ void update_socket_active_status(char *resp_params) { long status, sd; - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET, sd); + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET, status); if (ERROR_SOCKET_INACTIVE == status) { @@ -900,7 +901,7 @@ void update_socket_active_status(char *resp_params) } } -/***************************************************************************** +/**************************************************************************** * Name: SimpleLinkWaitEvent * * Description: @@ -914,7 +915,7 @@ void update_socket_active_status(char *resp_params) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void SimpleLinkWaitEvent(uint16_t opcode, void *pRetParams) { @@ -923,7 +924,7 @@ void SimpleLinkWaitEvent(uint16_t opcode, void *pRetParams) */ tSLInformation.usRxEventOpcode = opcode; - nllvdbg("Looking for opcode 0x%x\n",opcode); + nllvdbg("Looking for opcode 0x%x\n", opcode); uint16_t event_type; do @@ -931,32 +932,33 @@ void SimpleLinkWaitEvent(uint16_t opcode, void *pRetParams) nllvdbg("cc3000_wait\n"); tSLInformation.pucReceivedData = cc3000_wait(); tSLInformation.usEventOrDataReceived = 1; - STREAM_TO_UINT16((char *)tSLInformation.pucReceivedData, HCI_EVENT_OPCODE_OFFSET,event_type); + STREAM_TO_UINT16((FAR char *)tSLInformation.pucReceivedData, + HCI_EVENT_OPCODE_OFFSET, event_type); if (*tSLInformation.pucReceivedData == HCI_TYPE_EVNT) { - nllvdbg("Evtn:0x%x\n",event_type); + nllvdbg("Evtn:0x%x\n", event_type); } if (event_type != opcode) { if (hci_unsolicited_event_handler() == 1) { - nllvdbg("Processed Event 0x%x want 0x%x\n",event_type, opcode); + nllvdbg("Processed Event 0x%x want 0x%x\n", event_type, opcode); } } else { - nllvdbg("Processing opcode 0x%x\n",opcode); + nllvdbg("Processing opcode 0x%x\n", opcode); hci_event_handler(pRetParams, 0, 0); } } while (tSLInformation.usRxEventOpcode != 0); - nllvdbg("Done for opcode 0x%x\n",opcode); + nllvdbg("Done for opcode 0x%x\n", opcode); } -/***************************************************************************** +/**************************************************************************** * Name: SimpleLinkWaitData * * Description: @@ -971,7 +973,7 @@ void SimpleLinkWaitEvent(uint16_t opcode, void *pRetParams) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) { @@ -1005,7 +1007,7 @@ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) } else { - nllvdbg("!!!!!opcode 0x%x\n",opcode); + nllvdbg("!!!!!opcode 0x%x\n", opcode); } UNUSED(event_type); diff --git a/drivers/wireless/cc3000/hci.c b/drivers/wireless/cc3000/hci.c index e82fd842dfd3073d3b6aa135980300aa173ebdae..6caf64c60d490e6757b015ab2bee575e75225458 100644 --- a/drivers/wireless/cc3000/hci.c +++ b/drivers/wireless/cc3000/hci.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * hci.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -47,16 +47,16 @@ #include #include -/****************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ #define SL_PATCH_PORTION_SIZE (1000) -/****************************************************************************** +/**************************************************************************** * Public Functions - ******************************************************************************/ -/****************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: hci_command_send * * Description: @@ -70,7 +70,7 @@ * Returned Value: * Zero * - *****************************************************************************/ + ****************************************************************************/ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength) @@ -79,7 +79,7 @@ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, stream = (pucBuff + SPI_HEADER_SIZE); - nllvdbg("Send 0x%x\n",usOpcode); + nllvdbg("Send 0x%x\n", usOpcode); UINT8_TO_STREAM(stream, HCI_TYPE_CMND); stream = UINT16_TO_STREAM(stream, usOpcode); UINT8_TO_STREAM(stream, ucArgsLength); @@ -87,12 +87,12 @@ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, /* Update the opcode of the event we will be waiting for */ cc3000_write(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - nllvdbg("Send of 0x%x Completed\n",usOpcode); + nllvdbg("Send of 0x%x Completed\n", usOpcode); return 0; } -/****************************************************************************** +/**************************************************************************** * Name: hci_data_send * * Description: @@ -108,7 +108,7 @@ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, uint16_t usDataLength, const uint8_t *ucTail, @@ -132,7 +132,7 @@ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, return ESUCCESS; } -/****************************************************************************** +/**************************************************************************** * Name: hci_data_command_send * * Description: @@ -147,10 +147,10 @@ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, - uint8_t ucArgsLength,uint16_t ucDataLength) + uint8_t ucArgsLength, uint16_t ucDataLength) { uint8_t *stream = (pucBuff + SPI_HEADER_SIZE); @@ -166,7 +166,7 @@ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); } -/****************************************************************************** +/**************************************************************************** * Name: hci_patch_send * * Description: @@ -181,7 +181,7 @@ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch, uint16_t usDataLength) diff --git a/drivers/wireless/cc3000/host_driver_version.h b/drivers/wireless/cc3000/host_driver_version.h index 70204b17fa6a9e8fbaece24920a72457abe73e8b..e191ba1ae0a070dba397951ecd91b60ef6a2323a 100644 --- a/drivers/wireless/cc3000/host_driver_version.h +++ b/drivers/wireless/cc3000/host_driver_version.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * * host_driver_version.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ diff --git a/drivers/wireless/cc3000/netapp.c b/drivers/wireless/cc3000/netapp.c index b6a76ed4fc52b323bc56f1abe99cfa0d2c678ba7..f6ac0aa0426ed98d7c140c8e04937ec7fc299720 100644 --- a/drivers/wireless/cc3000/netapp.c +++ b/drivers/wireless/cc3000/netapp.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * netapp.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -46,9 +46,9 @@ #include "cc3000.h" #include "cc3000_socket.h" -/****************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ #define MIN_TIMER_VAL_SECONDS 20 #define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ @@ -62,11 +62,11 @@ #define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) #define NETAPP_PING_SEND_PARAMS_LEN (16) -/****************************************************************************** +/**************************************************************************** * Public Functions - ******************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Name: netapp_config_mac_adrress * * Description: @@ -80,14 +80,14 @@ * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ long netapp_config_mac_adrress(uint8_t *mac) { return nvmem_set_mac_address(mac); } -/****************************************************************************** +/**************************************************************************** * Name: netapp_dhcp * * Description: @@ -112,7 +112,7 @@ long netapp_config_mac_adrress(uint8_t *mac) * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, unsigned long *aucDefaultGateway, unsigned long *aucDNSServer) @@ -129,11 +129,11 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, /* Fill in temporary command buffer */ - ARRAY_TO_STREAM(args,aucIP,4); - ARRAY_TO_STREAM(args,aucSubnetMask,4); - ARRAY_TO_STREAM(args,aucDefaultGateway,4); + ARRAY_TO_STREAM(args, aucIP, 4); + ARRAY_TO_STREAM(args, aucSubnetMask, 4); + ARRAY_TO_STREAM(args, aucDefaultGateway, 4); args = UINT32_TO_STREAM(args, 0); - ARRAY_TO_STREAM(args,aucDNSServer,4); + ARRAY_TO_STREAM(args, aucDNSServer, 4); /* Initiate a HCI command */ @@ -148,7 +148,7 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, return(scRet); } -/****************************************************************************** +/**************************************************************************** * Name: netapp_timeout_values * * Description: @@ -196,7 +196,7 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, @@ -241,7 +241,7 @@ long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_send * * Description: @@ -263,7 +263,7 @@ long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, @@ -299,7 +299,7 @@ long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_report * * Description: @@ -324,7 +324,7 @@ long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER void netapp_ping_report(void) @@ -349,7 +349,7 @@ void netapp_ping_report(void) } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_stop * * Description: @@ -361,7 +361,7 @@ void netapp_ping_report(void) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_ping_stop(void) @@ -388,7 +388,7 @@ long netapp_ping_stop(void) } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ipconfig * * Description: @@ -416,7 +416,7 @@ long netapp_ping_stop(void) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig) @@ -443,7 +443,7 @@ void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig) } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_arp_flush * * Description: @@ -455,7 +455,7 @@ void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_arp_flush(void) @@ -483,7 +483,7 @@ long netapp_arp_flush(void) } #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_set_debug_level * * Description: @@ -507,7 +507,7 @@ long netapp_arp_flush(void) * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_set_debug_level(unsigned long ulLevel) diff --git a/drivers/wireless/cc3000/nvmem.c b/drivers/wireless/cc3000/nvmem.c index 82fac1de68eb77e8771dcbe3fa0717b76a461f12..8009e4802044f4e7f0dbc4fbfafe83d2439e8525 100644 --- a/drivers/wireless/cc3000/nvmem.c +++ b/drivers/wireless/cc3000/nvmem.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * nvmem.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include #include @@ -44,18 +44,18 @@ #include #include "cc3000.h" -/****************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ #define NVMEM_READ_PARAMS_LEN (12) #define NVMEM_CREATE_PARAMS_LEN (8) #define NVMEM_WRITE_PARAMS_LEN (16) -/****************************************************************************** +/**************************************************************************** * Public Functions - ******************************************************************************/ -/****************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: nvmem_read * * Description: @@ -79,7 +79,7 @@ * Returned Value: * Number of bytes read, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, uint8_t *buff) @@ -120,7 +120,7 @@ signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, return ucStatus; } -/****************************************************************************** +/**************************************************************************** * Name: nvmem_write * * Description: @@ -141,7 +141,7 @@ signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, uint8_t *buff) @@ -165,7 +165,7 @@ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, args = UINT32_TO_STREAM(args, ulEntryOffset); memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + - NVMEM_WRITE_PARAMS_LEN),buff,ulLength); + NVMEM_WRITE_PARAMS_LEN), buff, ulLength); /* Initiate a HCI command but it will come on data channel */ @@ -179,7 +179,7 @@ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, return iRes; } -/****************************************************************************** +/**************************************************************************** * Name: nvmem_set_mac_address * * Description: @@ -192,14 +192,14 @@ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_set_mac_address(uint8_t *mac) { return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); } -/****************************************************************************** +/**************************************************************************** * Name: nvmem_get_mac_address * * Description: @@ -212,14 +212,14 @@ uint8_t nvmem_set_mac_address(uint8_t *mac) * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_get_mac_address(uint8_t *mac) { return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); } -/****************************************************************************** +/**************************************************************************** * Name: nvmem_write_patch * * Description: @@ -236,14 +236,14 @@ uint8_t nvmem_get_mac_address(uint8_t *mac) * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData) { - uint8_t status = 0; - uint16_t offset = 0; - uint8_t *spDataPtr = (uint8_t*)spData; + FAR uint8_t *spDataPtr = (FAR uint8_t *)spData; + uint8_t status = 0; + uint16_t offset = 0; while ((status == 0) && (spLength >= SP_PORTION_SIZE)) { @@ -253,7 +253,7 @@ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, spDataPtr += SP_PORTION_SIZE; } - if (status !=0) + if (status != 0) { /* NVMEM error occurred */ @@ -270,7 +270,7 @@ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, return status; } -/****************************************************************************** +/**************************************************************************** * Name: nvmem_read_sp_version * * Description: @@ -284,7 +284,7 @@ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER uint8_t nvmem_read_sp_version(uint8_t *patchVer) @@ -316,7 +316,7 @@ uint8_t nvmem_read_sp_version(uint8_t *patchVer) } #endif -/****************************************************************************** +/**************************************************************************** * Name: nvmem_create_entry * * Description: @@ -336,7 +336,7 @@ uint8_t nvmem_read_sp_version(uint8_t *patchVer) * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) { @@ -349,14 +349,14 @@ signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); - /*( Fill in HCI packet structure */ + /* Fill in HCI packet structure */ args = UINT32_TO_STREAM(args, ulFileId); args = UINT32_TO_STREAM(args, ulNewLen); /* Initiate a HCI command */ - hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); + hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY, ptr, NVMEM_CREATE_PARAMS_LEN); SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); diff --git a/drivers/wireless/cc3000/security.c b/drivers/wireless/cc3000/security.c deleted file mode 100644 index 990828b10eb1d31293c94c4b6618f5288ced01c6..0000000000000000000000000000000000000000 --- a/drivers/wireless/cc3000/security.c +++ /dev/null @@ -1,541 +0,0 @@ -/***************************************************************************** - * security.c - CC3000 Host Driver Implementation. - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 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. - * - * Neither the name of Texas Instruments Incorporated 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. - * - *****************************************************************************/ - -/***************************************************************************** - * Included Files - *****************************************************************************/ - -#include - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - -/***************************************************************************** - * Private Data - *****************************************************************************/ - -// foreward sbox - -const uint8_t sbox[256] = -{ -//0 1 2 3 4 5 6 7 8 9 A B C D E F -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 //F -}; - -// inverse sbox - -const uint8_t rsbox[256] = -{ - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb -, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb -, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e -, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 -, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 -, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 -, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 -, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b -, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 -, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e -, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b -, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 -, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f -, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef -, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 -, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -}; - -// round constant - -const uint8_t Rcon[11] = -{ - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 -}; - -uint8_t aexpandedKey[176]; - -/***************************************************************************** - * Public Functions - *****************************************************************************/ -//***************************************************************************** -// -//! expandKey -//! -//! @param key AES128 key - 16 bytes -//! @param expandedKey expanded AES128 key -//! -//! @return none -//! -//! @brief expend a 16 bytes key for AES128 implementation -//! -//***************************************************************************** - -void expandKey(uint8_t *expandedKey, - uint8_t *key) -{ - uint16_t ii, buf1; - - for (ii=0;ii<16;ii++) - expandedKey[ii] = key[ii]; - - for (ii=1;ii<11;ii++) - { - buf1 = expandedKey[ii*16 - 4]; - expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii]; - expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1]; - expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2]; - expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3]; - expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0]; - expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1]; - expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2]; - expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3]; - expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4]; - expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5]; - expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6]; - expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7]; - expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8]; - expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9]; - expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10]; - expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11]; - } -} - -//***************************************************************************** -// -//! galois_mul2 -//! -//! @param value argument to multiply -//! -//! @return multiplied argument -//! -//! @brief multiply by 2 in the galois field -//! -//***************************************************************************** - -uint8_t galois_mul2(uint8_t value) -{ - if (value>>7) - { - value = value << 1; - return (value^0x1b); - } else - return value<<1; -} - -//***************************************************************************** -// -//! aes_encr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in/out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief internal implementation of AES128 encryption. -//! straight forward aes encryption implementation -//! first the group of operations -//! - addRoundKey -//! - subbytes -//! - shiftrows -//! - mixcolums -//! is executed 9 times, after this addroundkey to finish the 9th -//! round, after that the 10th round without mixcolums -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles. -//! -//! -//***************************************************************************** - -void aes_encr(uint8_t *state, uint8_t *expandedKey) -{ - uint8_t buf1, buf2, buf3, round; - - for (round = 0; round < 9; round ++){ - // addroundkey, sbox and shiftrows - // row 0 - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - } - // 10th round without mixcols - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - // last addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; -} - -//***************************************************************************** -// -//! aes_decr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief internal implementation of AES128 decryption. -//! straight forward aes decryption implementation -//! the order of substeps is the exact reverse of decryption -//! inverse functions: -//! - addRoundKey is its own inverse -//! - rsbox is inverse of sbox -//! - rightshift instead of leftshift -//! - invMixColumns = barreto + mixColumns -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles -//! -//***************************************************************************** - -void aes_decr(uint8_t *state, uint8_t *expandedKey) -{ - uint8_t buf1, buf2, buf3; - int8_t round; - round = 9; - - // initial addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; - - // 10th round without mixcols - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - - for (round = 8; round >= 0; round--){ - // barreto - //col1 - buf1 = galois_mul2(galois_mul2(state[0]^state[2])); - buf2 = galois_mul2(galois_mul2(state[1]^state[3])); - state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2; - //col2 - buf1 = galois_mul2(galois_mul2(state[4]^state[6])); - buf2 = galois_mul2(galois_mul2(state[5]^state[7])); - state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2; - //col3 - buf1 = galois_mul2(galois_mul2(state[8]^state[10])); - buf2 = galois_mul2(galois_mul2(state[9]^state[11])); - state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2; - //col4 - buf1 = galois_mul2(galois_mul2(state[12]^state[14])); - buf2 = galois_mul2(galois_mul2(state[13]^state[15])); - state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2; - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - // addroundkey, rsbox and shiftrows - // row 0 - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - } - -} - -/***************************************************************************** - * Name: aes_encrypt - * - * Description: - * AES128 encryption: Given AES128 key and 16 bytes plain text, cipher - * text of 16 bytes is computed. The AES implementation is in mode ECB - * (Electronic Code Book). - * - * Input Parameters: - * key AES128 key of size 16 bytes - * state 16 bytes of plain text and cipher text - * - * Returned Value - * None - * - *****************************************************************************/ - -void aes_encrypt(uint8_t *state, uint8_t *key) -{ - // expand the key into 176 bytes - expandKey(aexpandedKey, key); - aes_encr(state, aexpandedKey); -} - -/***************************************************************************** - * Name: aes_decrypt - * - * Description: - * AES128 decryption: Given AES128 key and 16 bytes cipher text, plain - * text of 16 bytes is computed The AES implementation is in mode ECB - * (Electronic Code Book). - * - * Input Parameters: - * key AES128 key of size 16 bytes - * state 16 bytes of plain text and cipher text - * - * Returned Value - * None - * - *****************************************************************************/ - -void aes_decrypt(uint8_t *state, uint8_t *key) -{ - expandKey(aexpandedKey, key); // expand the key into 176 bytes - aes_decr(state, aexpandedKey); -} - -/***************************************************************************** - * Name: aes_read_key - * - * Description: - * Reads AES128 key from EEPROM. Reads the AES128 key from fileID #12 in - * EEPROM returns an error if the key does not exist. - * - * Input Parameters: - * key AES128 key of size 16 bytes - * - * Returned Value - * On success 0, error otherwise. - * - *****************************************************************************/ - -signed long aes_read_key(uint8_t *key) -{ - signed long returnValue; - - returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -/***************************************************************************** - * Name: aes_write_key - * - * Description: - * Writes AES128 key from EEPROM Writes the AES128 key to fileID #12 in - * EEPROM - * - * Input Parameters: - * key AES128 key of size 16 bytes - * - * Returned Value - * On success 0, error otherwise. - * - *****************************************************************************/ - -signed long aes_write_key(uint8_t *key) -{ - signed long returnValue; - - returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -#endif //CC3000_UNENCRYPTED_SMART_CONFIG diff --git a/drivers/wireless/cc3000/socket.c b/drivers/wireless/cc3000/socket.c index 87d7f4dacb5e50400ce374e602e3d6e9c1943e42..9653d06ed7b7d1792732590b0d5f7cdc34836955 100644 --- a/drivers/wireless/cc3000/socket.c +++ b/drivers/wireless/cc3000/socket.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * socket.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include @@ -54,9 +54,9 @@ #include "cc3000drv.h" #include "cc3000.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #ifndef ARRAY_SIZE # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -99,7 +99,7 @@ static const int bsd2ti_types[] = * Public Functions ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: socket * * Description: @@ -120,7 +120,7 @@ static const int bsd2ti_types[] = * On success, socket handle that is used for consequent socket * operations. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_socket(int domain, int type, int protocol) { @@ -167,7 +167,7 @@ int cc3000_socket(int domain, int type, int protocol) cc3000_lib_lock(); type = bsd2ti_types[type]; - sd = cc3000_socket_impl(domain,type,protocol); + sd = cc3000_socket_impl(domain, type, protocol); #ifdef CONFIG_CC3000_MT cc3000_add_socket(sd); #endif @@ -175,7 +175,7 @@ int cc3000_socket(int domain, int type, int protocol) return sd; } -/***************************************************************************** +/**************************************************************************** * Name: closesocket * * Description: @@ -187,7 +187,7 @@ int cc3000_socket(int domain, int type, int protocol) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_closesocket(int sockfd) { @@ -205,7 +205,7 @@ int cc3000_closesocket(int sockfd) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: accept, cc3000_do_accept * * Description: @@ -248,7 +248,7 @@ int cc3000_closesocket(int sockfd) * - On connection pending, SOC_IN_PROGRESS (-2) * - On failure, SOC_ERROR (-1) * - *****************************************************************************/ + ****************************************************************************/ int cc3000_do_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { @@ -271,12 +271,12 @@ int cc3000_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) return -errno; } - memset(addr,0,*addrlen); - return cc3000_accept_socket(sockfd,addr,addrlen); + memset(addr, 0, *addrlen); + return cc3000_accept_socket(sockfd, addr, addrlen); } #else { - cc3000_accept_socket(sockfd,0); + cc3000_accept_socket(sockfd, 0); short nonBlocking = CC3000_SOCK_OFF; if (setsockopt(sockfd, CC3000_SOL_SOCKET, CC3000_SOCKOPT_ACCEPT_NONBLOCK, @@ -286,11 +286,11 @@ int cc3000_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) return -errno; } - return cc3000_do_accept(int sockfd, addr, addrlen);; + return cc3000_do_accept(sockfd, addr, addrlen); } #endif -/***************************************************************************** +/**************************************************************************** * Name: bind * * Description: @@ -311,7 +311,7 @@ int cc3000_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen) { @@ -323,7 +323,7 @@ int cc3000_bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: listen * * Description: @@ -345,19 +345,19 @@ int cc3000_bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_listen(int sockfd, int backlog) { int ret; cc3000_lib_lock(); - ret = cc3000_listen_impl(sockfd,backlog); + ret = cc3000_listen_impl(sockfd, backlog); cc3000_lib_unlock(); return ret; } -/***************************************************************************** +/**************************************************************************** * Name: connect * * Description: @@ -385,7 +385,7 @@ int cc3000_listen(int sockfd, int backlog) * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen) { @@ -397,7 +397,7 @@ int cc3000_connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrle return ret; } -/***************************************************************************** +/**************************************************************************** * Name: select * * Description: @@ -434,10 +434,10 @@ int cc3000_connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrle * will return without delay. * *exceptfds - return the sockets which closed recently. * - *****************************************************************************/ + ****************************************************************************/ -int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, - struct timeval *timeout) +int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout) { int ret; @@ -450,7 +450,7 @@ int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, } #ifndef CC3000_TINY_DRIVER -/***************************************************************************** +/**************************************************************************** * Name: setsockopt * * Description: @@ -496,7 +496,7 @@ int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_setsockopt(int sockfd, int level, int option, FAR const void *value, socklen_t value_len) @@ -510,7 +510,7 @@ int cc3000_setsockopt(int sockfd, int level, int option, } #endif -/***************************************************************************** +/**************************************************************************** * Name: getsockopt * * Description: @@ -556,7 +556,7 @@ int cc3000_setsockopt(int sockfd, int level, int option, * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_getsockopt(int sockfd, int level, int option, FAR void *value, FAR socklen_t *value_len) @@ -569,7 +569,7 @@ int cc3000_getsockopt(int sockfd, int level, int option, FAR void *value, return ret; } -/***************************************************************************** +/**************************************************************************** * Name: recv * * Description: @@ -589,7 +589,7 @@ int cc3000_getsockopt(int sockfd, int level, int option, FAR void *value, * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t cc3000_recv(int sockfd, FAR void *buf, size_t len, int flags) { @@ -619,7 +619,7 @@ ssize_t cc3000_recv(int sockfd, FAR void *buf, size_t len, int flags) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: recvfrom * * Description: @@ -646,7 +646,7 @@ ssize_t cc3000_recv(int sockfd, FAR void *buf, size_t len, int flags) * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t cc3000_recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from, FAR socklen_t *fromlen) @@ -672,7 +672,7 @@ ssize_t cc3000_recvfrom(int sockfd, FAR void *buf, size_t len, int flags, return ret; } -/***************************************************************************** +/**************************************************************************** * Name: send * * Description: @@ -692,7 +692,7 @@ ssize_t cc3000_recvfrom(int sockfd, FAR void *buf, size_t len, int flags, * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t cc3000_send(int sockfd, FAR const void *buf, size_t len, int flags) { @@ -704,7 +704,7 @@ ssize_t cc3000_send(int sockfd, FAR const void *buf, size_t len, int flags) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: sendto * * Description: @@ -728,7 +728,7 @@ ssize_t cc3000_send(int sockfd, FAR const void *buf, size_t len, int flags) * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t cc3000_sendto(int sockfd, FAR const void *buf, size_t len, int flags, FAR const struct sockaddr *to, socklen_t tolen) @@ -741,7 +741,7 @@ ssize_t cc3000_sendto(int sockfd, FAR const void *buf, size_t len, int flags, return ret; } -/***************************************************************************** +/**************************************************************************** * Name: gethostbyname * * Description: @@ -762,11 +762,13 @@ ssize_t cc3000_sendto(int sockfd, FAR const void *buf, size_t len, int flags, * Returned Value: * On success, positive is returned. On error, negative is returned * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER -// TODO: Standard is struct hostent *gethostbyname(const char *name); -int cc3000_gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out_ip_addr) +/* REVISIT: Standard is struct hostent *gethostbyname(const char *name); */ + +int cc3000_gethostbyname(char *hostname, uint16_t usNameLen, + unsigned long *out_ip_addr) { int ret; @@ -777,7 +779,7 @@ int cc3000_gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out } #endif -/***************************************************************************** +/**************************************************************************** * Name: mdnsAdvertiser * * Description: @@ -793,7 +795,7 @@ int cc3000_gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out * On success, zero is returned, return SOC_ERROR if socket was not * opened successfully, or if an error occurred. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_mdnsadvertiser(uint16_t mdnsEnabled, char *deviceServiceName, uint16_t deviceServiceNameLength) diff --git a/drivers/wireless/cc3000/socket_imp.c b/drivers/wireless/cc3000/socket_imp.c index d52fe270d37f90d438ac6edc3d87c5fb9855de9c..780a085eb8ce8d59649233997a1ab0b49bef6f38 100644 --- a/drivers/wireless/cc3000/socket_imp.c +++ b/drivers/wireless/cc3000/socket_imp.c @@ -33,11 +33,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include @@ -51,9 +51,9 @@ #include #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* Enable this flag if and only if you must comply with BSD socket close() * function @@ -101,10 +101,10 @@ #define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ -/***************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: HostFlowControlConsumeBuff * * Input Parameters: @@ -121,7 +121,7 @@ * becomes available, else return immediately with correct status * regarding the buffers available. * - *****************************************************************************/ + ****************************************************************************/ int HostFlowControlConsumeBuff(int sd) { @@ -197,7 +197,7 @@ int HostFlowControlConsumeBuff(int sd) #endif } -/***************************************************************************** +/**************************************************************************** * Name: socket * * Decription: @@ -218,7 +218,7 @@ int HostFlowControlConsumeBuff(int sd) * On success, socket handle that is used for consequent socket * operations. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_socket_impl(long domain, long type, long protocol) { @@ -250,7 +250,7 @@ int cc3000_socket_impl(long domain, long type, long protocol) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: closesocket * * Decription: @@ -262,7 +262,7 @@ int cc3000_socket_impl(long domain, long type, long protocol) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_closesocket_impl(long sd) { @@ -296,7 +296,7 @@ long cc3000_closesocket_impl(long sd) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: accept * * Decription: @@ -339,7 +339,7 @@ long cc3000_closesocket_impl(long sd) * - On connection pending, SOC_IN_PROGRESS (-2) * - On failure, SOC_ERROR (-1) * - *****************************************************************************/ + ****************************************************************************/ long cc3000_accept_impl(long sd, struct sockaddr *addr, socklen_t *addrlen) { @@ -385,7 +385,7 @@ long cc3000_accept_impl(long sd, struct sockaddr *addr, socklen_t *addrlen) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: bind * * Decription: @@ -406,7 +406,7 @@ long cc3000_accept_impl(long sd, struct sockaddr *addr, socklen_t *addrlen) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_bind_impl(long sd, const struct sockaddr *addr, socklen_t addrlen) { @@ -439,7 +439,7 @@ long cc3000_bind_impl(long sd, const struct sockaddr *addr, socklen_t addrlen) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: listen * * Decription: @@ -461,7 +461,7 @@ long cc3000_bind_impl(long sd, const struct sockaddr *addr, socklen_t addrlen) * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ long cc3000_listen_impl(long sd, long backlog) { @@ -490,7 +490,7 @@ long cc3000_listen_impl(long sd, long backlog) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: gethostbyname * * Decription: @@ -511,10 +511,11 @@ long cc3000_listen_impl(long sd, long backlog) * Returned Value: * On success, positive is returned. On error, negative is returned * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER -int cc3000_gethostbyname_impl(char * hostname, uint16_t usNameLen, unsigned long* out_ip_addr) +int cc3000_gethostbyname_impl(char *hostname, uint16_t usNameLen, + unsigned long *out_ip_addr) { tBsdGethostbynameParams ret; uint8_t *ptr, *args; @@ -546,13 +547,13 @@ int cc3000_gethostbyname_impl(char * hostname, uint16_t usNameLen, unsigned long set_errno(ret.retVal); - (*((long*)out_ip_addr)) = ret.outputAddress; + (*((FAR long *)out_ip_addr)) = ret.outputAddress; return ret.retVal; } #endif -/***************************************************************************** +/**************************************************************************** * Name: connect * * Decription: @@ -580,7 +581,7 @@ int cc3000_gethostbyname_impl(char * hostname, uint16_t usNameLen, unsigned long * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ long cc3000_connect_impl(long sd, const struct sockaddr *addr, socklen_t addrlen) { @@ -612,7 +613,7 @@ long cc3000_connect_impl(long sd, const struct sockaddr *addr, socklen_t addrlen return (long)ret; } -/***************************************************************************** +/**************************************************************************** * Name: select * * Decription: @@ -649,7 +650,7 @@ long cc3000_connect_impl(long sd, const struct sockaddr *addr, socklen_t addrlen * will return without delay. * *exceptsds - return the sockets which closed recently. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_select_impl(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds, struct timeval *timeout) @@ -680,9 +681,9 @@ int cc3000_select_impl(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *write args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, is_blocking); - args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); - args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); - args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); + args = UINT32_TO_STREAM(args, ((readsds) ? *(FAR unsigned long *)readsds : 0)); + args = UINT32_TO_STREAM(args, ((writesds) ? *(FAR unsigned long *)writesds : 0)); + args = UINT32_TO_STREAM(args, ((exceptsds) ? *(FAR unsigned long *)exceptsds : 0)); if (timeout) { @@ -732,7 +733,7 @@ int cc3000_select_impl(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *write } } -/***************************************************************************** +/**************************************************************************** * Name: setsockopt * * Decription: @@ -778,7 +779,7 @@ int cc3000_select_impl(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *write * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER int cc3000_setsockopt_impl(long sd, long level, long optname, const void *optval, socklen_t optlen) @@ -819,7 +820,7 @@ int cc3000_setsockopt_impl(long sd, long level, long optname, const void *optval } #endif -/***************************************************************************** +/**************************************************************************** * Name: getsockopt * * Decription: @@ -865,7 +866,7 @@ int cc3000_setsockopt_impl(long sd, long level, long optname, const void *optval * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int cc3000_getsockopt_impl(long sd, long level, long optname, void *optval, socklen_t *optlen) { @@ -903,7 +904,7 @@ int cc3000_getsockopt_impl(long sd, long level, long optname, void *optval, sock } } -/***************************************************************************** +/**************************************************************************** * Name: simple_link_recv * * Input Parameters: @@ -925,7 +926,7 @@ int cc3000_getsockopt_impl(long sd, long level, long optname, void *optval, sock * excess bytes may be discarded depending on the type of * socket the message is received from * - *****************************************************************************/ + ****************************************************************************/ int simple_link_recv(long sd, void *buf, long len, long flags, struct sockaddr *from, socklen_t *fromlen, long opcode) @@ -965,7 +966,7 @@ int simple_link_recv(long sd, void *buf, long len, long flags, struct sockaddr * return tSocketReadEvent.iNumberOfBytes; } -/***************************************************************************** +/**************************************************************************** * Name: recv * * Decription: @@ -985,14 +986,14 @@ int simple_link_recv(long sd, void *buf, long len, long flags, struct sockaddr * * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_recv_impl(long sd, void *buf, long len, long flags) { return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); } -/***************************************************************************** +/**************************************************************************** * Name: recvfrom * * Decription: @@ -1019,7 +1020,7 @@ int cc3000_recv_impl(long sd, void *buf, long len, long flags) * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_recvfrom_impl(long sd, void *buf, long len, long flags, struct sockaddr *from, socklen_t *fromlen) @@ -1028,7 +1029,7 @@ int cc3000_recvfrom_impl(long sd, void *buf, long len, long flags, struct sockad HCI_CMND_RECVFROM)); } -/***************************************************************************** +/**************************************************************************** * Name: simple_link_send * * Input Parameters: @@ -1049,7 +1050,7 @@ int cc3000_recvfrom_impl(long sd, void *buf, long len, long flags, struct sockad * This function is used to transmit a message to another * socket * - *****************************************************************************/ + ****************************************************************************/ int simple_link_send(long sd, const void *buf, long len, long flags, const struct sockaddr *to, long tolen, long opcode) @@ -1078,7 +1079,7 @@ int simple_link_send(long sd, const void *buf, long len, long flags, /* Update the offset of data and parameters according to the command */ - switch(opcode) + switch (opcode) { case HCI_CMND_SENDTO: { @@ -1119,18 +1120,18 @@ int simple_link_send(long sd, const void *buf, long len, long flags, /* Copy the data received from user into the TX Buffer */ - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); + ARRAY_TO_STREAM(pDataPtr, ((FAR uint8_t *)buf), len); /* In case we are using SendTo, copy the to parameters */ if (opcode == HCI_CMND_SENDTO) { - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); + ARRAY_TO_STREAM(pDataPtr, ((FAR uint8_t *)to), tolen); } /* Initiate a HCI command */ - hci_data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); + hci_data_send(opcode, ptr, uArgSize, len, (FAR uint8_t *)to, tolen); if (opcode == HCI_CMND_SENDTO) { @@ -1144,7 +1145,7 @@ int simple_link_send(long sd, const void *buf, long len, long flags, return len; } -/***************************************************************************** +/**************************************************************************** * Name: send * * Decription: @@ -1164,14 +1165,14 @@ int simple_link_send(long sd, const void *buf, long len, long flags, * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_send_impl(long sd, const void *buf, long len, long flags) { return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); } -/***************************************************************************** +/**************************************************************************** * Name: sendto * * Decription: @@ -1195,7 +1196,7 @@ int cc3000_send_impl(long sd, const void *buf, long len, long flags) * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ int cc3000_sendto_impl(long sd, const void *buf, long len, long flags, const struct sockaddr *to, socklen_t tolen) @@ -1203,7 +1204,7 @@ int cc3000_sendto_impl(long sd, const void *buf, long len, long flags, const str return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); } -/***************************************************************************** +/**************************************************************************** * Name: mdnsAdvertiser * * Decription: @@ -1219,7 +1220,7 @@ int cc3000_sendto_impl(long sd, const void *buf, long len, long flags, const str * On success, zero is returned, return SOC_ERROR if socket was not * opened successfully, or if an error occurred. * - *****************************************************************************/ + ****************************************************************************/ int cc3000_mdnsadvertiser_impl(uint16_t mdnsEnabled, char * deviceServiceName, uint16_t deviceServiceNameLength) diff --git a/drivers/wireless/cc3000/spi_version.h b/drivers/wireless/cc3000/spi_version.h index 0ca1516f99514cda7a1f32d10ab5713cc5bc504c..607988fb0e9826afe3e8f01779b57f008e990ea5 100644 --- a/drivers/wireless/cc3000/spi_version.h +++ b/drivers/wireless/cc3000/spi_version.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * * spi_version.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ diff --git a/drivers/wireless/cc3000/wlan.c b/drivers/wireless/cc3000/wlan.c index e84fd8954f0c8e1503ed8e7613eb9ae2f31fd650..175d6334b4dc4429767ce93c782019edcf9c3d6e 100644 --- a/drivers/wireless/cc3000/wlan.c +++ b/drivers/wireless/cc3000/wlan.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * wlan.c - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,11 +30,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include @@ -43,19 +43,20 @@ #include #include +#include + #include #include #include #include -#include #include #include "cc3000.h" #include "cc3000drv.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define SMART_CONFIG_PROFILE_SIZE 67 /* 67 = 32 (max ssid) + 32 (max key) + * 1 (SSID length) + 1 (security type) + @@ -99,12 +100,12 @@ #define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ volatile sSimplLinkInformation tSLInformation; #ifndef CC3000_UNENCRYPTED_SMART_CONFIG @@ -112,10 +113,10 @@ uint8_t akey[AES128_KEY_SIZE]; uint8_t profileArray[SMART_CONFIG_PROFILE_SIZE]; #endif /* CC3000_UNENCRYPTED_SMART_CONFIG */ -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ -/***************************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: SimpleLink_Init_Start * * Input Parameters: @@ -132,7 +133,7 @@ uint8_t profileArray[SMART_CONFIG_PROFILE_SIZE]; * Description: * Send HCI_CMND_SIMPLE_LINK_START to CC3000 * - *****************************************************************************/ + ****************************************************************************/ static void SimpleLink_Init_Start(uint16_t usPatchesAvailableAtHost) { @@ -157,7 +158,7 @@ static void SimpleLink_Init_Start(uint16_t usPatchesAvailableAtHost) SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); } -/***************************************************************************** +/**************************************************************************** * Name: wlan_init * * Input Parameters: @@ -193,7 +194,7 @@ static void SimpleLink_Init_Start(uint16_t usPatchesAvailableAtHost) * * WARNING: This function must be called before ANY other wlan driver function * - *****************************************************************************/ + ****************************************************************************/ void wlan_init(size_t max_tx_len, tWlanCB sWlanCB, @@ -222,7 +223,7 @@ void wlan_init(size_t max_tx_len, /* Init I/O callback */ /* Init asynchronous events callback */ - tSLInformation.sWlanCB= sWlanCB; + tSLInformation.sWlanCB = sWlanCB; /* By default TX Complete events are routed to host too */ @@ -235,7 +236,7 @@ void wlan_init(size_t max_tx_len, } } -/***************************************************************************** +/**************************************************************************** * Name: SpiReceiveHandler * * Input Parameters: @@ -248,7 +249,7 @@ void wlan_init(size_t max_tx_len, * The function triggers Received event/data processing. It is * called from the SPI library to receive the data * - *****************************************************************************/ + ****************************************************************************/ void SpiReceiveHandler(void *pvBuffer) { @@ -266,7 +267,7 @@ void SpiReceiveHandler(void *pvBuffer) hci_unsolicited_event_handler(); } -/***************************************************************************** +/**************************************************************************** * Name: wlan_start * * Input Parameters: @@ -291,7 +292,7 @@ void SpiReceiveHandler(void *pvBuffer) * WARNING: This function must be called after wlan_init and before any * other wlan API * - *****************************************************************************/ + ****************************************************************************/ void wlan_start(uint16_t usPatchesAvailableAtHost) { @@ -321,7 +322,7 @@ void wlan_start(uint16_t usPatchesAvailableAtHost) cc3000_lib_unlock(); } -/***************************************************************************** +/**************************************************************************** * Name: wlan_get_buffer * * Input Parameters: @@ -330,14 +331,14 @@ void wlan_start(uint16_t usPatchesAvailableAtHost) * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void wlan_get_buffer(wlan_buffer_desc *pdes) { *pdes = tSLInformation.usrBuffer; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_stop * * Input Parameters: @@ -349,7 +350,7 @@ void wlan_get_buffer(wlan_buffer_desc *pdes) * Description: * Stop WLAN device by putting it into reset state. * - *****************************************************************************/ + ****************************************************************************/ void wlan_stop(void) { @@ -358,7 +359,7 @@ void wlan_stop(void) cc3000_lib_unlock(); } -/***************************************************************************** +/**************************************************************************** * Name: wlan_connect * * Input Parameters: @@ -388,11 +389,12 @@ void wlan_stop(void) * type WEP, please confirm that the key is set as ASCII and not * as HEX. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, - uint8_t *bssid, uint8_t *key, long key_len) +long wlan_connect(unsigned long ulSecType, FAR const char *ssid, + long ssid_len, FAR const uint8_t *bssid, + FAR const uint8_t *key, long key_len) { long ret; uint8_t *ptr; @@ -445,7 +447,7 @@ long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, return ret; } #else -long wlan_connect(char *ssid, long ssid_len) +long wlan_connect(FAR const char *ssid, long ssid_len) { long ret; uint8_t *ptr; @@ -488,7 +490,7 @@ long wlan_connect(char *ssid, long ssid_len) } #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_disconnect * * Input Parameters: @@ -500,7 +502,7 @@ long wlan_connect(char *ssid, long ssid_len) * Description: * Disconnect connection from AP. * - *****************************************************************************/ + ****************************************************************************/ long wlan_disconnect(void) { @@ -524,7 +526,7 @@ long wlan_disconnect(void) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_set_connection_policy * * Input Parameters: @@ -554,7 +556,7 @@ long wlan_disconnect(void) * enabled, the device will try to connect to any AP. * * Note that the policy settings are stored in the CC3000 NVMEM. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, @@ -589,7 +591,7 @@ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_add_profile * * Input Parameters: @@ -615,15 +617,15 @@ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, * profile based on security policy, signal strength, etc * parameters. All the profiles are stored in CC3000 NVMEM. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, +long wlan_add_profile(unsigned long ulSecType, uint8_t *ucSsid, unsigned long ulSsidLen, uint8_t *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, - unsigned long ulKeyMgmt, uint8_t* ucPf_OrKey, + unsigned long ulKeyMgmt, uint8_t *ucPf_OrKey, unsigned long ulPassPhraseLen) { uint16_t arg_len = 0; @@ -701,7 +703,7 @@ long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, } break; - /*WPA, WPA2 */ + /* WPA, WPA2 */ case WLAN_SEC_WPA: case WLAN_SEC_WPA2: @@ -755,7 +757,7 @@ long wlan_add_profile(unsigned long ulSecType, uint8_t * ucSsid, uint8_t ulSsidL } #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_del_profile * * Input Parameters: @@ -769,7 +771,7 @@ long wlan_add_profile(unsigned long ulSecType, uint8_t * ucSsid, uint8_t ulSsidL * * @Note In order to delete all stored profile, set index to 255. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_del_profile(unsigned long ulIndex) { @@ -801,7 +803,7 @@ long wlan_ioctl_del_profile(unsigned long ulIndex) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_get_scan_results * * Input Parameters: @@ -832,7 +834,7 @@ long wlan_ioctl_del_profile(unsigned long ulIndex) * * NOTE: scan_timeout, is not supported on this version. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults) @@ -864,7 +866,7 @@ long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults } #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_set_scan_params * * Input Parameters: @@ -899,14 +901,15 @@ long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults * * @Note uiDefaultTxPower, is not supported on this version. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime, unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests, - unsigned long uiChannelMask,long iRSSIThreshold, + unsigned long uiChannelMask, + long iRSSIThreshold, unsigned long uiSNRThreshold, unsigned long uiDefaultTxPower, unsigned long *aiIntervalList) @@ -949,7 +952,7 @@ long wlan_ioctl_set_scan_params(unsigned long uiEnable, } #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_set_event_mask * * Input Parameters: @@ -971,7 +974,7 @@ long wlan_ioctl_set_scan_params(unsigned long uiEnable, * Mask event according to bit mask. In case that event is * masked (1), the device will not send the masked event to host. * - *****************************************************************************/ + ****************************************************************************/ long wlan_set_event_mask(unsigned long ulMask) { @@ -1024,7 +1027,7 @@ long wlan_set_event_mask(unsigned long ulMask) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_statusget * * Input Parameters: @@ -1037,7 +1040,7 @@ long wlan_set_event_mask(unsigned long ulMask) * Description: * get wlan status: disconnected, scanning, connecting or connected * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long wlan_ioctl_statusget(void) @@ -1063,7 +1066,7 @@ long wlan_ioctl_statusget(void) } #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_start * * Input Parameters: @@ -1082,7 +1085,7 @@ long wlan_ioctl_statusget(void) * @Note An asynchronous event - Smart Config Done will be generated as soon * as the process finishes successfully. * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_start(unsigned long algoEncryptedFlag) { @@ -1111,7 +1114,7 @@ long wlan_smart_config_start(unsigned long algoEncryptedFlag) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_stop * * Input Parameters: @@ -1123,7 +1126,7 @@ long wlan_smart_config_start(unsigned long algoEncryptedFlag) * Description: * Stop the acquire profile procedure * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_stop(void) { @@ -1145,7 +1148,7 @@ long wlan_smart_config_stop(void) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_set_prefix * * Input Parameters: @@ -1160,9 +1163,9 @@ long wlan_smart_config_stop(void) * * @Note The prefix is stored in CC3000 NVMEM * - *****************************************************************************/ + ****************************************************************************/ -long wlan_smart_config_set_prefix(char* cNewPrefix) +long wlan_smart_config_set_prefix(FAR char *cNewPrefix) { long ret; uint8_t *ptr; @@ -1202,7 +1205,59 @@ long wlan_smart_config_set_prefix(char* cNewPrefix) return ret; } -/***************************************************************************** +/**************************************************************************** + * Name: aes_read_key + * + * Description: + * Reads AES128 key from EEPROM. Reads the AES128 key from fileID #12 in + * EEPROM returns an error if the key does not exist. + * + * Input Parameters: + * key AES128 key of size 16 bytes + * + * Returned Value + * On success 0, error otherwise. + * + ****************************************************************************/ + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +signed long aes_read_key(uint8_t *key) +{ + signed long returnValue; + + returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); + + return returnValue; +} +#endif + +/**************************************************************************** + * Name: aes_write_key + * + * Description: + * Writes AES128 key from EEPROM Writes the AES128 key to fileID #12 in + * EEPROM + * + * Input Parameters: + * key AES128 key of size 16 bytes + * + * Returned Value + * On success 0, error otherwise. + * + ****************************************************************************/ + +#if 0 //#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +signed long aes_write_key(uint8_t *key) +{ + signed long returnValue; + + returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); + + return returnValue; +} +#endif + +/**************************************************************************** * Name: wlan_smart_config_process * * Input Parameters: @@ -1217,7 +1272,7 @@ long wlan_smart_config_set_prefix(char* cNewPrefix) * The encrypted data is decrypted and stored as a profile. * behavior is as defined by connection policy. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_UNENCRYPTED_SMART_CONFIG long wlan_smart_config_process() diff --git a/drivers/wireless/ieee802154/Kconfig b/drivers/wireless/ieee802154/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..93e802323df6051e8c1364a24cdad0396d61f357 --- /dev/null +++ b/drivers/wireless/ieee802154/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if DRIVERS_IEEE802154 + +config IEEE802154_MRF24J40 + bool "Microchip MRF24J40 IEEE 802.15.4 transceiver" + default n + ---help--- + This selection enables support for the Microchip MRF24J40 device. + +endif # DRIVERS_IEEE802154 diff --git a/drivers/wireless/ieee802154/Make.defs b/drivers/wireless/ieee802154/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..b0a1406baa41689c2409263c85cd86684a60ff7c --- /dev/null +++ b/drivers/wireless/ieee802154/Make.defs @@ -0,0 +1,54 @@ +############################################################################ +# drivers/ieee802154/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Include nothing if IEEE 802.15.4 is disabled + +ifeq ($(CONFIG_DRIVERS_IEEE802154),y) + +# Include common IEEE 802.15.4 files into the build + +# Include IEEE 802.15.4 drivers into the build + +ifeq ($(CONFIG_IEEE802154_MRF24J40),y) + CSRCS += mrf24j40.c +endif + +# Include IEEE 802.15.4 build support + +DEPPATH += --dep-path wireless$(DELIM)ieee802154 +VPATH += :wireless$(DELIM)ieee802154 +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154} + +endif # CONFIG_DRIVERS_IEEE802154 diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c new file mode 100644 index 0000000000000000000000000000000000000000..fa7cfd815d3c5daf01c6375cd27e88f0f8738a30 --- /dev/null +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -0,0 +1,1402 @@ +/**************************************************************************** + * drivers/wireless/ieee802154/mrf24j40.c + * + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "mrf24j40.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_SCHED_HPWORK +#error High priority work queue required in this driver +#endif + +#ifndef CONFIG_IEEE802154_MRF24J40_SPIMODE +# define CONFIG_IEEE802154_MRF24J40_SPIMODE SPIDEV_MODE0 +#endif + +#ifndef CONFIG_IEEE802154_MRF24J40_FREQUENCY +# define CONFIG_IEEE802154_MRF24J40_FREQUENCY 8000000 +#endif + +#ifndef CONFIG_SPI_EXCHANGE +# error CONFIG_SPI_EXCHANGE required for this driver +#endif + +/* Definitions for the device structure */ + +#define MRF24J40_RXMODE_NORMAL 0 +#define MRF24J40_RXMODE_PROMISC 1 +#define MRF24J40_RXMODE_NOCRC 2 + +/* Definitions for PA control on high power modules */ + +#define MRF24J40_PA_AUTO 1 +#define MRF24J40_PA_ED 2 +#define MRF24J40_PA_SLEEP 3 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A MRF24J40 device instance */ + +struct mrf24j40_dev_s +{ + struct ieee802154_dev_s ieee; /* The public device instance */ + FAR struct spi_dev_s *spi; /* Saved SPI interface instance */ + struct work_s irqwork; /* Interrupt continuation work queue support */ + FAR const struct mrf24j40_lower_s *lower; /* Low-level MCU-specific support */ + + uint16_t panid; /* PAN identifier, FFFF = not set */ + uint16_t saddr; /* short address, FFFF = not set */ + uint8_t eaddr[8]; /* extended address, FFFFFFFFFFFFFFFF = not set */ + uint8_t channel; /* 11 to 26 for the 2.4 GHz band */ + uint8_t devmode; /* device mode: device, coord, pancoord */ + uint8_t paenabled; /* enable usage of PA */ + uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */ + int32_t txpower; /* TX power in mBm = dBm/100 */ + struct ieee802154_cca_s cca; /* Clear channel assessement method */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Internal operations */ + +static void mrf24j40_lock (FAR struct spi_dev_s *spi); + +static void mrf24j40_setreg (FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val); +static uint8_t mrf24j40_getreg (FAR struct spi_dev_s *spi, uint32_t addr); + +static int mrf24j40_resetrfsm (FAR struct mrf24j40_dev_s *dev); +static int mrf24j40_pacontrol (FAR struct mrf24j40_dev_s *dev, int mode); +static int mrf24j40_initialize(FAR struct mrf24j40_dev_s *dev); + +static int mrf24j40_setrxmode (FAR struct mrf24j40_dev_s *dev, int mode); +static int mrf24j40_regdump (FAR struct mrf24j40_dev_s *dev); +static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev); +static void mrf24j40_irqwork_tx(FAR struct mrf24j40_dev_s *dev); +static void mrf24j40_irqworker (FAR void *arg); +static int mrf24j40_interrupt (int irq, FAR void *context); + +/* Driver operations */ + +static int mrf24j40_setchannel (FAR struct ieee802154_dev_s *ieee, uint8_t chan); +static int mrf24j40_getchannel (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *chan); +static int mrf24j40_setpanid (FAR struct ieee802154_dev_s *ieee, uint16_t panid); +static int mrf24j40_getpanid (FAR struct ieee802154_dev_s *ieee, FAR uint16_t *panid); +static int mrf24j40_setsaddr (FAR struct ieee802154_dev_s *ieee, uint16_t saddr); +static int mrf24j40_getsaddr (FAR struct ieee802154_dev_s *ieee, FAR uint16_t *saddr); +static int mrf24j40_seteaddr (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *eaddr); +static int mrf24j40_geteaddr (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *eaddr); +static int mrf24j40_setpromisc (FAR struct ieee802154_dev_s *ieee, bool promisc); +static int mrf24j40_getpromisc (FAR struct ieee802154_dev_s *ieee, FAR bool *promisc); +static int mrf24j40_setdevmode (FAR struct ieee802154_dev_s *ieee, uint8_t mode); +static int mrf24j40_getdevmode (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *mode); +static int mrf24j40_settxpower (FAR struct ieee802154_dev_s *ieee, int32_t txpwr); +static int mrf24j40_gettxpower (FAR struct ieee802154_dev_s *ieee, FAR int32_t *txpwr); +static int mrf24j40_setcca (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_cca_s *cca); +static int mrf24j40_getcca (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_cca_s *cca); +static int mrf24j40_ioctl (FAR struct ieee802154_dev_s *ieee, int cmd, unsigned long arg); +static int mrf24j40_energydetect(FAR struct ieee802154_dev_s *ieee, FAR uint8_t *energy); +static int mrf24j40_rxenable (FAR struct ieee802154_dev_s *ieee, bool state, FAR struct ieee802154_packet_s *packet); +static int mrf24j40_transmit (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_packet_s *packet); + +/* These are pointers to ALL registered MRF24J40 devices. + * This table is used during irqs to find the context + * Only one device is supported for now. + * More devices can be supported in the future by lookup them up + * using the IRQ number. See the ENC28J60 or CC3000 drivers for reference. + */ + +static struct mrf24j40_dev_s g_mrf24j40_devices[1]; + +static const struct ieee802154_devops_s mrf24j40_devops = +{ + mrf24j40_setchannel, mrf24j40_getchannel, + mrf24j40_setpanid , mrf24j40_getpanid, + mrf24j40_setsaddr , mrf24j40_getsaddr, + mrf24j40_seteaddr , mrf24j40_geteaddr, + mrf24j40_setpromisc, mrf24j40_getpromisc, + mrf24j40_setdevmode, mrf24j40_getdevmode, + mrf24j40_settxpower, mrf24j40_gettxpower, + mrf24j40_setcca , mrf24j40_getcca, + mrf24j40_ioctl, + mrf24j40_energydetect, + mrf24j40_rxenable, + mrf24j40_transmit +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Hardware access routines */ + +/**************************************************************************** + * Name: mrf24j40_lock + * + * Description: + * Acquire exclusive access to the shared SPI bus. + * + ****************************************************************************/ + +static void mrf24j40_lock(FAR struct spi_dev_s *spi) +{ + SPI_LOCK (spi, 1); + SPI_SETBITS (spi, 8); + SPI_SETMODE (spi, CONFIG_IEEE802154_MRF24J40_SPIMODE); + SPI_SETFREQUENCY(spi, CONFIG_IEEE802154_MRF24J40_FREQUENCY); +} + +/**************************************************************************** + * Name: mrf24j40_unlock + * + * Description: + * Release exclusive access to the shared SPI bus. + * + ****************************************************************************/ + +static inline void mrf24j40_unlock(FAR struct spi_dev_s *spi) +{ + SPI_LOCK(spi,0); +} + +/**************************************************************************** + * Name: mrf24j40_setreg + * + * Description: + * Define the value of an MRF24J40 device register + * + ****************************************************************************/ + +static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val) +{ + uint8_t buf[3]; + int len; + + if (!(addr&0x80000000)) + { + addr &= 0x3F; /* 6-bit address */ + addr <<= 1; + addr |= 0x01; /* writing */ + buf[0] = addr; + len = 1; + } + else + { + addr &= 0x3FF; /* 10-bit address */ + addr <<= 5; + addr |= 0x8010; /* writing long */ + buf[0] = (addr >> 8); + buf[1] = (addr & 0xFF); + len = 2; + } + + buf[len++] = val; + + mrf24j40_lock(spi); + SPI_SELECT(spi, SPIDEV_IEEE802154, true); + SPI_SNDBLOCK(spi, buf, len); + SPI_SELECT(spi, SPIDEV_IEEE802154, false); + mrf24j40_unlock(spi); +} + +/**************************************************************************** + * Name: mrf24j40_getreg + * + * Description: + * Return the value of an MRF24J40 device register + * + ****************************************************************************/ + +static uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr) +{ + uint8_t buf[3]; + uint8_t rx[3]; + int len; + + if (!(addr&0x80000000)) + { + /* 6-bit address */ + + addr &= 0x3F; + addr <<= 1; + buf[0] = addr; + len = 1; + } + else + { + /* 10-bit address */ + + addr &= 0x3FF; + addr <<= 5; + addr |= 0x8000; + buf[0] = (addr >> 8); + buf[1] = (addr & 0xFF); + len = 2; + } + + buf[len++] = 0xFF; /* dummy */ + + mrf24j40_lock (spi); + SPI_SELECT (spi, SPIDEV_IEEE802154, true); + SPI_EXCHANGE (spi, buf, rx, len); + SPI_SELECT (spi, SPIDEV_IEEE802154, false); + mrf24j40_unlock(spi); + + /*dbg("r[%04X]=%02X\n",addr,rx[len-1]);*/ + return rx[len-1]; +} + +/**************************************************************************** + * Name: mrf24j40_resetrfsm + * + * Description: + * Reset the RF state machine. Required at boot, after channel change, + * and probably after PA settings. + * + ****************************************************************************/ + +static int mrf24j40_resetrfsm(FAR struct mrf24j40_dev_s *dev) +{ + uint8_t reg; + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RFCTL); + reg |= 0x04; + mrf24j40_setreg(dev->spi, MRF24J40_RFCTL, reg); + + reg &= ~0x04; + mrf24j40_setreg(dev->spi, MRF24J40_RFCTL, reg); + up_udelay(200); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_pacontrol + * + * Description: + * Control the external LNA/PA on the MRF24J40MB/MC/MD/ME modules + * GPIO 1: PA enable + * GPIO 2: LNA enable + * GPIO 3: PA power enable (not required on MB) + ****************************************************************************/ + +static int mrf24j40_pacontrol(FAR struct mrf24j40_dev_s *dev, int mode) +{ + if (!dev->paenabled) + { + return OK; + } + + if (mode == MRF24J40_PA_AUTO) + { + mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x08); + mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x08); + mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x0F); + } + else if (mode == MRF24J40_PA_ED) + { + mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x08); + mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x0F); + mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x0C); + } + else if (mode == MRF24J40_PA_SLEEP) + { + mrf24j40_setreg(dev->spi, MRF24J40_TESTMODE, 0x08); + mrf24j40_setreg(dev->spi, MRF24J40_TRISGPIO, 0x0F); + mrf24j40_setreg(dev->spi, MRF24J40_GPIO , 0x00); + } + else + { + return -EINVAL; + } + + mrf24j40_resetrfsm(dev); + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_initialize + * + * Description: + * Reset the device and put in in order of operation + * + ****************************************************************************/ + +static int mrf24j40_initialize(FAR struct mrf24j40_dev_s *dev) +{ + /* Software reset */ + + mrf24j40_setreg(dev->spi, MRF24J40_SOFTRST , 0x07); /* 00000111 Reset */ + while(mrf24j40_getreg(dev->spi, MRF24J40_SOFTRST) & 0x07); + + /* Apply recommended settings */ + + mrf24j40_setreg(dev->spi, MRF24J40_PACON2 , 0x98); /* 10011000 Enable FIFO (default), TXONTS=6 (recommended), TXONT<8:7>=0 */ + mrf24j40_setreg(dev->spi, MRF24J40_TXSTBL , 0x95); /* 10010101 set the SIFS period. RFSTBL=9, MSIFS=5, aMinSIFSPeriod=14 (min 12) */ + mrf24j40_setreg(dev->spi, MRF24J40_TXPEND , 0x7C); /* 01111100 set the LIFS period, MLIFS=1Fh=31 aMinLIFSPeriod=40 (min 40) */ + mrf24j40_setreg(dev->spi, MRF24J40_TXTIME , 0x30); /* 00110000 set the turnaround time, TURNTIME=3 aTurnAroundTime=12 */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON1 , 0x02); /* 00000010 VCO optimization, recommended value */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON2 , 0x80); /* 10000000 Enable PLL */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON6 , 0x90); /* 10010000 TX filter enable, fast 20M recovery, No bat monitor*/ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON7 , 0x80); /* 10000000 Sleep clock on internal 100 kHz */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON8 , 0x10); /* 00010000 VCO control bit, as recommended */ + mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); /* 00000001 no CLKOUT, default divisor */ + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6 , 0x40); /* 01000000 Append RSSI to rx packets */ + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setrxmode + * + * Description: + * Set the RX mode (normal, promiscuous, no CRC) + * + ****************************************************************************/ + +static int mrf24j40_setrxmode(FAR struct mrf24j40_dev_s *dev, int mode) +{ + uint8_t reg; + if (mode < MRF24J40_RXMODE_NORMAL || mode > MRF24J40_RXMODE_NOCRC) + { + return -EINVAL; + } + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR); + reg &= ~0x03; + reg |= mode; + + /* Set mode options */ + + if (mode != MRF24J40_RXMODE_NORMAL) + { + /* Promisc and error modes: Disable auto ACK */ + reg |= MRF24J40_RXMCR_NOACKRSP; + } + else + { + /* Normal mode : enable auto-ACK */ + reg &= ~MRF24J40_RXMCR_NOACKRSP; + } + + mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg); + + dev->rxmode = mode; + dbg("%u\n",(unsigned)mode); + return OK; +} + +/* Publicized driver routines */ + +/**************************************************************************** + * Name: mrf24j40_setchannel + * + * Description: + * Define the current radio channel the device is operating on. + * In the 2.4 GHz, there are 16 channels, each 2 MHz wide, 5 MHz spacing: + * Chan MHz Chan MHz Chan MHz Chan MHz + * 11 2405 15 2425 19 2445 23 2465 + * 12 2410 16 2430 20 2450 24 2470 + * 13 2415 17 2435 21 2455 25 2475 + * 14 2420 18 2440 22 2460 26 2480 + * + ****************************************************************************/ + +static int mrf24j40_setchannel(FAR struct ieee802154_dev_s *ieee, + uint8_t chan) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + if (chan<11 || chan>26) + { + dbg("Invalid chan: %d\n",chan); + return -EINVAL; + } + + /* 15. Set channel – See Section 3.4 “Channel Selection”. */ + + mrf24j40_setreg(dev->spi, MRF24J40_RFCON0, (chan - 11) << 4 | 0x03); + + /* 17. RFCTL (0x36) = 0x04 – Reset RF state machine. + * 18. RFCTL (0x36) = 0x00. + */ + + mrf24j40_resetrfsm(dev); + + dev->channel = chan; + //dbg("%u\n",(unsigned)chan); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_getchannel + * + * Description: + * Define the current radio channel the device is operating on. + * + ****************************************************************************/ + +static int mrf24j40_getchannel(FAR struct ieee802154_dev_s *ieee, + FAR uint8_t *chan) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *chan = dev->channel; + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setpanid + * + * Description: + * Define the PAN ID the device is operating on. + * + ****************************************************************************/ + +static int mrf24j40_setpanid(FAR struct ieee802154_dev_s *ieee, + uint16_t panid) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + mrf24j40_setreg(dev->spi, MRF24J40_PANIDH, (uint8_t)(panid>>8)); + mrf24j40_setreg(dev->spi, MRF24J40_PANIDL, (uint8_t)(panid&0xFF)); + + dev->panid = panid; + dbg("%04X\n",(unsigned)panid); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_getpanid + * + * Description: + * Define the current PAN ID the device is operating on. + * + ****************************************************************************/ + +static int mrf24j40_getpanid(FAR struct ieee802154_dev_s *ieee, + FAR uint16_t *panid) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *panid = dev->panid; + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setsaddr + * + * Description: + * Define the device short address. The following addresses are special: + * FFFEh : Broadcast + * FFFFh : Unspecified + * + ****************************************************************************/ + +static int mrf24j40_setsaddr(FAR struct ieee802154_dev_s *ieee, + uint16_t saddr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + mrf24j40_setreg(dev->spi, MRF24J40_SADRH, (uint8_t)(saddr>>8)); + mrf24j40_setreg(dev->spi, MRF24J40_SADRL, (uint8_t)(saddr&0xFF)); + + dev->saddr = saddr; + dbg("%04X\n",(unsigned)saddr); + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_getsaddr + * + * Description: + * Define the current short address the device is using. + * + ****************************************************************************/ + +static int mrf24j40_getsaddr(FAR struct ieee802154_dev_s *ieee, + FAR uint16_t *saddr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *saddr = dev->saddr; + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_seteaddr + * + * Description: + * Define the device extended address. The following addresses are special: + * FFFFFFFFFFFFFFFFh : Unspecified + * + ****************************************************************************/ + +static int mrf24j40_seteaddr(FAR struct ieee802154_dev_s *ieee, + FAR uint8_t *eaddr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + int i; + + for (i=0; i<8; i++) + { + mrf24j40_setreg(dev->spi, MRF24J40_EADR0 + i, eaddr[i]); + dev->eaddr[i] = eaddr[i]; + } + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_geteaddr + * + * Description: + * Define the current extended address the device is using. + * + ****************************************************************************/ + +static int mrf24j40_geteaddr(FAR struct ieee802154_dev_s *ieee, + FAR uint8_t *eaddr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + memcpy(eaddr, dev->eaddr, 8); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setpromisc + * + * Description: + * Set the device into promiscuous mode, e.g do not filter any incoming + * frame. + * + ****************************************************************************/ + +static int mrf24j40_setpromisc(FAR struct ieee802154_dev_s *ieee, + bool promisc) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + return mrf24j40_setrxmode(dev, promisc ? MRF24J40_RXMODE_PROMISC : + MRF24J40_RXMODE_NORMAL); +} + +/**************************************************************************** + * Name: mrf24j40_getpromisc + * + * Description: + * Get the device receive mode. + * + ****************************************************************************/ + +static int mrf24j40_getpromisc(FAR struct ieee802154_dev_s *ieee, + FAR bool *promisc) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *promisc = (dev->rxmode == MRF24J40_RXMODE_PROMISC); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setdevmode + * + * Description: + * Define the device behaviour: normal end device or coordinator + * + ****************************************************************************/ + +static int mrf24j40_setdevmode(FAR struct ieee802154_dev_s *ieee, + uint8_t mode) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + int ret = OK; + uint8_t reg; + + /* Disable slotted mode until I decide to implement slotted mode */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR); + reg &= ~MRF24J40_TXMCR_SLOTTED; + mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg); + mrf24j40_setreg(dev->spi, MRF24J40_ORDER, 0xFF); + + /* Define dev mode */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR); + + if (mode == IEEE802154_MODE_PANCOORD) + { + reg |= MRF24J40_RXMCR_PANCOORD; + reg &= ~MRF24J40_RXMCR_COORD; + } + else if (mode == IEEE802154_MODE_COORD) + { + reg |= MRF24J40_RXMCR_COORD; + reg &= ~MRF24J40_RXMCR_PANCOORD; + } + else if (mode == IEEE802154_MODE_DEVICE) + { + reg &= ~MRF24J40_RXMCR_PANCOORD; + reg &= ~MRF24J40_RXMCR_COORD; + } + else + { + return -EINVAL; + } + + mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg); + dev->devmode = mode; + + return ret; +} + +/**************************************************************************** + * Name: mrf24j40_setdevmode + * + * Description: + * Return the current device mode + * + ****************************************************************************/ + +static int mrf24j40_getdevmode(FAR struct ieee802154_dev_s *ieee, + FAR uint8_t *mode) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *mode = dev->devmode; + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_settxpower + * + * Description: + * Define the transmit power. Value is passed in mBm, it is rounded to + * the nearest value. Some MRF modules have a power amplifier, this routine + * does not care about this. We only change the CHIP output power. + * + ****************************************************************************/ + +static int mrf24j40_settxpower(FAR struct ieee802154_dev_s *ieee, + int32_t txpwr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + uint8_t reg; + int save_txpwr = txpwr; + + if (txpwr <= -3000 && txpwr > -3630) + { + reg = 0xC0; + txpwr += 3000; + } + else if (txpwr <= -2000) + { + reg = 0x80; + txpwr += 2000; + } + else if (txpwr <= -1000) + { + reg = 0x40; + txpwr += 1000; + } + else if (txpwr <= 0) + { + reg = 0x00; + } + else + { + return -EINVAL; + } + + lldbg("remaining attenuation: %d mBm\n",txpwr); + + switch(txpwr/100) + { + case -9: + case -8: + case -7: + case -6: reg |= 0x07; break; + case -5: reg |= 0x06; break; + case -4: reg |= 0x05; break; + case -3: reg |= 0x04; break; + case -2: reg |= 0x03; break; + case -1: reg |= 0x02; break; + case 0: reg |= 0x00; break; /* value 0x01 is 0.5 db, not used */ + default: return -EINVAL; + } + + mrf24j40_setreg(dev->spi, MRF24J40_RFCON3, reg); + dev->txpower = save_txpwr; + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_gettxpower + * + * Description: + * Return the actual transmit power, in mBm. + * + ****************************************************************************/ + +static int mrf24j40_gettxpower(FAR struct ieee802154_dev_s *ieee, + FAR int32_t *txpwr) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + *txpwr = dev->txpower; + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setcca + * + * Description: + * Define the Clear Channel Assessement method. + * + ****************************************************************************/ + +static int mrf24j40_setcca(FAR struct ieee802154_dev_s *ieee, + FAR struct ieee802154_cca_s *cca) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + uint8_t mode; + + if (!cca->use_ed && !cca->use_cs) + { + return -EINVAL; + } + + if (cca->use_cs && cca->csth > 0x0f) + { + return -EINVAL; + } + + mode = mrf24j40_getreg(dev->spi, MRF24J40_BBREG2); + mode &= 0x03; + + if (cca->use_ed) + { + mode |= MRF24J40_BBREG2_CCAMODE_ED; + mrf24j40_setreg(dev->spi, MRF24J40_CCAEDTH, cca->edth); + } + + if (cca->use_cs) + { + mode |= MRF24J40_BBREG2_CCAMODE_CS; + mode |= cca->csth << 2; + } + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG2, mode); + + memcpy(&dev->cca, cca, sizeof(struct ieee802154_cca_s)); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_getcca + * + * Description: + * Return the Clear Channel Assessement method. + * + ****************************************************************************/ + +static int mrf24j40_getcca(FAR struct ieee802154_dev_s *ieee, + FAR struct ieee802154_cca_s *cca) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + memcpy(cca, &dev->cca, sizeof(struct ieee802154_cca_s)); + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_regdump + * + * Description: + * Display the value of all registers. + * + ****************************************************************************/ + +static int mrf24j40_regdump(FAR struct mrf24j40_dev_s *dev) +{ + uint32_t i; + char buf[4+16*3+2+1]; + int len=0; + + dbg("Short regs:\n"); + + for (i = 0; i < 0x40; i++) + { + if ((i & 15) == 0) + { + len=sprintf(buf, "%02x: ",i&0xFF); + } + + len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i)); + if ((i & 15) == 15) + { + sprintf(buf+len, "\n"); + dbg("%s",buf); + } + } + + dbg("Long regs:\n"); + for (i=0x80000200;i<0x80000250;i++) + { + if ((i&15)==0) + { + len=sprintf(buf, "%02x: ",i&0xFF); + } + + len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i)); + if ((i & 15) == 15) + { + sprintf(buf+len, "\n"); + dbg("%s",buf); + } + } + + return 0; +} + +/**************************************************************************** + * Name: mrf24j40_ioctl + * + * Description: + * Misc/unofficial device controls. + * + ****************************************************************************/ + +static int mrf24j40_ioctl(FAR struct ieee802154_dev_s *ieee, int cmd, + unsigned long arg) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + + switch(cmd) + { + case 1000: + return mrf24j40_regdump(dev); + + case 1001: dev->paenabled = (uint8_t)arg; + dbg("PA %sabled\n",arg?"en":"dis"); + return OK; + + default: + return -ENOTTY; + } +} + +/**************************************************************************** + * Name: mrf24j40_energydetect + * + * Description: + * Measure the RSSI level for the current channel. + * + ****************************************************************************/ + +static int mrf24j40_energydetect(FAR struct ieee802154_dev_s *ieee, + FAR uint8_t *energy) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + uint8_t reg; + + /* Manually enable the LNA*/ + + mrf24j40_pacontrol(dev, MRF24J40_PA_ED); + + /* Set RSSI average duration to 8 symbols */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON1); + reg |= 0x30; + mrf24j40_setreg(dev->spi, MRF24J40_TXBCON1, reg); + + /* 1. Set RSSIMODE1 0x3E<7> – Initiate RSSI calculation. */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x80); + + /* 2. Wait until RSSIRDY 0x3E<0> is set to ‘1’ – RSSI calculation is + * complete. + */ + + while(!(mrf24j40_getreg(dev->spi, MRF24J40_BBREG6) & 0x01)); + + /* 3. Read RSSI 0x210<7:0> – The RSSI register contains the averaged RSSI + * received power level for 8 symbol periods. + */ + + *energy = mrf24j40_getreg(dev->spi, MRF24J40_RSSI); + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x40); + + /* Back to automatic control */ + + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + + return OK; +} + +/* Packet exchange */ + +/**************************************************************************** + * Name: mrf24j40_transmit + * + * Description: + * Send a regular packet over the air. + * + ****************************************************************************/ + +static int mrf24j40_transmit(FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_packet_s *packet) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + uint32_t addr; + uint8_t reg; + int ret; + int hlen = 3; /* include frame control and seq number */ + uint8_t fc1, fc2; + + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + + addr = 0x80000000; + + /* Enable tx int */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg &= ~MRF24J40_INTCON_TXNIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Analyze frame control to compute header length */ + + fc1 = packet->data[0]; + fc2 = packet->data[1]; + + // dbg("fc1 %02X fc2 %02X\n", fc1,fc2); + + if ((fc2 & IEEE802154_FC2_DADDR) == IEEE802154_DADDR_SHORT) + { + hlen += 2 + 2; /* Destination PAN + shortaddr */ + } + else if ((fc2 & IEEE802154_FC2_DADDR) == IEEE802154_DADDR_EXT) + { + hlen += 2 + 8; /* Destination PAN + extaddr */ + } + + if ((fc2 & IEEE802154_FC2_SADDR) == IEEE802154_SADDR_SHORT) + { + if ((fc1 & IEEE802154_FC1_INTRA) != IEEE802154_INTRA) + { + hlen += 2; /* No PAN compression, source PAN is different from dest PAN */ + } + + hlen += 2; /* Source saddr */ + } + else if ((fc2 & IEEE802154_FC2_SADDR) == IEEE802154_SADDR_EXT) + { + if ((fc1 & IEEE802154_FC1_INTRA) != IEEE802154_INTRA) + { + hlen += 2; /* No PAN compression, source PAN is different from dest PAN */ + } + + hlen += 8; /* Ext saddr */ + } + +// dbg("hlen %d\n",hlen); + + /* Header len, 0, TODO for security modes */ + + mrf24j40_setreg(dev->spi, addr++, hlen); + + /* Frame length */ + + mrf24j40_setreg(dev->spi, addr++, packet->len); + + /* Frame data */ + + for (ret = 0; ret < packet->len; ret++) /* this sets the correct val for ret */ + { + mrf24j40_setreg(dev->spi, addr++, packet->data[ret]); + } + + /* If the frame control field contains + * an acknowledgment request, set the TXNACKREQ bit. + * See IEEE 802.15.4/2003 7.2.1.1 page 112 for info. + */ + + reg = MRF24J40_TXNCON_TXNTRIG; + if (fc1 & IEEE802154_FC1_ACKREQ) + { + reg |= MRF24J40_TXNCON_TXNACKREQ; + } + + /* Trigger packet emission */ + + mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg); + + /* Suspend calling thread until transmit is complete */ + + return sem_wait(&ieee->txsem); +} + +/**************************************************************************** + * Name: mrf24j40_irqwork_tx + * + * Description: + * Manage completion of packet transmission. + * + ****************************************************************************/ + +static void mrf24j40_irqwork_tx(FAR struct mrf24j40_dev_s *dev) +{ + uint8_t txstat; + uint8_t reg; + + txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT); + + /* 1 means it failed, we want 1 to mean it worked. + * tx_ok = !(tmp & ~(1 << TXNSTAT)); + * retries = tmp >> 6; + * channel_busy = (tmp & (1 << CCAFAIL)); + */ + + //dbg("TXSTAT%02X!\n", txstat); +#warning TODO report errors + UNUSED(txstat); + + /* Disable tx int */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_TXNIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Wake up the thread that triggered the transmission */ + + sem_post(&dev->ieee.txsem); +} + +/**************************************************************************** + * Name: mrf24j40_enablerx + * + * Description: + * Enable reception of a packet. The interrupt will signal the rx semaphore. + * + ****************************************************************************/ + +static int mrf24j40_rxenable(FAR struct ieee802154_dev_s *ieee, bool state, + FAR struct ieee802154_packet_s *packet) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee; + uint8_t reg; + + if (state) + { + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + ieee->rxbuf = packet; + + /* Enable rx int */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg &= ~MRF24J40_INTCON_RXIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + } + else + { + ieee->rxbuf = NULL; + } + + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_irqwork_rx + * + * Description: + * Manage packet reception. + * + ****************************************************************************/ + +static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev) +{ + uint32_t addr; + uint32_t index; + uint8_t reg; + + /*dbg("!\n");*/ + + /* Disable rx int */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_RXIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Disable packet reception */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV); + + /* Read packet */ + + addr = 0x80000300; + dev->ieee.rxbuf->len = mrf24j40_getreg(dev->spi, addr++); + /*dbg("len %3d\n", dev->ieee.rxbuf->len);*/ + + for (index = 0; index < dev->ieee.rxbuf->len; index++) + { + dev->ieee.rxbuf->data[index] = mrf24j40_getreg(dev->spi, addr++); + } + + dev->ieee.rxbuf->lqi = mrf24j40_getreg(dev->spi, addr++); + dev->ieee.rxbuf->rssi = mrf24j40_getreg(dev->spi, addr++); + + /* Reduce len by 2, we only receive frames with correct crc, no check required */ + + dev->ieee.rxbuf->len -= 2; + + /* Enable reception of next packet by flushing the fifo. + * This is an MRF24J40 errata (no. 1). + */ + + mrf24j40_setreg(dev->spi, MRF24J40_RXFLUSH, 1); + + /* Enable packet reception */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0); + + sem_post(&dev->ieee.rxsem); +} + +/**************************************************************************** + * Name: mrf24j40_irqworker + * + * Description: + * Perform interrupt handling logic outside of the interrupt handler (on + * the work queue thread). + * + * Parameters: + * arg - The reference to the driver structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void mrf24j40_irqworker(FAR void *arg) +{ + FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)arg; + uint8_t intstat; + + DEBUGASSERT(dev); + DEBUGASSERT(dev->spi); + + /* Read and store INTSTAT - this clears the register. */ + + intstat = mrf24j40_getreg(dev->spi, MRF24J40_INTSTAT); +// dbg("INT%02X\n", intstat); + + /* Do work according to the pending interrupts */ + + if ((intstat & MRF24J40_INTSTAT_RXIF)) + { + /* A packet was received, retrieve it */ + + mrf24j40_irqwork_rx(dev); + } + + if ((intstat & MRF24J40_INTSTAT_TXNIF)) + { + /* A packet was transmitted or failed*/ + + mrf24j40_irqwork_tx(dev); + } + + /* Re-Enable GPIO interrupts */ + + dev->lower->enable(dev->lower, TRUE); +} + +/**************************************************************************** + * Name: mrf24j40_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int mrf24j40_interrupt(int irq, FAR void *context) +{ + /* To support multiple devices, + * retrieve the priv structure using the irq number + */ + + register FAR struct mrf24j40_dev_s *dev = &g_mrf24j40_devices[0]; + + /* In complex environments, we cannot do SPI transfers from the interrupt + * handler because semaphores are probably used to lock the SPI bus. In + * this case, we will defer processing to the worker thread. This is also + * much kinder in the use of system resources and is, therefore, probably + * a good thing to do in any event. + */ + + DEBUGASSERT(work_available(&dev->irqwork)); + + /* Notice that further GPIO interrupts are disabled until the work is + * actually performed. This is to prevent overrun of the worker thread. + * Interrupts are re-enabled in enc_irqworker() when the work is completed. + */ + + dev->lower->enable(dev->lower, FALSE); + return work_queue(HPWORK, &dev->irqwork, mrf24j40_irqworker, (FAR void *)dev, 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mrf24j40_init + * + * Description: + * Return an mrf24j40 device for use by other drivers. + * + ****************************************************************************/ + +FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi, + FAR const struct mrf24j40_lower_s *lower) +{ + FAR struct mrf24j40_dev_s *dev; + struct ieee802154_cca_s cca; + +#if 0 + dev = kmm_zalloc(sizeof(struct mrf24j40_dev_s)); + + if (!dev) + { + return NULL; + } +#else + dev = &g_mrf24j40_devices[0]; +#endif + + /* Attach irq */ + + if (lower->attach(lower, mrf24j40_interrupt) != OK) + { +#if 0 + free(dev); +#endif + return NULL; + } + + dev->ieee.ops = &mrf24j40_devops; + sem_init(&dev->ieee.rxsem, 0, 0); + sem_init(&dev->ieee.txsem, 0, 0); + + dev->lower = lower; + dev->spi = spi; + + mrf24j40_initialize(dev); + + mrf24j40_setchannel(&dev->ieee, 11); + mrf24j40_setpanid (&dev->ieee, IEEE802154_PAN_DEFAULT); + mrf24j40_setsaddr (&dev->ieee, IEEE802154_SADDR_UNSPEC); + mrf24j40_seteaddr (&dev->ieee, IEEE802154_EADDR_UNSPEC); + + /* Default device params */ + + cca.use_ed = 1; + cca.use_cs = 0; + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ + mrf24j40_setcca(&dev->ieee, &cca); + + mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); + + mrf24j40_settxpower(&dev->ieee, 0); /*16. Set transmitter power .*/ + + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + + dev->lower->enable(dev->lower, TRUE); + + return &dev->ieee; +} diff --git a/drivers/wireless/ieee802154/mrf24j40.h b/drivers/wireless/ieee802154/mrf24j40.h new file mode 100644 index 0000000000000000000000000000000000000000..de3131e4df4534ef5ca1d1239df586e043b67e98 --- /dev/null +++ b/drivers/wireless/ieee802154/mrf24j40.h @@ -0,0 +1,206 @@ +/**************************************************************************** + * drivers/wireless/ieee802154/mrf24j40.h + * + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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 __DRIVERS_IEEE802154_MRF24J40_H +#define __DRIVERS_IEEE802154_MRF24J40_H + +/* MRF24J40 Registers *******************************************************/ + +#define MRF24J40_RXMCR 0x00 +#define MRF24J40_PANIDL 0x01 +#define MRF24J40_PANIDH 0x02 +#define MRF24J40_SADRL 0x03 +#define MRF24J40_SADRH 0x04 +#define MRF24J40_EADR0 0x05 +#define MRF24J40_EADR1 0x06 +#define MRF24J40_EADR2 0x07 +#define MRF24J40_EADR3 0x08 +#define MRF24J40_EADR4 0x09 +#define MRF24J40_EADR5 0x0A +#define MRF24J40_EADR6 0x0B +#define MRF24J40_EADR7 0x0C +#define MRF24J40_RXFLUSH 0x0D +#define MRF24J40_ORDER 0x10 +#define MRF24J40_TXMCR 0x11 +#define MRF24J40_ACKTMOUT 0x12 +#define MRF24J40_ESLOTG1 0x13 +#define MRF24J40_SYMTICKL 0x14 +#define MRF24J40_SYMTICKH 0x15 +#define MRF24J40_PACON0 0x16 +#define MRF24J40_PACON1 0x17 +#define MRF24J40_PACON2 0x18 +#define MRF24J40_TXBCON0 0x1A +#define MRF24J40_TXNCON 0x1B +#define MRF24J40_TXG1CON 0x1C +#define MRF24J40_TXG2CON 0x1D +#define MRF24J40_ESLOTG23 0x1E +#define MRF24J40_ESLOTG45 0x1F +#define MRF24J40_ESLOTG67 0x20 +#define MRF24J40_TXPEND 0x21 +#define MRF24J40_WAKECON 0x22 +#define MRF24J40_FRMOFFSET 0x23 +#define MRF24J40_TXSTAT 0x24 +#define MRF24J40_TXBCON1 0x25 +#define MRF24J40_GATECLK 0x26 +#define MRF24J40_TXTIME 0x27 +#define MRF24J40_HSYMTMRL 0x28 +#define MRF24J40_HSYMTMRH 0x29 +#define MRF24J40_SOFTRST 0x2A +#define MRF24J40_SECCON0 0x2C +#define MRF24J40_SECCON1 0x2C +#define MRF24J40_TXSTBL 0x2E +#define MRF24J40_RXSR 0x30 +#define MRF24J40_INTSTAT 0x31 +#define MRF24J40_INTCON 0x32 +#define MRF24J40_GPIO 0x33 +#define MRF24J40_TRISGPIO 0x34 +#define MRF24J40_SLPACK 0x35 +#define MRF24J40_RFCTL 0x36 +#define MRF24J40_SECCR2 0x37 +#define MRF24J40_BBREG0 0x38 +#define MRF24J40_BBREG1 0x39 +#define MRF24J40_BBREG2 0x3A +#define MRF24J40_BBREG3 0x3B +#define MRF24J40_BBREG4 0x3C +#define MRF24J40_BBREG6 0x3E +#define MRF24J40_CCAEDTH 0x3F + +#define MRF24J40_RFCON0 0x80000200 +#define MRF24J40_RFCON1 0x80000201 +#define MRF24J40_RFCON2 0x80000202 +#define MRF24J40_RFCON3 0x80000203 +#define MRF24J40_RFCON5 0x80000205 +#define MRF24J40_RFCON6 0x80000206 +#define MRF24J40_RFCON7 0x80000207 +#define MRF24J40_RFCON8 0x80000208 +#define MRF24J40_SLPCAL0 0x80000209 +#define MRF24J40_SLPCAL1 0x8000020A +#define MRF24J40_SLPCAL2 0x8000020B +#define MRF24J40_RFSTATE 0x8000020F +#define MRF24J40_RSSI 0x80000210 +#define MRF24J40_SLPCON0 0x80000211 +#define MRF24J40_SLPCON1 0x80000220 +#define MRF24J40_WAKETIMEL 0x80000222 +#define MRF24J40_WAKETIMEH 0x80000223 +#define MRF24J40_REMCNTL 0x80000224 +#define MRF24J40_REMCNTH 0x80000225 +#define MRF24J40_MAINCNT0 0x80000226 +#define MRF24J40_MAINCNT1 0x80000227 +#define MRF24J40_MAINCNT2 0x80000228 +#define MRF24J40_MAINCNT3 0x80000229 +#define MRF24J40_TESTMODE 0x8000022F +#define MRF24J40_ASSOEADR0 0x80000230 +#define MRF24J40_ASSOEADR1 0x80000231 +#define MRF24J40_ASSOEADR2 0x80000232 +#define MRF24J40_ASSOEADR3 0x80000233 +#define MRF24J40_ASSOEADR4 0x80000234 +#define MRF24J40_ASSOEADR5 0x80000235 +#define MRF24J40_ASSOEADR6 0x80000236 +#define MRF24J40_ASSOEADR7 0x80000237 +#define MRF24J40_ASSOSADR0 0x80000238 +#define MRF24J40_ASSOSADR1 0x80000239 +#define MRF24J40_UPNONCE0 0x80000240 +#define MRF24J40_UPNONCE1 0x80000241 +#define MRF24J40_UPNONCE2 0x80000242 +#define MRF24J40_UPNONCE3 0x80000243 +#define MRF24J40_UPNONCE4 0x80000244 +#define MRF24J40_UPNONCE5 0x80000245 +#define MRF24J40_UPNONCE6 0x80000246 +#define MRF24J40_UPNONCE7 0x80000247 +#define MRF24J40_UPNONCE8 0x80000248 +#define MRF24J40_UPNONCE9 0x80000249 +#define MRF24J40_UPNONCE10 0x8000024A +#define MRF24J40_UPNONCE11 0x8000024B +#define MRF24J40_UPNONCE12 0x8000024C + +/* INTSTAT bits */ + +#define MRF24J40_INTSTAT_SLPIF 0x80 +#define MRF24J40_INTSTAT_WAKEIF 0x40 +#define MRF24J40_INTSTAT_HSYMTMRIF 0x20 +#define MRF24J40_INTSTAT_SECIF 0x10 +#define MRF24J40_INTSTAT_RXIF 0x08 +#define MRF24J40_INTSTAT_TXG2IF 0x04 +#define MRF24J40_INTSTAT_TXG1IF 0x02 +#define MRF24J40_INTSTAT_TXNIF 0x01 + +/* RXMCR bits */ + +#define MRF24J40_RXMCR_PROMI 0x01 /* Enable promisc mode (rx all valid packets) */ +#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */ +#define MRF24J40_RXMCR_COORD 0x04 /* Enable coordinator mode ??? DIFFERENCE ??? - not used in datasheet! */ +#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */ +#define MRF24J40_RXMCR_NOACKRSP 0x20 /* Enable auto ACK when a packet is rxed */ + +/* TXMCR bits */ + +#define MRF24J40_TXMCR_CSMABF0 0x01 +#define MRF24J40_TXMCR_CSMABF1 0x02 +#define MRF24J40_TXMCR_CSMABF2 0x04 +#define MRF24J40_TXMCR_MACMINBE0 0x08 +#define MRF24J40_TXMCR_MACMINBE1 0x10 +#define MRF24J40_TXMCR_SLOTTED 0x20 +#define MRF24J40_TXMCR_BATLIFEXT 0x40 +#define MRF24J40_TXMCR_NOCSMA 0x80 + +/* INTCON bits */ + +#define MRF24J40_INTCON_SLPIE 0x80 +#define MRF24J40_INTCON_WAKEIE 0x40 +#define MRF24J40_INTCON_HSYMTMRIE 0x20 +#define MRF24J40_INTCON_SECIE 0x10 +#define MRF24J40_INTCON_RXIE 0x08 +#define MRF24J40_INTCON_TXG2IE 0x04 +#define MRF24J40_INTCON_TXG1IE 0x02 +#define MRF24J40_INTCON_TXNIE 0x01 + +/* BBREG1 bits */ + +#define MRF24J40_BBREG1_RXDECINV 0x04 /* Enable/Disable packet reception */ + +/* BBREG2 bits */ + +#define MRF24J40_BBREG2_CCAMODE_ED 0x80 +#define MRF24J40_BBREG2_CCAMODE_CS 0x40 + +/* TXNCON bits */ + +#define MRF24J40_TXNCON_TXNTRIG 0x01 /* Trigger packet tx, automatically cleared */ +#define MRF24J40_TXNCON_TXNSECEN 0x02 /* Enable security */ +#define MRF24J40_TXNCON_TXNACKREQ 0x04 /* An ACK is requested for this pkt */ +#define MRF24J40_TXNCON_INDIRECT 0x08 /* Activate indirect tx bit (for coordinators) */ +#define MRF24J40_TXNCON_FPSTAT 0x10 /* Status of the frame pending big in txed acks */ + +#endif /* __DRIVERS_IEEE802154_MRF24J40_H */ diff --git a/drivers/wireless/nrf24l01.c b/drivers/wireless/nrf24l01.c index ad5bdcc3b3ec68c1cc3ea353b8db7ce2f7722e8a..ab7402d77358efcde8c59f7224f3f50b5b04857e 100644 --- a/drivers/wireless/nrf24l01.c +++ b/drivers/wireless/nrf24l01.c @@ -158,21 +158,13 @@ struct nrf24l01_dev_s ****************************************************************************/ /* Low-level SPI helpers */ -#ifdef CONFIG_SPI_OWNBUS static inline void nrf24l01_configspi(FAR struct spi_dev_s *spi); -# define nrf24l01_lock(spi) -# define nrf24l01_unlock(spi) -#else -# define nrf24l01_configspi(spi); static void nrf24l01_lock(FAR struct spi_dev_s *spi); static void nrf24l01_unlock(FAR struct spi_dev_s *spi); -#endif static uint8_t nrf24l01_access(FAR struct nrf24l01_dev_s *dev, nrf24l01_access_mode_t mode, uint8_t cmd, uint8_t *buf, int length); - static uint8_t nrf24l01_flush_rx(FAR struct nrf24l01_dev_s *dev); - static uint8_t nrf24l01_flush_tx(FAR struct nrf24l01_dev_s *dev); /* Read register from nrf24 */ @@ -243,14 +235,15 @@ static const struct file_operations nrf24l01_fops = #ifndef CONFIG_DISABLE_POLL nrf24l01_poll, /* poll */ #endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS NULL /* unlink */ +#endif }; /**************************************************************************** * Private Functions ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void nrf24l01_lock(FAR struct spi_dev_s *spi) { /* Lock the SPI bus because there are multiple devices competing for the @@ -267,18 +260,17 @@ static void nrf24l01_lock(FAR struct spi_dev_s *spi) SPI_SELECT(spi, SPIDEV_WIRELESS, true); SPI_SETMODE(spi, SPIDEV_MODE0); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, NRF24L01_SPIFREQ); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, NRF24L01_SPIFREQ); SPI_SELECT(spi, SPIDEV_WIRELESS, false); } -#endif /**************************************************************************** * Function: nrf24l01_unlock * * Description: - * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS - * undefined) then we need to un-lock the SPI bus for each transfer, - * possibly losing the current configuration. + * Un-lock the SPI bus after each transfer, possibly losing the current + * configuration if we are sharing the SPI bus with other devices. * * Parameters: * spi - Reference to the SPI driver structure @@ -290,23 +282,18 @@ static void nrf24l01_lock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS static void nrf24l01_unlock(FAR struct spi_dev_s *spi) { /* Relinquish the SPI bus. */ (void)SPI_LOCK(spi, false); } -#endif /**************************************************************************** * Function: nrf24l01_configspi * * Description: - * Configure the SPI for use with the NRF24L01. This function should be - * called once during touchscreen initialization to configure the SPI - * bus. Note that if CONFIG_SPI_OWNBUS is not defined, then this function - * does nothing. + * Configure the SPI for use with the NRF24L01. * * Parameters: * spi - Reference to the SPI driver structure @@ -318,20 +305,17 @@ static void nrf24l01_unlock(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS static inline void nrf24l01_configspi(FAR struct spi_dev_s *spi) { - /* Configure SPI for the NRF24L01 module. - * As we own the SPI bus this method is called just once. - */ + /* Configure SPI for the NRF24L01 module. */ - SPI_SELECT(spi, SPIDEV_WIRELESS, true); // Useful ? + SPI_SELECT(spi, SPIDEV_WIRELESS, true); /* Useful ? */ SPI_SETMODE(spi, SPIDEV_MODE0); SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, NRF24L01_SPIFREQ); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, NRF24L01_SPIFREQ); SPI_SELECT(spi, SPIDEV_WIRELESS, false); } -#endif static inline void nrf24l01_select(struct nrf24l01_dev_s * dev) { @@ -663,7 +647,7 @@ static void nrf24l01_tostate(struct nrf24l01_dev_s *dev, nrf24l01_state_t state) /* Entering new state */ - switch(state) + switch (state) { case ST_UNKNOWN: /* Power down the module here... */ @@ -980,7 +964,7 @@ static int nrf24l01_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; case NRF24L01IOC_GETRETRCFG: /* Get retransmit params. arg: Pointer to nrf24l01_retrcfg_t */ - result = -ENOSYS; /* TODO !*/ + result = -ENOSYS; /* TODO */ break; case NRF24L01IOC_SETPIPESCFG: @@ -1053,7 +1037,7 @@ static int nrf24l01_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } case NRF24L01IOC_GETDATARATE: - result = -ENOSYS; /* TODO !*/ + result = -ENOSYS; /* TODO */ break; case NRF24L01IOC_SETADDRWIDTH: @@ -1295,7 +1279,7 @@ int nrf24l01_init(FAR struct nrf24l01_dev_s *dev) CHECK_ARGS(dev); nrf24l01_lock(dev->spi); - /* Configure the SPI parameters now (if we own the bus) */ + /* Configure the SPI parameters before communicating */ nrf24l01_configspi(dev->spi); @@ -1351,7 +1335,8 @@ int nrf24l01_init(FAR struct nrf24l01_dev_s *dev) /* Clear interrupt sources (useful ?) */ - nrf24l01_writeregbyte(dev, NRF24L01_STATUS, NRF24L01_RX_DR|NRF24L01_TX_DS|NRF24L01_MAX_RT); + nrf24l01_writeregbyte(dev, NRF24L01_STATUS, + NRF24L01_RX_DR | NRF24L01_TX_DS | NRF24L01_MAX_RT); out: nrf24l01_unlock(dev->spi); @@ -1523,7 +1508,7 @@ int nrf24l01_settxpower(FAR struct nrf24l01_dev_s *dev, int outpower) * '11' – 0dBm */ - switch(outpower) + switch (outpower) { case 0: hwpow = 3 << NRF24L01_RF_PWR_SHIFT; diff --git a/drivers/wireless/pn532.c b/drivers/wireless/pn532.c new file mode 100644 index 0000000000000000000000000000000000000000..0f171950de9f995be69e5323f203add6ef931a1b --- /dev/null +++ b/drivers/wireless/pn532.c @@ -0,0 +1,1131 @@ +/**************************************************************************** + * include/wireless/pn532.h + * + * Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved. + * Authors: Janne Rosberg + * Teemu Pirinen + * Juho Grundstrĥm + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pn532.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_WL_PN532_DEBUG +# define pn532dbg dbg +#else +# ifdef CONFIG_CPP_HAVE_VARARGS +# define pn532dbg(x...) +# else +# define pn532dbg (void) +# endif +#endif + +#ifdef CONFIG_WL_PN532_DEBUG_TX +# define tracetx dbgdumpbuffer +#else +# define tracetx(x...) +#endif + +#ifdef CONFIG_WL_PN532_DEBUG_RX +# define tracerx dbgdumpbuffer +#else +# define tracerx(x...) +#endif + +#define FRAME_SIZE(f) (sizeof(struct pn532_frame) + f->len + 2) +#define FRAME_POSTAMBLE(f) (f->data[f->len + 1]) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline void pn532_configspi(FAR struct spi_dev_s *spi); +static void pn532_lock(FAR struct spi_dev_s *spi); +static void pn532_unlock(FAR struct spi_dev_s *spi); + +/* Character driver methods */ + +static int _open(FAR struct file *filep); +static int _close(FAR struct file *filep); +static ssize_t _read(FAR struct file *, FAR char *, size_t); +static ssize_t _write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int _ioctl(FAR struct file *filep,int cmd,unsigned long arg); + +static uint8_t pn532_checksum(uint8_t value); +static uint8_t pn532_data_checksum(uint8_t *data, int datalen); + +int pn532_read(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n); + +/* IRQ Handling TODO: +static int pn532_irqhandler(FAR int irq, FAR void *context, FAR void* dev); +static inline int pn532_attachirq(FAR struct pn532_dev_s *dev, xcpt_t isr); +*/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_pn532fops = +{ + _open, + _close, + _read, + _write, + 0, + _ioctl +#ifndef CONFIG_DISABLE_POLL + ,0 +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + ,0 +#endif +}; + +static const uint8_t pn532ack[] = +{ + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void pn532_lock(FAR struct spi_dev_s *spi) +{ + (void)SPI_LOCK(spi, true); + + SPI_SETMODE(spi, SPIDEV_MODE0); + SPI_SETBITS(spi, -8); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ); +} + +static void pn532_unlock(FAR struct spi_dev_s *spi) +{ + (void)SPI_LOCK(spi, false); +} + +static inline void pn532_configspi(FAR struct spi_dev_s *spi) +{ + /* Configure SPI for the PN532 module. */ + + SPI_SETMODE(spi, SPIDEV_MODE0); + SPI_SETBITS(spi, -8); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ); +} + +static inline void pn532_select(struct pn532_dev_s *dev) +{ + if (dev->config->select) + { + dev->config->select(dev, true); + } + else + { + SPI_SELECT(dev->spi, SPIDEV_WIRELESS, true); + } +} + +static inline void pn532_deselect(struct pn532_dev_s *dev) +{ + if (dev->config->select) + { + dev->config->select(dev, false); + } + else + { + SPI_SELECT(dev->spi, SPIDEV_WIRELESS, false); + } +} + +static void pn532_frame_init(struct pn532_frame *frame, uint8_t cmd) +{ + frame->preamble = PN532_PREAMBLE; + frame->start_code = PN532_SOF; + frame->tfi = PN532_HOSTTOPN532; + frame->data[0] = cmd; + frame->len = 2; +} + +static void pn532_frame_finish(struct pn532_frame *frame) +{ + frame->lcs = pn532_checksum(frame->len); + frame->data[frame->len-1] = pn532_data_checksum(&frame->tfi, frame->len); + frame->data[frame->len] = PN532_POSTAMBLE; +} + +static inline uint8_t pn532_checksum(uint8_t value) +{ + return ~value + 1; +} + +static uint8_t pn532_data_checksum(uint8_t *data, int datalen) +{ + uint8_t sum = 0x00; + int i; + + for (i = 0; i < datalen; i++) + { + sum += data[i]; + } + + return pn532_checksum(sum); +} + +bool pn532_rx_frame_is_valid(struct pn532_frame *f, bool check_data) +{ + uint8_t chk; + + if (f->start_code != PN532_SOF) + { + pn532dbg("Frame startcode 0x%X != 0x%X\n", PN532_SOF, f->start_code); + return false; + } + + if (f->tfi != PN532_PN532TOHOST) + { + return false; + } + + chk = pn532_checksum(f->len); + if (chk != f->lcs) + { + pn532dbg("Frame data len checksum failed"); + return false; + } + + if (check_data) + { + chk = pn532_data_checksum(&f->tfi, f->len); + if (chk != f->data[f->len-1]) + { + pn532dbg("Frame data checksum failed: calc=0x%X != 0x%X", chk, f->data[f->len-1]); + return false; + } + } + + return true; +} + +static uint8_t pn532_status(struct pn532_dev_s *dev) +{ + int rs; + + pn532_lock(dev->spi); + pn532_select(dev); + + rs = SPI_SEND(dev->spi, PN532_SPI_STATREAD); + rs = SPI_SEND(dev->spi, PN532_SPI_STATREAD); + + pn532_deselect(dev); + pn532_unlock(dev->spi); + + return rs; +} + +/**************************************************************************** + * Name: pn532_wait_rx_ready + * + * Description: + * Blocks until Data frame available from chip. + * + * Input Parameters: + * dev + * timeout + * + * Returned Value: + * 0 for OK. -ETIMEDOUT if no data available + * + ****************************************************************************/ + +static int pn532_wait_rx_ready(struct pn532_dev_s *dev, int timeout) +{ + int ret = OK; + +#ifdef CONFIG_PN532_USE_IRQ_FLOW_CONTROL + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 1; + sem_timedwait(dev->sem_rx, &ts); +#endif + + /* TODO: Handle Exception bits 2, 3 */ + + while (pn532_status(dev) != PN532_SPI_READY) + { + if (--timeout == 0x00) + { + pn532dbg("wait RX timeout!\n"); + return -ETIMEDOUT; + } + + usleep(1000); + } + + dev->state = PN532_STATE_DATA_READY; + return ret; +} + +/**************************************************************************** + * Name: pn532_writecommand + * + * Description: + * Helper for debug/testing + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if 0 +static void pn532_writecommand(struct pn532_dev_s *dev, uint8_t cmd) +{ + char cmd_buffer[16]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + + pn532_frame_init(f, cmd); + pn532_frame_finish(f); + + pn532_lock(dev->spi); + pn532_select(dev); + usleep(10000); + + SPI_SEND(dev->spi, PN532_SPI_DATAWRITE); + SPI_SNDBLOCK(dev->spi, f, FRAME_SIZE(f)); + + pn532_deselect(dev); + pn532_unlock(dev->spi); + + tracetx("command sent", (uint8_t *) f, FRAME_SIZE(f)); +} +#endif + +/**************************************************************************** + * Name: pn532_read + * + * Description: + * RAW Read data from chip. + * NOTE: This WON'T wait if data is available! + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +int pn532_read(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n) +{ + pn532_lock(dev->spi); + pn532_select(dev); + SPI_SEND(dev->spi, PN532_SPI_DATAREAD); + SPI_RECVBLOCK(dev->spi, buff, n); + pn532_deselect(dev); + pn532_unlock(dev->spi); + + tracerx("read", buff, n); + return n; +} + +int pn532_read_more(struct pn532_dev_s *dev, uint8_t *buff, uint8_t n) +{ + pn532_lock(dev->spi); + pn532_select(dev); + SPI_RECVBLOCK(dev->spi, buff, n); + pn532_deselect(dev); + pn532_unlock(dev->spi); + + tracerx("read_more", buff, n); + return n; +} + +/**************************************************************************** + * Name: pn532_read_ack + * + * Description: + * Read Ack responce from device + * + * Input Parameters: + * dev + * + * Returned Value: + * 0 = NOK, 1 = OK + * + ****************************************************************************/ + +int pn532_read_ack(struct pn532_dev_s *dev) +{ + int res = 0; + uint8_t ack[6]; + + pn532_read(dev, (uint8_t *) &ack, 6); + + if (memcmp(&ack, &pn532ack, 6) == 0x00) + { + res = 1; + } + else + { + pn532dbg("ACK NOK"); + res = 0; + } + + return res; +} + +/**************************************************************************** + * Name: pn532_write_frame + * + * Description: + * Write frame to chip. Also waits and reads ACK frame from chip. + * + * Construct frame with + * pn532_frame_init(), pn532_frame_finish() + * + * Input Parameters: + * dev - Device instance + * f - Pointer to start frame + * + * Returned Value: + * 0 for OK, negative for error + * + ****************************************************************************/ + +int pn532_write_frame(struct pn532_dev_s *dev, struct pn532_frame *f) +{ + int res = OK; + + pn532_lock(dev->spi); + pn532_select(dev); + usleep(2000); + + SPI_SEND(dev->spi, PN532_SPI_DATAWRITE); + SPI_SNDBLOCK(dev->spi, f, FRAME_SIZE(f)); + pn532_deselect(dev); + pn532_unlock(dev->spi); + tracetx("WriteFrame", (uint8_t *) f, FRAME_SIZE(f)); + + /* Wait ACK frame */ + + res = pn532_wait_rx_ready(dev, 30); + if (res == OK) + { + if (!pn532_read_ack(dev)) + { + pn532dbg("command FAILED\n"); + res = -EIO; + } + } + + return res; +} + +int pn532_read_frame(struct pn532_dev_s *dev, struct pn532_frame *f, int max_size) +{ + int res = -EIO; + + /* Wait for frame available */ + + if ((res = pn532_wait_rx_ready(dev, 100)) == OK) + { + /* Read header */ + + pn532_read(dev, (uint8_t *) f, sizeof(struct pn532_frame)); + if (pn532_rx_frame_is_valid(f, false)) + { + if (max_size < f->len) + { + return -EINVAL; + } + + pn532_read_more(dev, &f->data[0], f->len); + + /* TODO: optimize frame integrity check... + * pn532_data_checksum(&f.tfi, f->len); + * dbgdumpbuffer("RX Frame:", f, f->len+6); + */ + + if (pn532_rx_frame_is_valid(f, true)) + { + res = OK; + } + } + } + + return res; +} + +bool pn532_set_config(struct pn532_dev_s *dev, uint8_t flags) +{ + char cmd_buffer[2+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + + pn532_frame_init(f, PN532_COMMAND_SETPARAMETERS); + f->data[1] = flags; + f->len += 1; + pn532_frame_finish(f); + + uint8_t resp[9]; + bool res = false; + + if (pn532_write_frame(dev, f) == OK) + { + pn532_read(dev, (uint8_t *) &resp, 9); + tracerx("set config responce", resp, 9); + res = true; + } + + return res; +} + +int pn532_sam_config(struct pn532_dev_s *dev, struct pn_sam_settings_s *settings) +{ + char cmd_buffer[4+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + int res; + + pn532_frame_init(f, PN532_COMMAND_SAMCONFIGURATION); + f->data[1] = PN532_SAM_NORMAL_MODE; + f->data[2] = 0x14; /* Timeout LSB=50ms 0x14*50ms = 1sec */ + f->data[3] = 0x01; /* P-70, IRQ enabled */ + + if (settings) + { + /* TODO: !!! */ + } + + f->len += 3; + pn532_frame_finish(f); + + res = -EIO; + + if (pn532_write_frame(dev, f) == OK) + { + if (pn532_read_frame(dev, f, 4) == OK) + { + tracerx("sam config response", (uint8_t *) f->data, 3); + if (f->data[0] == PN532_COMMAND_SAMCONFIGURATION + 1) + { + res = OK; + } + } + } + + return res; +} + +int pn532_get_fw_version(struct pn532_dev_s *dev, + struct pn_firmware_version *fv) +{ + uint8_t cmd_buffer[4+8+1]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + struct pn_firmware_version *fw; + int res = -EIO; + + pn532_frame_init(f, PN532_COMMAND_GETFIRMWAREVERSION); + pn532_frame_finish(f); + + if (pn532_write_frame(dev, f) == OK) + { + if (pn532_read_frame(dev, f, 6) == OK) + { + if (f->data[0] == PN532_COMMAND_GETFIRMWAREVERSION + 1) + { + fw = (struct pn_firmware_version*) &f->data[1]; + pn532dbg("FW: %d.%d on IC:0x%X (Features: 0x%X)\n", + fw->ver, fw->rev, fw->ic, fw->support); + if (fv) + { + memcpy(fv, fw, sizeof(struct pn_firmware_version)); + } + + res = OK; + } + } + } + + return res; +} + +int pn532_write_gpio(struct pn532_dev_s *dev, uint8_t p3, uint8_t p7) +{ + uint8_t cmd_buffer[3+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + int res = -EIO; + + pn532_frame_init(f, PN532_COMMAND_WRITEGPIO); + f->data[1] = p3; + f->data[2] = p7; + f->len += 2; + pn532_frame_finish(f); + + if (pn532_write_frame(dev, f)) + { + pn532_read(dev, cmd_buffer, 10); + tracetx("Resp:", cmd_buffer, 10); + pn532dbg("TFI=%x, data0=%X", f->tfi, f->data[0]); + if ((f->tfi == PN532_PN532TOHOST) && (f->data[0] == PN532_COMMAND_WRITEGPIO+1)) + { + res = OK; + } + } + + return res; +} + +uint32_t pn532_write_passive_data(struct pn532_dev_s *dev, uint8_t address, + uint8_t *data, uint8_t len) +{ + uint8_t cmd_buffer[8+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + uint8_t resp[20]; + uint32_t res = -EIO; + + pn532_frame_init(f, PN532_COMMAND_INDATAEXCHANGE); + f->data[1] = 1; /* max n cards at once */ + f->data[2] = 0xA2; /* command WRITE */ + f->data[3] = address; /* ADDRESS, 0 = serial */ + memcpy(&f->data[4], data, len); + f->len += 7; + pn532_frame_finish(f); + + if (pn532_write_frame(dev, f) == OK) + { + if (dev->state == PN532_STATE_DATA_READY) + { + if (pn532_read_frame(dev, (struct pn532_frame *) resp, 15) == OK) + { + dev->state = PN532_STATE_IDLE; + f = (struct pn532_frame *) resp; + tracerx("passive target id resp:", f, f->len+6); + + if (f->data[0] == PN532_COMMAND_INDATAEXCHANGE+1) + { + res = f->data[1]; + } + } + } + } + + return res; +} + +uint32_t pn532_read_passive_data(struct pn532_dev_s *dev, uint8_t address, + uint8_t *data, uint8_t len) +{ + uint8_t cmd_buffer[4+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + uint8_t resp[30]; + uint32_t res = -1; + + pn532_frame_init(f, PN532_COMMAND_INDATAEXCHANGE); + f->data[1] = 1; /* max n cards at once */ + f->data[2] = 0x30; /* command READ */ + f->data[3] = address; /* ADDRESS, 0 = serial */ + f->len += 3; + pn532_frame_finish(f); + + if (pn532_write_frame(dev, f) == OK) + { + if (dev->state == PN532_STATE_DATA_READY) + { + if (pn532_read_frame(dev, (struct pn532_frame *)resp, 25) == OK) + { + dev->state = PN532_STATE_IDLE; + f = (struct pn532_frame *) resp; + tracerx("passive target id resp:", f, f->len+6); + + if (f->data[0] == PN532_COMMAND_INDATAEXCHANGE+1) + { + if(f->data[1] == 0 && data && len) + { + memcpy(data, &f->data[2], len); + } + + res = f->data[1]; + } + } + } + } + + return res; +} + +uint32_t pn532_read_passive_target_id(struct pn532_dev_s *dev, uint8_t baudrate) +{ + uint8_t cmd_buffer[4+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + uint8_t resp[20]; + uint32_t res = -EAGAIN; + int i; + + if (dev->state == PN532_STATE_DATA_READY) + { + res = -EIO; + if (pn532_read_frame(dev, (struct pn532_frame *) resp, 15) == OK) + { + dev->state = PN532_STATE_IDLE; + f = (struct pn532_frame *) resp; + struct pn_poll_response *r = (struct pn_poll_response *) &f->data[1]; + tracerx("passive target id resp:", f, f->len+6); + + if (f->data[0] == PN532_COMMAND_INLISTPASSIVETARGET+1) + { + uint32_t cid = 0; + + if (r->nbtg == 1) + { + pn532dbg("Found %d card(s)\n", r->nbtg); + + /* now supports only type_a cards + * if (poll_mode == PN532_POLL_MOD_106KBPS_A) + */ + + struct pn_target_type_a *t = (struct pn_target_type_a *) &r->target_data; + pn532dbg("sens:0x%x sel:0x%x", t->sens_res, t->sel_res); + pn532dbg("idlen:0x%x ", t->nfcid_len); + + /* generate 32bit cid from id (could be longer) + * HACK: Using only top 4 bytes. + */ + + for (i = 0; i < 4 /*t->nfcid_len*/; i++) + { + cid <<= 8; + cid |= t->nfcid_data[i]; + } + } + + res = cid; + } + } + } + + return res; + +} + +static int pn532_read_passive_target(struct pn532_dev_s *dev, uint8_t baudrate) +{ + uint8_t cmd_buffer[4+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + + pn532_frame_init(f, PN532_COMMAND_INLISTPASSIVETARGET); + f->data[1] = 1; + f->data[2] = baudrate; + f->len += 2; + pn532_frame_finish(f); + return pn532_write_frame(dev, f); +} + +bool pn532_set_rf_config(struct pn532_dev_s *dev, struct pn_rf_config_s *conf) +{ + bool res = false; + uint8_t cmd_buffer[15+7]; + struct pn532_frame *f = (struct pn532_frame *) cmd_buffer; + + pn532_frame_init(f, PN532_COMMAND_RFCONFIGURATION); + f->data[1] = conf->cfg_item; + memcpy(&f->data[2], conf->config, conf->data_size); + f->len += conf->data_size+1; + pn532_frame_finish(f); + + if (pn532_write_frame(dev, f) == OK) + { + pn532_read(dev, (uint8_t *) f, 10); + tracerx("rf config response", (uint8_t *) f, 10); + if (pn532_rx_frame_is_valid(f, true)) + { + if (f->data[0] == PN532_COMMAND_RFCONFIGURATION + 1) + { + res = true; + } + } + } + + return res; +} + +/**************************************************************************** + * Name: pn532_attachirq + * + * Description: + * IRQ handling TODO: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#if 0 +static inline int (FAR struct pn532_dev_s *dev, xcpt_t isr) +{ + return dev->config->irqattach(dev,isr); +} + +static int irq_handler(int irq, FAR void *context) +{ + (void) irq; + (void) context; + + /* pn532dbg("*IRQ*\n"); */ + /* work_queue(HPWORK, &g_dev->irq_work, pn532_worker, dev, 0); */ + + return OK; +} +#endif + +/**************************************************************************** + * Name: pn532_open + * + * Description: + * This function is called whenever the PN532 device is opened. + * + ****************************************************************************/ + +static int _open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct pn532_dev_s *dev; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + dev = inode->i_private; + + pn532_configspi(dev->spi); + + dev->config->reset(1); + usleep(10000); + + pn532_sam_config(dev, NULL); + pn532_get_fw_version(dev, NULL); + + dev->state = PN532_STATE_IDLE; + return OK; +} + +/**************************************************************************** + * Name: _close + * + * Description: + * This routine is called when the PN532 device is closed. + * + ****************************************************************************/ + +static int _close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct pn532_dev_s *dev; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + dev = inode->i_private; + + dev->config->reset(0); + dev->state = PN532_STATE_NOT_INIT; + +#ifdef CONFIG_PM + if(dev->pm_level >= PM_SLEEP) + { + //priv->config->reset(0); + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: _read + * + * Description: + * This routine is called when the device is read. + * + * Returns TAG id as string to buffer. + * or -EIO if no TAG found + * + ****************************************************************************/ + +static ssize_t _read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + FAR struct inode *inode; + FAR struct pn532_dev_s *dev; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + dev = inode->i_private; + + uint32_t id = pn532_read_passive_target_id(dev, PN532_MIFARE_ISO14443A); + if (id != 0xFFFFFFFF) + { + if (buffer) + { + return snprintf(buffer, buflen, "0X%X", id); + } + } + + return -EIO; +} + +/**************************************************************************** + * Name: pn532_write + ****************************************************************************/ + +static ssize_t _write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + FAR struct inode *inode; + FAR struct pn532_dev_s *dev; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + dev = inode->i_private; + + (void) dev; + + return -ENOSYS; +} + +/**************************************************************************** + * Name: pn532_ioctl + ****************************************************************************/ + +static int _ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct pn532_dev_s *dev; + int ret = OK; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + dev = inode->i_private; + + switch (cmd) + { + case PN532IOC_READ_TAG_DATA: + { + struct pn_mifare_tag_data_s *tag_data = (struct pn_mifare_tag_data_s *) arg; + if (tag_data) + { + /* HACK: get rid of previous command */ + + if (dev->state == PN532_STATE_CMD_SENT) + { + if (pn532_wait_rx_ready(dev, 1)) + { + pn532_read_passive_target_id(dev,0); + } + } + + ret = pn532_read_passive_data(dev, tag_data->address, + (uint8_t *) &tag_data->data, + sizeof(tag_data->data)); + + dev->state = PN532_STATE_IDLE; + } + } + break; + + case PN532IOC_WRITE_TAG_DATA: + { + struct pn_mifare_tag_data_s *tag_data = (struct pn_mifare_tag_data_s *) arg; + if (tag_data) + { + /* HACK: get rid of previous command */ + + if (dev->state == PN532_STATE_CMD_SENT) + { + if (pn532_wait_rx_ready(dev, 1)) + { + pn532_read_passive_target_id(dev,0); + } + } + + ret = pn532_write_passive_data(dev, tag_data->address, + (uint8_t *) &tag_data->data, + sizeof(tag_data->data)); + + dev->state = PN532_STATE_IDLE; + } + } + break; + + case PN532IOC_SET_SAM_CONF: + pn532_sam_config(dev, (struct pn_sam_settings_s *) arg); + break; + + case PN532IOC_READ_PASSIVE: + if (dev->state == PN532_STATE_CMD_SENT) + { + uint32_t *ptr = (uint32_t *)((uintptr_t)arg); + *ptr = pn532_read_passive_target_id(dev,0); + } + else + { + uint32_t *ptr = (uint32_t *)((uintptr_t)arg); + *ptr = -1; + } + break; + + case PN532IOC_SET_RF_CONF: + pn532_set_rf_config(dev, (struct pn_rf_config_s *) arg); + break; + + case PN532IOC_SEND_CMD_READ_PASSIVE: + ret = pn532_read_passive_target(dev,0); + if (ret == 0) + { + dev->state = PN532_STATE_CMD_SENT; + } + else + { + dev->state = PN532_STATE_IDLE; + } + break; + + case PN532IOC_GET_DATA_READY: + if (pn532_wait_rx_ready(dev, 1)) + { + ret = 0; + } + else + { + ret = 1; + } + break; + + case PN532IOC_GET_TAG_ID: + { + uint32_t *ptr = (uint32_t *)((uintptr_t)arg); + *ptr = pn532_read_passive_target_id(dev,0); + } + break; + + case PN532IOC_GET_STATE: + ret = dev->state; + break; + + default: + pn532dbg("Unrecognized cmd: %d\n", cmd); + ret = -EINVAL; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pn532_register + * + * Description: + * Register the PN532 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. + * E.g., "/dev/nfc0" + * spi - An instance of the SPI interface to use to communicate with + * PN532. + * config - chip config + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pn532_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + FAR struct pn532_config_s *config) +{ + FAR struct pn532_dev_s *dev; + int ret; + + /* Initialize the PN532 device structure */ + + dev = (FAR struct pn532_dev_s *)kmm_malloc(sizeof(struct pn532_dev_s)); + if (!dev) + { + pn532dbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + dev->spi = spi; + dev->config = config; + +#if defined CONFIG_PM + dev->pm_level = PM_IDLE; +#endif + + /* pn532_attachirq(dev, pn532_irqhandler); */ + + /* Register the character driver */ + + ret = register_driver(devpath, &g_pn532fops, 0666, dev); + if (ret < 0) + { + pn532dbg("Failed to register driver: %d\n", ret); + kmm_free(dev); + } + + return ret; +} diff --git a/drivers/wireless/pn532.h b/drivers/wireless/pn532.h new file mode 100644 index 0000000000000000000000000000000000000000..8361f5ed505bf2c1229ca7493f0e145d35fe066e --- /dev/null +++ b/drivers/wireless/pn532.h @@ -0,0 +1,171 @@ +/**************************************************************************** + * drivers/wireless/pn532.h + * + * Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved. + * Authors: Janne Rosberg + * Teemu Pirinen + * Juho Grundstrĥm + * + * 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 __DRIVERS_WIRELESS_PN532_H +#define __DRIVERS_WIRELESS_PN532_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define PN532_PREAMBLE 0x00 +#define PN532_STARTCODE1 0x00 +#define PN532_STARTCODE2 0xFF +#define PN532_POSTAMBLE 0x00 + +#define PN532_SOF 0xFF00 + +#define PN532_HOSTTOPN532 0xD4 +#define PN532_PN532TOHOST 0xD5 + +#define PN532_SPI_STATREAD 0x02 +#define PN532_SPI_DATAWRITE 0x01 +#define PN532_SPI_DATAREAD 0x03 +#define PN532_SPI_READY 0x01 + +/* PN532 Commands */ + +#define PN532_COMMAND_DIAGNOSE 0x00 +#define PN532_COMMAND_GETFIRMWAREVERSION 0x02 +#define PN532_COMMAND_GETGENERALSTATUS 0x04 +#define PN532_COMMAND_READREGISTER 0x06 +#define PN532_COMMAND_WRITEREGISTER 0x08 +#define PN532_COMMAND_READGPIO 0x0C +#define PN532_COMMAND_WRITEGPIO 0x0E +#define PN532_COMMAND_SETSERIALBAUDRATE 0x10 +#define PN532_COMMAND_SETPARAMETERS 0x12 +#define PN532_COMMAND_SAMCONFIGURATION 0x14 +#define PN532_COMMAND_POWERDOWN 0x16 +#define PN532_COMMAND_RFCONFIGURATION 0x32 +#define PN532_COMMAND_RFREGULATIONTEST 0x58 +#define PN532_COMMAND_INJUMPFORDEP 0x56 +#define PN532_COMMAND_INJUMPFORPSL 0x46 +#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A +#define PN532_COMMAND_INATR 0x50 +#define PN532_COMMAND_INPSL 0x4E +#define PN532_COMMAND_INDATAEXCHANGE 0x40 +#define PN532_COMMAND_INCOMMUNICATETHRU 0x42 +#define PN532_COMMAND_INDESELECT 0x44 +#define PN532_COMMAND_INRELEASE 0x52 +#define PN532_COMMAND_INSELECT 0x54 +#define PN532_COMMAND_INAUTOPOLL 0x60 +#define PN532_COMMAND_TGINITASTARGET 0x8C +#define PN532_COMMAND_TGSETGENERALBYTES 0x92 +#define PN532_COMMAND_TGGETDATA 0x86 +#define PN532_COMMAND_TGSETDATA 0x8E +#define PN532_COMMAND_TGSETMETADATA 0x94 +#define PN532_COMMAND_TGGETINITIATORCOMMAND 0x88 +#define PN532_COMMAND_TGRESPONSETOINITIATOR 0x90 +#define PN532_COMMAND_TGGETTARGETSTATUS 0x8A + +#define PN532_WAKEUP 0x55 + +#define PN532_SAM_NORMAL_MODE 0x01 +#define PN532_SAM_VIRTUAL_CARD 0x02 +#define PN532_SAM_WIRED_CARD 0x03 +#define PN532_SAM_DUAL_CARD 0x04 + +#ifndef CONFIG_PN532_SPI_FREQ +# define CONFIG_PN532_SPI_FREQ (5000000) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct pn532_frame +{ + uint8_t preamble; /* 0x00 */ + uint16_t start_code; /* 0x00FF (BE) -> 0xFF00 (LE) */ + uint8_t len; /* 1 byte indicating the number of bytes in + * the data field */ + uint8_t lcs; /* 1 Packet Length Checksum LCS byte that satisfies + * the relation: Lower byte of [LEN + LCS] = 00h */ + uint8_t tfi; /* Frame idenfifier 0xD4, 0xD5 */ + uint8_t data[]; /* LEN-1 bytes of Packet Data Information. + * The first byte PD0 is the Command Code */ +} packed_struct; + +struct pn_poll_response +{ + uint8_t nbtg; + uint8_t tg; + uint8_t target_data[]; +} packed_struct; + +struct pn_target_type_a +{ + uint16_t sens_res; + uint8_t sel_res; + uint8_t nfcid_len; + uint8_t nfcid_data[]; +} packed_struct; + +struct pn_firmware_version +{ + uint8_t ic; + uint8_t ver; + uint8_t rev; + uint8_t support; +}; + +struct pn532_dev_s +{ + uint8_t state; + FAR struct spi_dev_s *spi; /* SPI interface */ + FAR struct pn532_config_s *config; /* Board configuration data */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +bool pn532_set_config(struct pn532_dev_s *dev, uint8_t flags); + +#endif /* __DRIVERS_WIRELESS_PN532_H */ diff --git a/fs/Kconfig b/fs/Kconfig index a03a7445a4ddf72a9314e889f851df80f429c1f8..8f25c3d43f88334c2312471351875fc97f30caca 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -57,10 +57,12 @@ source fs/fat/Kconfig source fs/nfs/Kconfig source fs/nxffs/Kconfig source fs/romfs/Kconfig +source fs/tmpfs/Kconfig source fs/smartfs/Kconfig source fs/binfs/Kconfig source fs/procfs/Kconfig source fs/unionfs/Kconfig +source fs/hostfs/Kconfig comment "System Logging" diff --git a/fs/Makefile b/fs/Makefile index 9c30b61a97c07f7352cdf003a7eb212633799a30..e60af07ae097179ed85b4edf287007778a4465e2 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -64,12 +64,14 @@ ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) include mount/Make.defs include fat/Make.defs include romfs/Make.defs +include tmpfs/Make.defs include nxffs/Make.defs include nfs/Make.defs include smartfs/Make.defs include binfs/Make.defs include procfs/Make.defs include unionfs/Make.defs +include hostfs/Make.defs endif endif diff --git a/fs/aio/aio_signal.c b/fs/aio/aio_signal.c index 9545a86227eb4fa01b24b60bf0c1cf2f47fa6a35..5a279044c87aeec51f5a290f1e67b8ba684bab12 100644 --- a/fs/aio/aio_signal.c +++ b/fs/aio/aio_signal.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/aio/aio_signal.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,29 +51,10 @@ #ifdef CONFIG_FS_AIO -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ + /**************************************************************************** * Name: aio_signal * @@ -126,6 +107,19 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp) } } +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ + + else if (aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD) + { + ret = sig_notification(pid, &aiocbp->aio_sigevent); + if (ret < 0) + { + fdbg("ERROR: sig_notification failed: %d\n", ret); + } + } +#endif + /* Send the poll signal in any event in case the caller is waiting * on sig_suspend(); */ diff --git a/fs/binfs/fs_binfs.c b/fs/binfs/fs_binfs.c index 52a801560f48cb0489776e9f86e7c59b21f27720..9c03b9530e3abe7dc4ed7ff6c5d1f43803a64798 100644 --- a/fs/binfs/fs_binfs.c +++ b/fs/binfs/fs_binfs.c @@ -93,11 +93,11 @@ static int binfs_stat(FAR struct inode *mountpt, FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly extern'ed there. @@ -171,7 +171,7 @@ static int binfs_open(FAR struct file *filep, FAR const char *relpath, /* Save the index as the open-specific state in filep->f_priv */ - filep->f_priv = (FAR void *)index; + filep->f_priv = (FAR void *)((uintptr_t)index); return OK; } @@ -223,7 +223,7 @@ static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } else { - *ptr = builtin_getname((int)filep->f_priv); + *ptr = builtin_getname((int)((uintptr_t)filep->f_priv)); ret = OK; } } @@ -425,13 +425,14 @@ static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *b /* It's a execute-only file name */ - buf->st_mode = S_IFREG|S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode = S_IFREG | S_IXOTH | S_IXGRP | S_IXUSR; } else { /* It's a read/execute-only directory name */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR | S_IXOTH | + S_IXGRP | S_IXUSR; } /* File/directory size, access block size */ diff --git a/fs/dirent/fs_opendir.c b/fs/dirent/fs_opendir.c index 00876012c6507066f055e5a2008657fe24fa50b6..5731ba632b2d365bb69f673f626da6c45c443bd8 100644 --- a/fs/dirent/fs_opendir.c +++ b/fs/dirent/fs_opendir.c @@ -261,7 +261,7 @@ FAR DIR *opendir(FAR const char *path) if (!inode) { - /* 'path' is not a does not exist.*/ + /* 'path' is not a does not exist. */ ret = ENOTDIR; goto errout_with_semaphore; @@ -274,7 +274,7 @@ FAR DIR *opendir(FAR const char *path) dir = (FAR struct fs_dirent_s *)kumm_zalloc(sizeof(struct fs_dirent_s)); if (!dir) { - /* Insufficient memory to complete the operation.*/ + /* Insufficient memory to complete the operation. */ ret = ENOMEM; goto errout_with_semaphore; @@ -350,7 +350,7 @@ FAR DIR *opendir(FAR const char *path) } inode_semgive(); - return ((DIR*)dir); + return ((FAR DIR *)dir); /* Nasty goto's make error handling simpler */ diff --git a/fs/dirent/fs_seekdir.c b/fs/dirent/fs_seekdir.c index f58274f43abdb29cee88c609b622f9463787f70f..761dba33cd7578a514123d371297c9e6c598f546 100644 --- a/fs/dirent/fs_seekdir.c +++ b/fs/dirent/fs_seekdir.c @@ -68,7 +68,7 @@ static inline void seekpseudodir(struct fs_dirent_s *idir, off_t offset) * "rewind" to the root dir. */ - if ( offset < idir->fd_position ) + if (offset < idir->fd_position) { pos = 0; curr = idir->fd_root; @@ -126,7 +126,7 @@ static inline void seekmountptdir(struct fs_dirent_s *idir, off_t offset) */ inode = idir->fd_root; - if ( offset < idir->fd_position ) + if (offset < idir->fd_position) { if (inode->u.i_mops && inode->u.i_mops->rewinddir) { diff --git a/fs/driver/Make.defs b/fs/driver/Make.defs index 7cf8c344b3faf76e2e6908ca57cf92e39b1953e7..e280ea1580a68cfdd9ad15667b00fb6ad8dd5621 100644 --- a/fs/driver/Make.defs +++ b/fs/driver/Make.defs @@ -41,10 +41,13 @@ CSRCS += fs_registerdriver.c fs_unregisterdriver.c # Don't build-in block driver support if there are no mountpoints - ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c CSRCS += fs_findblockdriver.c fs_openblockdriver.c fs_closeblockdriver.c + +ifneq ($(CONFIG_DISABLE_PSEUDOFS_OPERATIONS),y) +CSRCS += fs_blockproxy.c +endif endif # System logging to a character device (or file) diff --git a/fs/driver/driver.h b/fs/driver/driver.h index 02e98b071af47ba36242c9fa99d6c5fa39180f8b..72ba7318a0d6db45248e91424439fe5df5a7a1af 100644 --- a/fs/driver/driver.h +++ b/fs/driver/driver.h @@ -51,7 +51,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -91,8 +91,43 @@ extern "C" * ****************************************************************************/ +#ifndef CONFIG_DISABLE_MOUNTPOINT int find_blockdriver(FAR const char *pathname, int mountflags, FAR struct inode **ppinode); +#endif + +/* fs/drivers/fs_blockproxy.c ***********************************************/ +/**************************************************************************** + * Name: block_proxy + * + * Description: + * Create a temporary char driver using drivers/bch to mediate character + * oriented accessed to the block driver. + * + * Input parameters: + * blkdev - The path to the block driver + * oflags - Character driver open flags + * + * Returned Value: + * If positive, non-zero file descriptor is returned on success. This + * is the file descriptor of the nameless character driver that mediates + * accesses to the block driver. + * + * Errors that may be returned: + * + * ENOMEM - Failed to create a temporay path name. + * + * Plus: + * + * - Errors reported from bchdev_register() + * - Errors reported from open() or unlink() + * + ****************************************************************************/ + +#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \ + !defined(CONFIG_DISABLE_MOUNTPOINT) +int block_proxy(FAR const char *blkdev, int oflags); +#endif #undef EXTERN #if defined(__cplusplus) diff --git a/fs/driver/fs_blockproxy.c b/fs/driver/fs_blockproxy.c new file mode 100644 index 0000000000000000000000000000000000000000..b01ecc2a88eaf81e4815ca97c41b6ed35c0a1430 --- /dev/null +++ b/fs/driver/fs_blockproxy.c @@ -0,0 +1,246 @@ +/**************************************************************************** + * fs/driver/fs_blockproxy.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \ + !defined(CONFIG_DISABLE_MOUNTPOINT) + +/**************************************************************************** + * Pre-processor oDefinitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t g_devno; +static sem_t g_devno_sem = SEM_INITIALIZER(1); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: unique_chardev + * + * Description: + * Create a unique temporary device name in the /dev/ directory of the + * psuedo-file system. We cannot use mktemp for this because it will + * attempt to open() the file. + * + * Input parameters: + * None + * + * Returned Value: + * The allocated path to the device. This must be released by the caller + * to prevent memory links. NULL will be returned only the case where + * we fail to allocate memory. + * + ****************************************************************************/ + +static FAR char *unique_chardev(void) +{ + struct stat statbuf; + char devbuf[16]; + uint32_t devno; + int ret; + + /* Loop until we get a unique device name */ + + for (; ; ) + { + /* Get the semaphore protecting the path number */ + + while (sem_wait(&g_devno_sem) < 0) + { + DEBUGASSERT(errno == EINTR); + } + + /* Get the next device number and release the semaphore */ + + devno = ++g_devno; + sem_post(&g_devno_sem); + + /* Construct the full device number */ + + devno &= 0xffffff; + snprintf(devbuf, 16, "/dev/tmp%06lx", (unsigned long)devno); + + /* Make sure that file name is not in use */ + + ret = stat(devbuf, &statbuf); + if (ret < 0) + { + DEBUGASSERT(errno == ENOENT); + return strdup(devbuf); + } + + /* It is in use, try again */ + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: block_proxy + * + * Description: + * Create a temporary char driver using drivers/bch to mediate character + * oriented accessed to the block driver. + * + * Input parameters: + * blkdev - The path to the block driver + * oflags - Character driver open flags + * + * Returned Value: + * If positive, non-zero file descriptor is returned on success. This + * is the file descriptor of the nameless character driver that mediates + * accesses to the block driver. + * + * Errors that may be returned: + * + * ENOMEM - Failed to create a temporay path name. + * + * Plus: + * + * - Errors reported from bchdev_register() + * - Errors reported from open() or unlink() + * + ****************************************************************************/ + +int block_proxy(FAR const char *blkdev, int oflags) +{ + FAR char *chardev; + bool readonly; + int ret; + int fd; + + DEBUGASSERT(blkdev); + DEBUGASSERT((oflags & (O_CREAT | O_EXCL | O_APPEND | O_TRUNC)) == 0); + + /* Create a unique temporary file name for the character device */ + + chardev = unique_chardev(); + if (chardev == NULL) + { + fdbg("ERROR: Failed to create temporary device name\n"); + return -ENOMEM; + } + + /* Should this character driver be read-only? */ + + readonly = ((oflags & O_WROK) == 0); + + /* Wrap the block driver with an instance of the BCH driver */ + + ret = bchdev_register(blkdev, chardev, readonly); + if (ret < 0) + { + fdbg("ERROR: bchdev_register(%s, %s) failed: %d\n", + blkdev, chardev, ret); + + goto errout_with_chardev; + } + + /* Open the newly created character driver */ + + oflags &= ~(O_CREAT | O_EXCL | O_APPEND | O_TRUNC); + fd = open(chardev, oflags); + if (fd < 0) + { + ret = -errno; + fdbg("ERROR: Failed to open %s: %d\n", chardev, ret); + goto errout_with_bchdev; + } + + /* Unlink the character device name. The driver instance will persist, + * provided that CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y (otherwise, we have + * a problem here!) + */ + + ret = unlink(chardev); + if (ret < 0) + { + ret = -errno; + fdbg("ERROR: Failed to unlink %s: %d\n", chardev, ret); + } + + /* Free the allocate character driver name and return the open file + * descriptor. + */ + + kmm_free(chardev); + return fd; + +errout_with_bchdev: + (void)unlink(chardev); + +errout_with_chardev: + kmm_free(chardev); + return ret; +} + +#endif /* !CONFIG_DISABLE_PSEUDOFS_OPERATIONS && !CONFIG_DISABLE_MOUNTPOINT */ diff --git a/fs/driver/fs_devsyslog.c b/fs/driver/fs_devsyslog.c index 526a9e0b28920172e2f62bf81b98fa81f510edd8..70b21a2c08219671731d17f87f5b614b99b5148e 100644 --- a/fs/driver/fs_devsyslog.c +++ b/fs/driver/fs_devsyslog.c @@ -61,10 +61,10 @@ * Pre-processor Definitions ****************************************************************************/ - /* Open the device/file write-only, try to create (file) it if it doesn't - * exist, if the file that already exists, then append the new log data to - * end of the file. - */ +/* Open the device/file write-only, try to create (file) it if it doesn't + * exist, if the file that already exists, then append the new log data to + * end of the file. + */ #define SYSLOG_OFLAGS (O_WRONLY | O_CREAT | O_APPEND) @@ -108,7 +108,10 @@ struct syslog_dev_s /* This is the device structure for the console or syslogging function. */ static struct syslog_dev_s g_sysdev; -static const uint8_t g_syscrlf[2] = { '\r', '\n' }; +static const uint8_t g_syscrlf[2] = +{ + '\r', '\n' +}; /**************************************************************************** * Private Functions @@ -348,7 +351,7 @@ int syslog_initialize(void) g_sysdev.sl_state = SYSLOG_OPENED; return OK; - errout_with_inode: +errout_with_inode: inode_release(inode); g_sysdev.sl_state = SYSLOG_FAILURE; return ret; diff --git a/fs/driver/fs_registerblockdriver.c b/fs/driver/fs_registerblockdriver.c index ea611022d307ce2a7c3e8f2fda49ed51b1a204bb..65493c900c0c94a3b0c0ccd2857de91d96889852 100644 --- a/fs/driver/fs_registerblockdriver.c +++ b/fs/driver/fs_registerblockdriver.c @@ -53,11 +53,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -108,7 +108,9 @@ int register_blockdriver(FAR const char *path, ret = inode_reserve(path, &node); if (ret >= 0) { - /* We have it, now populate it with block driver specific information. */ + /* We have it, now populate it with block driver specific information. + * NOTE that the initial reference count on the new inode is zero. + */ INODE_SET_BLOCK(node); diff --git a/fs/driver/fs_registerdriver.c b/fs/driver/fs_registerdriver.c index db635cdfd13f28041e72e1b95e9c20fd5e5bb64b..42c7acf41835518bb118eabb06faf9a7e4c194c5 100644 --- a/fs/driver/fs_registerdriver.c +++ b/fs/driver/fs_registerdriver.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -103,7 +103,9 @@ int register_driver(FAR const char *path, FAR const struct file_operations *fops ret = inode_reserve(path, &node); if (ret >= 0) { - /* We have it, now populate it with driver specific information. */ + /* We have it, now populate it with driver specific information. + * NOTE that the initial reference count on the new inode is zero. + */ INODE_SET_DRIVER(node); diff --git a/fs/driver/fs_unregisterblockdriver.c b/fs/driver/fs_unregisterblockdriver.c index 1669a4d4ed8c9f7495d568901635dbe7a82dae40..b4b775cdf046a0195b372fa3a087ba30e0fb8c7b 100644 --- a/fs/driver/fs_unregisterblockdriver.c +++ b/fs/driver/fs_unregisterblockdriver.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/driver/fs_unregisterdriver.c b/fs/driver/fs_unregisterdriver.c index 96e9e9bae18ee1bf3e2fdc5be9817ffd189dd8a8..b8dec302ed00a9be168ea8c1bc7750c5bed41632 100644 --- a/fs/driver/fs_unregisterdriver.c +++ b/fs/driver/fs_unregisterdriver.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig index d9bd865c3aa7045d2af51850c34fd50c29b9e3ba..1c20a9ddd1c9c81e9da4c3208dda413880b859d2 100644 --- a/fs/fat/Kconfig +++ b/fs/fat/Kconfig @@ -13,6 +13,7 @@ config FS_FAT Enable FAT filesystem support if FS_FAT + config FAT_LCNAMES bool "FAT upper/lower names" default n @@ -49,9 +50,60 @@ config FS_FATTIME much sense in supporting FAT date and time unless you have a hardware RTC or other way to get the time and date. +config FAT_FORCE_INDIRECT + bool "Force direct transfers" + default n + ---help--- + Normally, the default behavior for the FAT file system is to perform + data transfers indirectly though specially allocated sector buffers + or, under certain circumstances, directly through user provided + buffers . These circumstances are: (1) The transfer is being + performed from the beginning of a sector (2) the user-provided + buffer will hold the full sector of data. + + Some hardware, however, may require special DMA-capable memory or + specially aligned memory in order to perform the transfers. In this + case, there may be no circumstance where the user buffer can be used. + Selecting this option will disable all attempts to use the user- + provided buffer: All transfers will be force to be performed + indirectly through the FAT file systems sector buffers. + + Note: This will have the negative impact of: (1) An extra data + copy to transfer the data between the user buffer and the FAT file + systems internal sector buffers, and (2) A loss of performance + because I/O will be limited to one sector at a time. + + This would typically be used with CONFIG_FAT_DMAMEMORY so that + special memory allocators are also used and transfers are also + performed using only that specially allocated memory. + CONFIG_FAT_DMAMEMORY, on the other hand, is often used without + CONFIG_FAT_FORCE_INDIRECT when the user memory buffers may come + from mixed locations, some of which are DMA-able and some of + which are not. But CONFIG_FAT_FORCE_INDIRECT could be used + without CONFIG_FAT_DMAMEMORY if there is, for example, only a + memory aligment constraints. + + FORCE_ DMA DIRECT EXAMPLE USAGE + INDIRECT MEMORY RETRY + Y Y * Use specially allocated memory; + Never use caller provided buffer + Y N * Not recommended + N Y ** Special memory required; user memory + has mixed capability; sometimes + caller memory is not usable + N N Y No special memory but there are + alignment requirements; return is + caller buffer is not properly aligned + N N N User memory can always be used for + transfer. + + * CONFIG_DIRECT_RETRY cannot be selected with CONFIG_FORCE_INDIRECT + ** CONFIG_DIRECT_RETRY is automatically selected with CONFIG_DMA_MEMORY + config FAT_DMAMEMORY bool "DMA memory allocator" default n + select FAT_DIRECT_RETRY if !FAT_FORCE_INDIRECT ---help--- The FAT file system allocates two I/O buffers for data transfer, each are the size of one device sector. One of the buffers is allocated @@ -66,4 +118,66 @@ config FAT_DMAMEMORY corresponding function that will be called to free the DMA-capable memory. -endif + FORCE_ DMA DIRECT EXAMPLE USAGE + INDIRECT MEMORY RETRY + Y Y * Use specially allocated memory; + Never use caller provided buffer + Y N * Not recommended + N Y ** Special memory required; user memory + has mixed capability; sometimes + caller memory is not usable + N N Y No special memory but there are + alignment requirements; return is + caller buffer is not properly aligned + N N N User memory can always be used for + transfer. + + * CONFIG_DIRECT_RETRY cannot be selected with CONFIG_FORCE_INDIRECT + ** CONFIG_DIRECT_RETRY is automatically selected with CONFIG_DMA_MEMORY + +config FAT_DIRECT_RETRY + bool "Direct transfer retry" + default y if FAT_DMAMEMORY + default n if !FAT_DMAMEMORY + depends on !FAT_FORCE_INDIRECT + ---help--- + The FAT file system contains internal, well aligned sector buffers + for indirect data transfer. These transfers are indirect in the + sense that that the actual transfer occurs into/out of the sector + buffers and an additional copy is necessary to/from the user- + provided I/O buffers. But under certain conditions, the FAT file + system will use the caller-provided I/O buffers directly to improve + efficiency. Those conditions are (1) CONFIG_FAT_FORCE_INDIRECT is + not defined, (2) The access is to/from the beginning of a sector, + and (3) the user provided buffer is large enough to hold an entire + sector. + + The lower level SDIO driver may have, certain requirements on the + memory buffer in order to perform the transfer. Perhaps special + DMA memory should be used (with CONFIG_FAT_DMAMEMORY) or perhaps + some special memory alignment is required to interace with the + hardware. + + If this option is selected, then the FAT file system will first + try the user provided I/O buffer under above conditions. If the + transfer fails with -EFAULT. then the FAT file system will try one + more time using the internal sector buffers. + + FORCE_ DMA DIRECT EXAMPLE USAGE + INDIRECT MEMORY RETRY + Y Y * Use specially allocated memory; + Never use caller provided buffer + Y N * Not recommended + N Y ** Special memory required; user memory + has mixed capability; sometimes + caller memory is not usable + N N Y No special memory but there are + alignment requirements; return is + caller buffer is not properly aligned + N N N User memory can always be used for + transfer. + + * CONFIG_DIRECT_RETRY cannot be selected with CONFIG_FORCE_INDIRECT + ** CONFIG_DIRECT_RETRY is automatically selected with CONFIG_DMA_MEMORY + +endif # FAT diff --git a/fs/fat/fs_configfat.c b/fs/fat/fs_configfat.c index 59e174ef58d514841e00a2e283cf80e8ae7d27e3..8fe7c576f2a85183e7eddb16a0e8df55e3fabfd4 100644 --- a/fs/fat/fs_configfat.c +++ b/fs/fat/fs_configfat.c @@ -853,7 +853,7 @@ mkfatfs_clustersearch(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var) } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/fat/fs_fat32.c b/fs/fat/fs_fat32.c index f993e7d6d6c4c81a2e8b5b7bbbc49bfad07b7cce..7fddec4d032e1db69a0a1ff91b6b39ba6c98c0f5 100644 --- a/fs/fat/fs_fat32.c +++ b/fs/fat/fs_fat32.c @@ -118,11 +118,11 @@ static int fat_stat(struct inode *mountpt, const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly extern'ed there. @@ -229,7 +229,7 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath, /* It would be an error if we are asked to create it exclusively */ - if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { /* Already exists -- can't create it exclusively */ @@ -256,7 +256,7 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath, * access is ignored. */ - if ((oflags & (O_TRUNC|O_WRONLY)) == (O_TRUNC|O_WRONLY)) + if ((oflags & (O_TRUNC | O_WRONLY)) == (O_TRUNC | O_WRONLY)) { /* Truncate the file to zero length */ @@ -314,7 +314,7 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath, * file. */ - ff = (struct fat_file_s *)kmm_zalloc(sizeof(struct fat_file_s)); + ff = (FAR struct fat_file_s *)kmm_zalloc(sizeof(struct fat_file_s)); if (!ff) { ret = -ENOMEM; @@ -323,7 +323,7 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath, /* Create a file buffer to support partial sector accesses */ - ff->ff_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize); + ff->ff_buffer = (FAR uint8_t *)fat_io_alloc(fs->fs_hwsectorsize); if (!ff->ff_buffer) { ret = -ENOMEM; @@ -366,7 +366,7 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath, /* In write/append mode, we need to set the file pointer to the end of the file */ - if ((oflags & (O_APPEND|O_WRONLY)) == (O_APPEND|O_WRONLY)) + if ((oflags & (O_APPEND | O_WRONLY)) == (O_APPEND | O_WRONLY)) { off_t offset = fat_seek(filep, ff->ff_size, SEEK_SET); if (offset < 0) @@ -409,17 +409,16 @@ static int fat_close(FAR struct file *filep) /* Recover our private data from the struct file instance */ - ff = filep->f_priv; + ff = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); /* Check for the forced mount condition */ if ((ff->ff_bflags & UMOUNT_FORCED) == 0) { - inode = filep->f_inode; - fs = inode->i_private; - - DEBUGASSERT(fs != NULL); - /* Do not check if the mount is healthy. We must support closing of * the file even when there is healthy mount. */ @@ -479,13 +478,16 @@ static ssize_t fat_read(FAR struct file *filep, FAR char *buffer, FAR struct fat_file_s *ff; unsigned int bytesread; unsigned int readsize; - unsigned int nsectors; size_t bytesleft; int32_t cluster; - FAR uint8_t *userbuffer = (uint8_t*)buffer; + FAR uint8_t *userbuffer = (FAR uint8_t *)buffer; int sectorindex; int ret; + +#ifndef CONFIG_FAT_FORCE_INDIRECT + unsigned int nsectors; bool force_indirect = false; +#endif /* Sanity checks */ @@ -586,10 +588,11 @@ static ssize_t fat_read(FAR struct file *filep, FAR char *buffer, ff->ff_sectorsincluster = fs->fs_fatsecperclus; } -#ifdef CONFIG_FAT_DMAMEMORY /* Warning avoidance */ +#ifdef CONFIG_FAT_DIRECT_RETRY /* Warning avoidance */ fat_read_restart: #endif +#ifndef CONFIG_FAT_FORCE_INDIRECT /* Check if the user has provided a buffer large enough to hold one * or more complete sectors -AND- the read is aligned to a sector * boundary. @@ -622,21 +625,22 @@ fat_read_restart: ret = fat_hwread(fs, userbuffer, ff->ff_currentsector, nsectors); if (ret < 0) { -#ifdef CONFIG_FAT_DMAMEMORY +#ifdef CONFIG_FAT_DIRECT_RETRY /* The low-level driver may return -EFAULT in the case where - * the transfer cannot be performed due to DMA constraints. - * It is probable that the buffer is completely un-DMA-able, - * so force indirect transfers via the sector buffer and - * restart the operation. + * the transfer cannot be performed due to buffer memory + * constraints. It is probable that the buffer is completely + * un-DMA-able or improperly aligned. In this case, force + * indirect transfers via the sector buffer and restart the + * operation (unless we have already tried that). */ - if (ret == -EFAULT) + if (ret == -EFAULT && !force_indirect) { fdbg("DMA: read alignment error, restarting indirect\n"); force_indirect = true; goto fat_read_restart; } -#endif +#endif /* CONFIG_FAT_DIRECT_RETRY */ goto errout_with_semaphore; } @@ -646,6 +650,7 @@ fat_read_restart: bytesread = nsectors * fs->fs_hwsectorsize; } else +#endif /* CONFIG_FAT_FORCE_INDIRECT */ { /* We are reading a partial sector, or handling a non-DMA-able * whole-sector transfer. First, read the whole sector @@ -709,11 +714,14 @@ static ssize_t fat_write(FAR struct file *filep, FAR const char *buffer, int32_t cluster; unsigned int byteswritten; unsigned int writesize; - unsigned int nsectors; - FAR uint8_t *userbuffer = (uint8_t*)buffer; + FAR uint8_t *userbuffer = (FAR uint8_t *)buffer; int sectorindex; int ret; + +#ifndef CONFIG_FAT_FORCE_INDIRECT + unsigned int nsectors; bool force_indirect = false; +#endif /* Sanity checks. I have seen the following assertion misfire if * CONFIG_DEBUG_MM is enabled while re-directing output to a @@ -840,10 +848,11 @@ static ssize_t fat_write(FAR struct file *filep, FAR const char *buffer, ff->ff_currentsector = fat_cluster2sector(fs, cluster); } -#ifdef CONFIG_FAT_DMAMEMORY /* Warning avoidance */ +#ifdef CONFIG_FAT_DIRECT_RETRY /* Warning avoidance */ fat_write_restart: #endif +#ifndef CONFIG_FAT_FORCE_INDIRECT /* Check if the user has provided a buffer large enough to * hold one or more complete sectors. */ @@ -876,21 +885,22 @@ fat_write_restart: ret = fat_hwwrite(fs, userbuffer, ff->ff_currentsector, nsectors); if (ret < 0) { -#ifdef CONFIG_FAT_DMAMEMORY +#ifdef CONFIG_FAT_DIRECT_RETRY /* The low-level driver may return -EFAULT in the case where - * the transfer cannot be performed due to DMA constraints. - * It is probable that the buffer is completely un-DMA-able, - * so force indirect transfers via the sector buffer and - * restart the operation. + * the transfer cannot be performed due to buffer memory + * constraints. It is probable that the buffer is completely + * un-DMA-able or improperly aligned. In this case, force + * indirect transfers via the sector buffer and restart the + * operation (unless we have already tried that). */ - if (ret == -EFAULT) + if (ret == -EFAULT && !force_indirect) { fdbg("DMA: write alignment error, restarting indirect\n"); force_indirect = true; goto fat_write_restart; } -#endif +#endif /* CONFIG_FAT_DIRECT_RETRY */ goto errout_with_semaphore; } @@ -901,6 +911,7 @@ fat_write_restart: ff->ff_bflags |= FFBUFF_MODIFIED; } else +#endif /* CONFIG_FAT_FORCE_INDIRECT */ { /* Decide whether we are performing a read-modify-write * operation, in which case we have to read the existing sector @@ -970,7 +981,7 @@ fat_write_restart: */ memcpy(&ff->ff_buffer[sectorindex], userbuffer, writesize); - ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED); + ff->ff_bflags |= (FFBUFF_DIRTY | FFBUFF_VALID | FFBUFF_MODIFIED); } /* Set up for the next write */ @@ -1119,7 +1130,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence) */ clustersize = fs->fs_fatsecperclus * fs->fs_hwsectorsize; - for (;;) + for (; ; ) { /* Skip over clusters prior to the one containing * the requested position. @@ -1436,7 +1447,7 @@ static int fat_dup(FAR const struct file *oldp, FAR struct file *newp) * dup'ed file. */ - newff = (struct fat_file_s *)kmm_malloc(sizeof(struct fat_file_s)); + newff = (FAR struct fat_file_s *)kmm_malloc(sizeof(struct fat_file_s)); if (!newff) { ret = -ENOMEM; @@ -1445,7 +1456,7 @@ static int fat_dup(FAR const struct file *oldp, FAR struct file *newp) /* Create a file buffer to support partial sector accesses */ - newff->ff_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize); + newff->ff_buffer = (FAR uint8_t *)fat_io_alloc(fs->fs_hwsectorsize); if (!newff->ff_buffer) { ret = -ENOMEM; @@ -1873,7 +1884,7 @@ static int fat_bind(FAR struct inode *blkdriver, FAR const void *data, return ret; } - *handle = (void*)fs; + *handle = (FAR void *)fs; fat_semgive(fs); return OK; } @@ -1889,7 +1900,7 @@ static int fat_bind(FAR struct inode *blkdriver, FAR const void *data, static int fat_unbind(FAR void *handle, FAR struct inode **blkdriver, unsigned int flags) { - FAR struct fat_mountpt_s *fs = (FAR struct fat_mountpt_s*)handle; + FAR struct fat_mountpt_s *fs = (FAR struct fat_mountpt_s *)handle; if (!fs) { @@ -2525,7 +2536,8 @@ static int fat_stat(FAR struct inode *mountpt, FAR const char *relpath, { /* It's directory name of the mount point */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IWOTH|S_IWGRP|S_IWUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | + S_IWGRP | S_IWUSR; ret = OK; goto errout_with_semaphore; } @@ -2544,10 +2556,10 @@ static int fat_stat(FAR struct inode *mountpt, FAR const char *relpath, * by everyone but may be writeable by no-one. */ - buf->st_mode = S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; if ((attribute & FATATTR_READONLY) == 0) { - buf->st_mode |= S_IWOTH|S_IWGRP|S_IWUSR; + buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR; } /* We will report only types file or directory */ diff --git a/fs/fat/fs_fat32.h b/fs/fat/fs_fat32.h index cfb97f37d88352196ac1e44a683c24cf70e7caf7..5b13b0a6c2a481a762148acc0a6bb352a80cc80f 100644 --- a/fs/fat/fs_fat32.h +++ b/fs/fat/fs_fat32.h @@ -495,7 +495,7 @@ # define LDIR_GETWCHAR6(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11)) # define LDIR_GETWCHAR7(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+2)) # define LDIR_GETWCHAR8(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+4)) -# define LDIR_GETWCHAR8(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+6)) +# define LDIR_GETWCHAR9(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+6)) # define LDIR_GETWCHAR10(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+8)) # define LDIR_GETWCHAR11(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+10)) # define LDIR_GETWCHAR12(p) fat_getuint16(UBYTE_PTR(p,LDIR_WCHAR12_13)) @@ -550,7 +550,7 @@ # define LDIR_PUTWCHAR6(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11),v) # define LDIR_PUTWCHAR7(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+2),v) # define LDIR_PUTWCHAR8(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+4),v) -# define LDIR_PUTWCHAR8(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+6),v) +# define LDIR_PUTWCHAR9(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+6),v) # define LDIR_PUTWCHAR10(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+8),v) # define LDIR_PUTWCHAR11(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR6_11+10),v) # define LDIR_PUTWCHAR12(p) fat_putuint16(UBYTE_PTR(p,LDIR_WCHAR12_13),v) @@ -770,7 +770,7 @@ struct fat_file_s uint8_t *ff_buffer; /* File buffer (for partial sector accesses) */ }; -/* This structure holds the sequency of directory entries used by one +/* This structure holds the sequence of directory entries used by one * file element (directory or file). For short file names, this is * single diretory entry. But for long file names, the is a sequence * of directory entries. Long directory name entries appear in reverse @@ -847,7 +847,7 @@ struct fat_dirinfo_s #endif /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/fat/fs_fat32attrib.c b/fs/fat/fs_fat32attrib.c index b79e5275eb5c0f70cd01641559546a76278031aa..ef9b90b474584a7f133fa0cb4fa642bd9179aec4 100644 --- a/fs/fat/fs_fat32attrib.c +++ b/fs/fat/fs_fat32attrib.c @@ -128,8 +128,10 @@ static int fat_attrib(const char *path, fat_attrib_t *retattrib, /* Set or clear any bits as requested */ - newattributes &= ~(clearbits & (FATATTR_READONLY|FATATTR_HIDDEN|FATATTR_SYSTEM|FATATTR_ARCHIVE)); - newattributes |= (setbits & (FATATTR_READONLY|FATATTR_HIDDEN|FATATTR_SYSTEM|FATATTR_ARCHIVE)); + newattributes &= ~(clearbits & (FATATTR_READONLY | FATATTR_HIDDEN | + FATATTR_SYSTEM | FATATTR_ARCHIVE)); + newattributes |= (setbits & (FATATTR_READONLY | FATATTR_HIDDEN | + FATATTR_SYSTEM | FATATTR_ARCHIVE)); /* Did any thingchange? */ @@ -166,7 +168,7 @@ errout: } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/fat/fs_fat32dirent.c b/fs/fat/fs_fat32dirent.c index c52de5e86a40ba227e33c4372f82099a195f6320..98a37e31988fb921e7f91d7b3558849973bd9e71 100644 --- a/fs/fat/fs_fat32dirent.c +++ b/fs/fat/fs_fat32dirent.c @@ -156,11 +156,11 @@ static int fat_putsfdirentry(struct fat_mountpt_s *fs, uint8_t attributes, uint32_t fattime); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -271,7 +271,7 @@ static inline int fat_parsesfname(const char **path, /* Loop until the name is successfully parsed or an error occurs */ endndx = 8; - for (;;) + for (; ; ) { /* Get the next byte from the path */ @@ -279,7 +279,7 @@ static inline int fat_parsesfname(const char **path, /* Check if this the last byte in this node of the name */ - if ((ch == '\0' || ch == '/') && ndx != 0 ) + if ((ch == '\0' || ch == '/') && ndx != 0) { /* Return the accumulated NT flags and the terminating character */ @@ -348,12 +348,12 @@ static inline int fat_parsesfname(const char **path, goto errout; } - /* So far, only upper case in the name*/ + /* So far, only upper case in the name */ namecase = FATCASE_UPPER; #endif - /* Clear lower case name bit in mask*/ + /* Clear lower case name bit in mask */ ntlcenable &= ~FATNTRES_LCNAME; } @@ -369,7 +369,7 @@ static inline int fat_parsesfname(const char **path, goto errout; } - /* So far, only upper case in the extension*/ + /* So far, only upper case in the extension */ extcase = FATCASE_UPPER; #endif @@ -415,7 +415,7 @@ static inline int fat_parsesfname(const char **path, goto errout; } - /* So far, only lower case in the name*/ + /* So far, only lower case in the name */ namecase = FATCASE_LOWER; #endif @@ -436,7 +436,7 @@ static inline int fat_parsesfname(const char **path, goto errout; } - /* So far, only lower case in the extension*/ + /* So far, only lower case in the extension */ extcase = FATCASE_LOWER; #endif @@ -463,7 +463,7 @@ static inline int fat_parsesfname(const char **path, dirinfo->fd_name[ndx++] = ch; } - errout: +errout: return -EINVAL; } @@ -503,7 +503,7 @@ static inline int fat_parselfname(const char **path, /* Loop until the name is successfully parsed or an error occurs */ - for (;;) + for (; ; ) { /* Get the next byte from the path */ @@ -511,7 +511,7 @@ static inline int fat_parselfname(const char **path, /* Check if this the last byte in this node of the name */ - if ((ch == '\0' || ch == '/') && ndx != 0 ) + if ((ch == '\0' || ch == '/') && ndx != 0) { /* Null terminate the string */ @@ -552,7 +552,7 @@ static inline int fat_parselfname(const char **path, dirinfo->fd_lfname[ndx++] = ch; } - errout: +errout: dirinfo->fd_lfname[0] = '\0'; return -EINVAL; } @@ -594,8 +594,8 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo) /* First, let's decide what is name and what is extension */ - len = strlen((char*)dirinfo->fd_lfname); - ext = strrchr((char*)dirinfo->fd_lfname, '.'); + len = strlen((FAR char *)dirinfo->fd_lfname); + ext = strrchr((FAR char *)dirinfo->fd_lfname, '.'); if (ext) { ptrdiff_t tmp; @@ -604,7 +604,7 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo) * beginning of the string is then the name length. */ - tmp = ext - (char*)dirinfo->fd_lfname; + tmp = ext - (FAR char *)dirinfo->fd_lfname; namechars = tmp; /* And the rest, excluding the '.' is the extension. */ @@ -656,7 +656,7 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo) } else { - src = (char*)dirinfo->fd_lfname; + src = (FAR char *)dirinfo->fd_lfname; } /* Then copy the name and extension, handling upper case conversions and @@ -666,7 +666,7 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo) ndx = 0; /* Position to write the next name character */ endndx = 6; /* Maximum index before we write ~! and switch to the extension */ - for (;;) + for (; ; ) { /* Get the next byte from the path. Break out of the loop if we * encounter the end of null-terminated the long file name string. @@ -991,7 +991,7 @@ static int fat_findsfnentry(struct fat_mountpt_s *fs, * the matching short name */ - for (;;) + for (; ; ) { /* Read the next sector into memory */ @@ -1017,7 +1017,7 @@ static int fat_findsfnentry(struct fat_mountpt_s *fs, if (direntry[DIR_NAME] != DIR0_EMPTY && !(DIR_GETATTRIBUTES(direntry) & FATATTR_VOLUMEID) && - !memcmp(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME) ) + !memcmp(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME)) { /* Yes.. Return success */ @@ -1085,7 +1085,7 @@ static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk) * should match the ASCII code. */ - wch = (wchar_t)fat_getuint16((uint8_t*)chunk); + wch = (wchar_t)fat_getuint16((FAR uint8_t *)chunk); if ((wch & 0xff) != (wchar_t)ch) { return false; @@ -1130,7 +1130,7 @@ static bool fat_cmplfname(const uint8_t *direntry, const uint8_t *substr) * terminator). */ - len = strlen((char*)substr) + 1; + len = strlen((FAR char *)substr) + 1; /* Check bytes 1-5 */ @@ -1186,7 +1186,7 @@ static inline int fat_findlfnentry(struct fat_mountpt_s *fs, * LDIR_MAXFNAME+1 we do not have to check the length of the string). */ - namelen = strlen((char*)dirinfo->fd_lfname); + namelen = strlen((FAR char *)dirinfo->fd_lfname); DEBUGASSERT(namelen <= LDIR_MAXFNAME+1); /* How many LFN directory entries are we expecting? */ @@ -1219,7 +1219,7 @@ static inline int fat_findlfnentry(struct fat_mountpt_s *fs, * the match shore name */ - for (;;) + for (; ; ) { /* Read the next sector into memory */ @@ -1406,7 +1406,7 @@ static inline int fat_allocatesfnentry(struct fat_mountpt_s *fs, /* Then search for a free short file name directory entry */ - for (;;) + for (; ; ) { /* Read the directory sector into fs_buffer */ @@ -1518,7 +1518,7 @@ static inline int fat_allocatelfnentry(struct fat_mountpt_s *fs, */ needed = nentries; - for (;;) + for (; ; ) { /* Read the directory sector into fs_buffer */ @@ -1613,111 +1613,111 @@ static inline int fat_getsfname(uint8_t *direntry, char *buffer, unsigned int buflen) { #ifdef CONFIG_FAT_LCNAMES - uint8_t ntflags; + uint8_t ntflags; #endif - int ch; - int ndx; + int ch; + int ndx; - /* Check if we will be doing upper to lower case conversions */ + /* Check if we will be doing upper to lower case conversions */ #ifdef CONFIG_FAT_LCNAMES - ntflags = DIR_GETNTRES(direntry); + ntflags = DIR_GETNTRES(direntry); #endif - /* Reserve a byte for the NUL terminator */ + /* Reserve a byte for the NUL terminator */ - buflen--; + buflen--; - /* Get the 8-byte filename */ + /* Get the 8-byte filename */ - for (ndx = 0; ndx < 8 && buflen > 0; ndx++) - { - /* Get the next filename character from the directory entry */ + for (ndx = 0; ndx < 8 && buflen > 0; ndx++) + { + /* Get the next filename character from the directory entry */ - ch = direntry[ndx]; + ch = direntry[ndx]; - /* Any space (or ndx==8) terminates the filename */ + /* Any space (or ndx==8) terminates the filename */ - if (ch == ' ') - { - break; - } + if (ch == ' ') + { + break; + } - /* In this version, we never write 0xe5 in the directory filenames - * (because we do not handle any character sets where 0xe5 is valid - * in a filaname), but we could encounted this in a filesystem - * written by some other system - */ + /* In this version, we never write 0xe5 in the directory filenames + * (because we do not handle any character sets where 0xe5 is valid + * in a filaname), but we could encounted this in a filesystem + * written by some other system + */ - if (ndx == 0 && ch == DIR0_E5) - { - ch = 0xe5; - } + if (ndx == 0 && ch == DIR0_E5) + { + ch = 0xe5; + } - /* Check if we should perform upper to lower case conversion - * of the (whole) filename. - */ + /* Check if we should perform upper to lower case conversion + * of the (whole) filename. + */ #ifdef CONFIG_FAT_LCNAMES - if (ntflags & FATNTRES_LCNAME && isupper(ch)) - { - ch = tolower(ch); - } + if (ntflags & FATNTRES_LCNAME && isupper(ch)) + { + ch = tolower(ch); + } #endif - /* Copy the next character into the filename */ + /* Copy the next character into the filename */ - *buffer++ = ch; - buflen--; - } + *buffer++ = ch; + buflen--; + } - /* Check if there is an extension */ + /* Check if there is an extension */ - if (direntry[8] != ' ' && buflen > 0) - { - /* Yes, output the dot before the extension */ + if (direntry[8] != ' ' && buflen > 0) + { + /* Yes, output the dot before the extension */ - *buffer++ = '.'; - buflen--; + *buffer++ = '.'; + buflen--; - /* Then output the (up to) 3 character extension */ + /* Then output the (up to) 3 character extension */ - for (ndx = 8; ndx < 11 && buflen > 0; ndx++) - { - /* Get the next extensions character from the directory entry */ + for (ndx = 8; ndx < 11 && buflen > 0; ndx++) + { + /* Get the next extensions character from the directory entry */ - ch = direntry[DIR_NAME + ndx]; + ch = direntry[DIR_NAME + ndx]; - /* Any space (or ndx==11) terminates the extension */ + /* Any space (or ndx==11) terminates the extension */ - if (ch == ' ') - { - break; - } + if (ch == ' ') + { + break; + } - /* Check if we should perform upper to lower case conversion - * of the (whole) filename. - */ + /* Check if we should perform upper to lower case conversion + * of the (whole) filename. + */ #ifdef CONFIG_FAT_LCNAMES - if (ntflags & FATNTRES_LCEXT && isupper(ch)) - { - ch = tolower(ch); - } + if (ntflags & FATNTRES_LCEXT && isupper(ch)) + { + ch = tolower(ch); + } #endif - /* Copy the next character into the filename */ + /* Copy the next character into the filename */ - *buffer++ = ch; - buflen--; - } - } + *buffer++ = ch; + buflen--; + } + } - /* Put a null terminator at the end of the filename. We don't have to - * check if there is room because we reserved a byte for the NUL - * terminator at the beginning of this function. - */ + /* Put a null terminator at the end of the filename. We don't have to + * check if there is room because we reserved a byte for the NUL + * terminator at the beginning of this function. + */ - *buffer = '\0'; - return OK; + *buffer = '\0'; + return OK; } /**************************************************************************** @@ -1798,7 +1798,7 @@ static inline int fat_getlfname(struct fat_mountpt_s *fs, struct fs_dirent_s *di /* Loop until the whole file name has been transferred */ - for (;;) + for (; ; ) { /* Get the string offset associated with the "last" entry. */ @@ -2028,7 +2028,7 @@ static int fat_putlfname(struct fat_mountpt_s *fs, * LDIR_MAXLFNCHARS (13). */ - namelen = strlen((char*)dirinfo->fd_lfname); + namelen = strlen((FAR char *)dirinfo->fd_lfname); DEBUGASSERT(namelen <= LDIR_MAXFNAME+1); /* How many LFN directory entries do we need to write? */ @@ -2093,7 +2093,7 @@ static int fat_putlfname(struct fat_mountpt_s *fs, /* Now loop, writing each long file name entry */ - for (;;) + for (; ; ) { /* Get the string offset associated with the directory entry. */ @@ -2314,7 +2314,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo, /* Now loop until the directory entry corresponding to the path is found */ - for (;;) + for (; ; ) { /* Convert the next the path segment name into the kind of name that * we would see in the directory entry. @@ -2441,7 +2441,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, * or until to fail to extend the directory cluster chain. */ - for (;;) + for (; ; ) { /* Can this cluster chain be extended */ @@ -2520,9 +2520,9 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, return cluster; } - /* Flush out any cached data in fs_buffer.. we are going to use - * it to initialize the new directory cluster. - */ + /* Flush out any cached data in fs_buffer.. we are going to use + * it to initialize the new directory cluster. + */ ret = fat_fscacheflush(fs); if (ret < 0) @@ -2591,7 +2591,7 @@ int fat_freedirentry(struct fat_mountpt_s *fs, struct fat_dirseq_s *seq) * and for the single short file name entry. */ - for (;;) + for (; ; ) { /* Read the directory sector into the sector cache */ @@ -2896,7 +2896,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, bool directory) * (2) the directory is found to be empty, or (3) some error occurs. */ - for (;;) + for (; ; ) { unsigned int subdirindex; uint8_t *subdirentry; diff --git a/fs/fat/fs_fat32util.c b/fs/fat/fs_fat32util.c index ac2f53365c2879821ce0ee0ae1f6e6e04144a1d5..604b9ca07b34b06f468b64cdd3538ed7c71f6c59 100644 --- a/fs/fat/fs_fat32util.c +++ b/fs/fat/fs_fat32util.c @@ -76,11 +76,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -322,9 +322,9 @@ uint32_t fat_getuint32(uint8_t *ptr) * Name: fat_putuint16 ****************************************************************************/ -void fat_putuint16(uint8_t *ptr, uint16_t value16) +void fat_putuint16(FAR uint8_t *ptr, uint16_t value16) { - uint8_t *val = (uint8_t*)&value16; + FAR uint8_t *val = (FAR uint8_t *)&value16; #ifdef CONFIG_ENDIAN_BIG /* If the target is big-endian then the bytes always have to be swapped so @@ -348,9 +348,9 @@ void fat_putuint16(uint8_t *ptr, uint16_t value16) * Name: fat_putuint32 ****************************************************************************/ -void fat_putuint32(uint8_t *ptr, uint32_t value32) +void fat_putuint32(FAR uint8_t *ptr, uint32_t value32) { - uint16_t *val = (uint16_t*)&value32; + FAR uint16_t *val = (FAR uint16_t *)&value32; #ifdef CONFIG_ENDIAN_BIG /* If the target is big-endian then the bytes always have to be swapped so @@ -554,7 +554,7 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable) /* Allocate a buffer to hold one hardware sector */ - fs->fs_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize); + fs->fs_buffer = (FAR uint8_t *)fat_io_alloc(fs->fs_hwsectorsize); if (!fs->fs_buffer) { ret = -ENOMEM; @@ -585,12 +585,12 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable) * indexed by 16x the partition number. */ - int i; - for (i = 0; i < 4; i++) - { - /* Check if the partition exists and, if so, get the bootsector for that - * partition and see if we can find the boot record there. - */ + int i; + for (i = 0; i < 4; i++) + { + /* Check if the partition exists and, if so, get the bootsector for that + * partition and see if we can find the boot record there. + */ uint8_t part = PART_GETTYPE(i, fs->fs_buffer); fvdbg("Partition %d, offset %d, type %d\n", i, PART_ENTRY(i), part); @@ -683,11 +683,11 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable) return OK; - errout_with_buffer: +errout_with_buffer: fat_io_free(fs->fs_buffer, fs->fs_hwsectorsize); fs->fs_buffer = 0; - errout: +errout: fs->fs_mounted = false; return ret; } @@ -748,7 +748,7 @@ int fat_hwread(struct fat_mountpt_s *fs, uint8_t *buffer, off_t sector, unsigned int nsectors) { int ret = -ENODEV; - if (fs && fs->fs_blkdriver ) + if (fs && fs->fs_blkdriver) { struct inode *inode = fs->fs_blkdriver; if (inode && inode->u.i_bops && inode->u.i_bops->read) @@ -781,7 +781,7 @@ int fat_hwwrite(struct fat_mountpt_s *fs, uint8_t *buffer, off_t sector, unsigned int nsectors) { int ret = -ENODEV; - if (fs && fs->fs_blkdriver ) + if (fs && fs->fs_blkdriver) { struct inode *inode = fs->fs_blkdriver; if (inode && inode->u.i_bops && inode->u.i_bops->write) @@ -811,7 +811,7 @@ int fat_hwwrite(struct fat_mountpt_s *fs, uint8_t *buffer, off_t sector, * ****************************************************************************/ -off_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32_t cluster ) +off_t fat_cluster2sector(FAR struct fat_mountpt_s *fs, uint32_t cluster) { cluster -= 2; if (cluster >= fs->fs_nclusters - 2) @@ -993,7 +993,7 @@ int fat_putcluster(struct fat_mountpt_s *fs, uint32_t clusterno, /* Make sure that the sector at this offset is in the cache */ - if (fat_fscacheread(fs, fatsector)< 0) + if (fat_fscacheread(fs, fatsector) < 0) { /* Read error */ @@ -1239,7 +1239,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, uint32_t cluster) */ newcluster = startcluster; - for (;;) + for (; ; ) { /* Examine the next cluster in the FAT */ @@ -1303,7 +1303,7 @@ int32_t fat_extendchain(struct fat_mountpt_s *fs, uint32_t cluster) return ret; } - /* And link if to the start cluster (if any)*/ + /* And link if to the start cluster (if any) */ if (cluster) { @@ -1563,29 +1563,29 @@ int fat_fscacheread(struct fat_mountpt_s *fs, off_t sector) * we do nothing. Otherwise, we will have to read the new sector. */ - if (fs->fs_currentsector != sector) - { - /* We will need to read the new sector. First, flush the cached - * sector if it is dirty. - */ + if (fs->fs_currentsector != sector) + { + /* We will need to read the new sector. First, flush the cached + * sector if it is dirty. + */ - ret = fat_fscacheflush(fs); - if (ret < 0) - { - return ret; - } + ret = fat_fscacheflush(fs); + if (ret < 0) + { + return ret; + } - /* Then read the specified sector into the cache */ + /* Then read the specified sector into the cache */ - ret = fat_hwread(fs, fs->fs_buffer, sector, 1); - if (ret < 0) - { - return ret; - } + ret = fat_hwread(fs, fs->fs_buffer, sector, 1); + if (ret < 0) + { + return ret; + } - /* Update the cached sector number */ + /* Update the cached sector number */ - fs->fs_currentsector = sector; + fs->fs_currentsector = sector; } return OK; @@ -1608,7 +1608,8 @@ int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff) */ if (ff->ff_cachesector && - (ff->ff_bflags & (FFBUFF_DIRTY|FFBUFF_VALID)) == (FFBUFF_DIRTY|FFBUFF_VALID)) + (ff->ff_bflags & (FFBUFF_DIRTY | FFBUFF_VALID)) == + (FFBUFF_DIRTY | FFBUFF_VALID)) { /* Write the dirty sector */ @@ -1875,7 +1876,7 @@ int fat_currentsector(struct fat_mountpt_s *fs, struct fat_file_s *ff, { int sectoroffset; - if (position <= ff->ff_size ) + if (position <= ff->ff_size) { /* sectoroffset is the sector number offset into the current cluster */ @@ -1883,7 +1884,7 @@ int fat_currentsector(struct fat_mountpt_s *fs, struct fat_file_s *ff, /* The current cluster is the first sector of the cluster plus * the sector offset - */ + */ ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster) + sectoroffset; diff --git a/fs/fat/fs_mkfatfs.c b/fs/fat/fs_mkfatfs.c index 08eb618c2b5a24ffd6f5cd31fbc6ffe6bda96b48..a1f17d737455d87cfabdc39c70da2472f8c27e71 100644 --- a/fs/fat/fs_mkfatfs.c +++ b/fs/fat/fs_mkfatfs.c @@ -299,9 +299,9 @@ int mkfatfs(FAR const char *pathname, FAR struct fat_format_s *fmt) /* Allocate a buffer that will be working sector memory */ #ifdef CONFIG_FAT_DMAMEMORY - var.fv_sect = (uint8_t*)fat_dma_alloc(var.fv_sectorsize); + var.fv_sect = (FAR uint8_t *)fat_dma_alloc(var.fv_sectorsize); #else - var.fv_sect = (uint8_t*)kmm_malloc(var.fv_sectorsize); + var.fv_sect = (FAR uint8_t *)kmm_malloc(var.fv_sectorsize); #endif if (!var.fv_sect) diff --git a/fs/fat/fs_mkfatfs.h b/fs/fat/fs_mkfatfs.h index d9212b1e4bccb6ac0c9359127ab316f5e95b8594..1e1fc05e158620da484661f0c74e1645952b19aa 100644 --- a/fs/fat/fs_mkfatfs.h +++ b/fs/fat/fs_mkfatfs.h @@ -110,7 +110,7 @@ struct fat_var_s }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/fat/fs_writefat.c b/fs/fat/fs_writefat.c index f994d49efe9714cc3ab648f1864f9402c64aefde..a484cbac6731c73c9f73689722744c5b5d896c09 100644 --- a/fs/fat/fs_writefat.c +++ b/fs/fat/fs_writefat.c @@ -81,7 +81,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt, /* 8@3: Usually "MSWIN4.1" */ - strcpy((char*)&var->fv_sect[BS_OEMNAME], "NUTTX "); + strcpy((FAR char *)&var->fv_sect[BS_OEMNAME], "NUTTX "); /* 2@11: Bytes per sector: 512, 1024, 2048, 4096 */ @@ -177,7 +177,7 @@ static inline void mkfatfs_initmbr(FAR struct fat_format_s *fmt, MBR_PUTFATSZ32(var->fv_sect, var->fv_nfatsects); - /* 2@40: 0-3:Active FAT, 7=0 both FATS, 7=1 one FAT -- left zero*/ + /* 2@40: 0-3:Active FAT, 7=0 both FATS, 7=1 one FAT -- left zero */ /* 2@42: MSB:Major LSB:Minor revision number (0.0) -- left zero */ /* 4@44: Cluster no. of 1st cluster of root dir */ @@ -333,7 +333,7 @@ static inline int mkfatfs_writembr(FAR struct fat_format_s *fmt, /* Write all of the reserved sectors */ memset(var->fv_sect, 0, var->fv_sectorsize); - for (sectno = 1; sectno < fmt->ff_rsvdseccount && ret >= 0; sectno++) + for (sectno = 1; sectno < fmt->ff_rsvdseccount && ret >= 0; sectno++) { ret = DEV_WRITE(var->fv_sect, sectno, 1); } @@ -357,7 +357,7 @@ static inline int mkfatfs_writembr(FAR struct fat_format_s *fmt, if (ret >= 0) { - /* Create an image of the fsinfo sector*/ + /* Create an image of the fsinfo sector */ mkfatfs_initfsinfo(fmt, var); @@ -408,7 +408,7 @@ static inline int mkfatfs_writefat(FAR struct fat_format_s *fmt, if (sectno == 0) { memset(var->fv_sect, 0, var->fv_sectorsize); - switch(fmt->ff_fattype) + switch (fmt->ff_fattype) { case 12: /* Mark the first two full FAT entries -- 24 bits, 3 bytes total */ @@ -498,7 +498,7 @@ static inline int mkfatfs_writerootdir(FAR struct fat_format_s *fmt, } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/hostfs/Kconfig b/fs/hostfs/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ab2abc12fb9b9c369201a11398e668b36d8a8180 --- /dev/null +++ b/fs/hostfs/Kconfig @@ -0,0 +1,24 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config FS_HOSTFS + bool "Host File System" + default n + depends on !DISABLE_MOUNTPOINT + depends on ARCH_SIM + select FS_READABLE + select FS_WRITABLE + ---help--- + The Host file system provides a mechanism to mount directories + from the host OS during simulation mode. The host directory + to be "mounted" is specified during the mount command using + the -o command line switch, such as: + + mount -t hostfs -o fs=/home/user/nuttx_root /host + + For non-NSH operation, the option "fs=home/user/nuttx_root" would + be passed to the 'mount()' routine using the optional 'void *data' + parameter. + diff --git a/fs/hostfs/Make.defs b/fs/hostfs/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..441221d29819be9dbe84f98aa7dcab5e4fb2ed9d --- /dev/null +++ b/fs/hostfs/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# Make.defs +# +# Copyright (C) 2015 Ken Pettit. All rights reserved. +# Author: Ken Pettit +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_FS_HOSTFS),y) + +# Files required for HostFS file system support + +ASRCS += +CSRCS += hostfs.c + +# Include HOSTFS build support + +DEPPATH += --dep-path hostfs +VPATH += :hostfs + +endif diff --git a/fs/hostfs/hostfs.c b/fs/hostfs/hostfs.c new file mode 100644 index 0000000000000000000000000000000000000000..f3701273e4529cddc5903d6cfb26eff37092c585 --- /dev/null +++ b/fs/hostfs/hostfs.c @@ -0,0 +1,1218 @@ +/**************************************************************************** + * nuttx/fs/hostfs/hostfs.c + * + * Copyright (C) 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "hostfs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int hostfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int hostfs_close(FAR struct file *filep); +static ssize_t hostfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t hostfs_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static off_t hostfs_seek(FAR struct file *filep, off_t offset, + int whence); +static int hostfs_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +static int hostfs_sync(FAR struct file *filep); +static int hostfs_dup(FAR const struct file *oldp, + FAR struct file *newp); + +static int hostfs_opendir(FAR struct inode *mountpt, + FAR const char *relpath, + FAR struct fs_dirent_s *dir); +static int hostfs_closedir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int hostfs_readdir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int hostfs_rewinddir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); + +static int hostfs_bind(FAR struct inode *blkdriver, + FAR const void *data, FAR void **handle); +static int hostfs_unbind(FAR void *handle, FAR struct inode **blkdriver, + unsigned int flags); +static int hostfs_statfs(FAR struct inode *mountpt, + FAR struct statfs *buf); + +static int hostfs_unlink(FAR struct inode *mountpt, + FAR const char *relpath); +static int hostfs_mkdir(FAR struct inode *mountpt, + FAR const char *relpath, mode_t mode); +static int hostfs_rmdir(FAR struct inode *mountpt, const char *relpath); +static int hostfs_rename(FAR struct inode *mountpt, + FAR const char *oldrelpath, + FAR const char *newrelpath); +static int hostfs_stat(FAR struct inode *mountpt, + FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_seminitialized = FALSE; +static sem_t g_sem; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* See fs_mount.c -- this structure is explicitly externed there. + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct mountpt_operations hostfs_operations = +{ + hostfs_open, /* open */ + hostfs_close, /* close */ + hostfs_read, /* read */ + hostfs_write, /* write */ + hostfs_seek, /* seek */ + hostfs_ioctl, /* ioctl */ + + hostfs_sync, /* sync */ + hostfs_dup, /* dup */ + + hostfs_opendir, /* opendir */ + hostfs_closedir, /* closedir */ + hostfs_readdir, /* readdir */ + hostfs_rewinddir, /* rewinddir */ + + hostfs_bind, /* bind */ + hostfs_unbind, /* unbind */ + hostfs_statfs, /* statfs */ + + hostfs_unlink, /* unlinke */ + hostfs_mkdir, /* mkdir */ + hostfs_rmdir, /* rmdir */ + hostfs_rename, /* rename */ + hostfs_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hostfs_semtake + ****************************************************************************/ + +void hostfs_semtake(struct hostfs_mountpt_s *fs) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(fs->fs_sem) != 0) + { + /* The only case that an error should occur here is if + * the wait was awakened by a signal. + */ + + ASSERT(*get_errno_ptr() == EINTR); + } +} + +/**************************************************************************** + * Name: hostfs_semgive + ****************************************************************************/ + +void hostfs_semgive(struct hostfs_mountpt_s *fs) +{ + sem_post(fs->fs_sem); +} + +/**************************************************************************** + * Name: hostfs_mkpath + * + * Description: Build absolute host path from relative NuttX path. + * + ****************************************************************************/ + +static void hostfs_mkpath(struct hostfs_mountpt_s *fs, const char *relpath, + char *path, int pathlen) +{ + int depth = 0; + int first; + int x; + + /* Copy base host path to output */ + + strncpy(path, fs->fs_root, pathlen); + + /* Be sure we aren't trying to use ".." to display outside of our + * mounted path. + */ + + x = 0; + while (relpath[x] == '/') + { + x++; + } + + first = x; + + while (relpath[x] != '\0') + { + /* Test for ".." occurance */ + + if (strncmp(&relpath[x], "..", 2) == 0) + { + /* Reduce depth by 1 */ + + depth--; + x += 2; + } + + else if (relpath[x] == '/' && relpath[x+1] != '/' && relpath[x+1] != '\0') + { + depth++; + x++; + } + else + { + x++; + } + } + + if (depth >= 0) + { + strncat(path, &relpath[first], pathlen-strlen(path)-1); + } +} + +/**************************************************************************** + * Name: hostfs_open + ****************************************************************************/ + +static int hostfs_open(FAR struct file *filep, const char *relpath, + int oflags, mode_t mode) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + int ret; + struct hostfs_ofile_s *hf; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT((filep->f_priv == NULL) && (filep->f_inode != NULL)); + + + /* Get the mountpoint inode reference from the file structure and the + * mountpoint private data from the inode structure + */ + + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Allocate memory for the open file */ + + hf = (struct hostfs_ofile_s *) kmm_malloc(sizeof *hf); + if (hf == NULL) + { + ret = -ENOMEM; + goto errout_with_semaphore; + } + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Try to open the file in the host file system */ + + hf->fd = host_open(path, oflags, mode); + if (hf->fd == -1) + { + /* Error opening file */ + + ret = -EBADF; + goto errout_with_buffer; + } + + /* Attach the private date to the struct file instance */ + + filep->f_priv = hf; + + /* Then insert the new instance into the mountpoint structure. + * It needs to be there (1) to handle error conditions that effect + * all files, and (2) to inform the umount logic that we are busy + * (but a simple reference count could have done that). + */ + + hf->fnext = fs->fs_head; + hf->crefs = 1; + hf->oflags = oflags; + fs->fs_head = hf; + + ret = OK; + goto errout_with_semaphore; + +errout_with_buffer: + kmm_free(hf); + +errout_with_semaphore: + hostfs_semgive(fs); + if (ret == -EINVAL) + { + ret = -EIO; + } + + return ret; +} + +/**************************************************************************** + * Name: hostfs_close + ****************************************************************************/ + +static int hostfs_close(FAR struct file *filep) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + struct hostfs_ofile_s *nextfile; + struct hostfs_ofile_s *prevfile; + + /* Sanity checks */ + + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + inode = filep->f_inode; + fs = inode->i_private; + hf = filep->f_priv; + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Check if we are the last one with a reference to the file and + * only close if we are. */ + + if (hf->crefs > 1) + { + /* The file is opened more than once. Just decrement the + * reference count and return. */ + + hf->crefs--; + goto okout; + } + + /* Remove ourselves from the linked list */ + + nextfile = fs->fs_head; + prevfile = nextfile; + while ((nextfile != hf) && (nextfile != NULL)) + { + /* Save the previous file pointer too */ + + prevfile = nextfile; + nextfile = nextfile->fnext; + } + + if (nextfile != NULL) + { + /* Test if we were the first entry */ + + if (nextfile == fs->fs_head) + { + /* Assign a new head */ + + fs->fs_head = nextfile->fnext; + } + else + { + /* Take ourselves out of the list */ + + prevfile->fnext = nextfile->fnext; + } + } + + /* Close the host file */ + + host_close(hf->fd); + + /* Now free the pointer */ + + filep->f_priv = NULL; + kmm_free(hf); + +okout: + hostfs_semgive(fs); + return OK; +} + +/**************************************************************************** + * Name: hostfs_read + ****************************************************************************/ + +static ssize_t hostfs_read(FAR struct file *filep, char *buffer, size_t buflen) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + int ret = OK; + + /* Sanity checks */ + + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + hf = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Call the host to perform the read */ + + ret = host_read(hf->fd, buffer, buflen); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_write + ****************************************************************************/ + +static ssize_t hostfs_write(FAR struct file *filep, const char *buffer, + size_t buflen) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + int ret; + + /* Sanity checks. I have seen the following assertion misfire if + * CONFIG_DEBUG_MM is enabled while re-directing output to a + * file. In this case, the debug output can get generated while + * the file is being opened, FAT data structures are being allocated, + * and things are generally in a perverse state. + */ + +#ifdef CONFIG_DEBUG_MM + if (filep->f_priv == NULL || filep->f_inode == NULL) + { + return -ENXIO; + } +#else + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); +#endif + + /* Recover our private data from the struct file instance */ + + hf = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Test the permissions. Only allow write if the file was opened with + * write flags. + */ + + if ((hf->oflags & O_WROK) == 0) + { + ret = -EACCES; + goto errout_with_semaphore; + } + + /* Call the host to perform the write */ + + ret = host_write(hf->fd, buffer, buflen); + +errout_with_semaphore: + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_seek + ****************************************************************************/ + +static off_t hostfs_seek(FAR struct file *filep, off_t offset, int whence) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + int ret; + + /* Sanity checks */ + + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + hf = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Call our internal routine to perform the seek */ + + ret = host_lseek(hf->fd, offset, whence); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_ioctl + ****************************************************************************/ + +static int hostfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + int ret; + + /* Sanity checks */ + + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + hf = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Call our internal routine to perform the ioctl */ + + ret = host_ioctl(hf->fd, cmd, arg); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_sync + * + * Description: Synchronize the file state on disk to match internal, in- + * memory state. + * + ****************************************************************************/ + +static int hostfs_sync(FAR struct file *filep) +{ + struct inode *inode; + struct hostfs_mountpt_s *fs; + struct hostfs_ofile_s *hf; + + /* Sanity checks */ + + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + hf = filep->f_priv; + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL); + + /* Take the semaphore */ + + hostfs_semtake(fs); + + host_sync(hf->fd); + + hostfs_semgive(fs); + return OK; +} + +/**************************************************************************** + * Name: hostfs_dup + * + * Description: Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int hostfs_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + struct hostfs_ofile_s *sf; + + /* Sanity checks */ + + DEBUGASSERT(oldp->f_priv != NULL && + newp->f_priv == NULL && + newp->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + sf = oldp->f_priv; + + DEBUGASSERT(sf != NULL); + + /* Just increment the reference count on the ofile */ + + sf->crefs++; + newp->f_priv = (FAR void *)sf; + + return OK; +} + +/**************************************************************************** + * Name: hostfs_opendir + * + * Description: Open a directory for read access + * + ****************************************************************************/ + +static int hostfs_opendir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir) +{ + struct hostfs_mountpt_s *fs; + int ret; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); + + /* Recover our private data from the inode instance */ + + fs = mountpt->i_private; + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Call the host's opendir function */ + + dir->u.hostfs.fs_dir = host_opendir(path); + + if (dir->u.hostfs.fs_dir == NULL) + { + ret = -ENOENT; + goto errout_with_semaphore; + } + + ret = OK; + +errout_with_semaphore: + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_closedir + * + * Description: Open a directory for read access + * + ****************************************************************************/ + +static int hostfs_closedir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir) +{ + struct hostfs_mountpt_s *fs; + + /* Sanity checks */ + + DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); + + /* Recover our private data from the inode instance */ + + fs = mountpt->i_private; + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Call the host's closedir function */ + + host_closedir(dir->u.hostfs.fs_dir); + + hostfs_semgive(fs); + return OK; +} + +/**************************************************************************** + * Name: hostfs_readdir + * + * Description: Read the next directory entry + * + ****************************************************************************/ + +static int hostfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) +{ + struct hostfs_mountpt_s *fs; + int ret; + struct host_dirent_s entry; + + /* Sanity checks */ + + DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); + + /* Recover our private data from the inode instance */ + + fs = mountpt->i_private; + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Call the host OS's readdir function */ + + ret = host_readdir(dir->u.hostfs.fs_dir, &entry); + + /* Save the entry name when successful */ + + if (ret == OK) + { + /* Copy the entry name */ + memset(dir->fd_dir.d_name, 0, sizeof(dir->fd_dir.d_name)); + strncpy(dir->fd_dir.d_name, entry.d_name, sizeof(dir->fd_dir.d_name)); + + /* Copy the entry type */ + + /* TODO: May need to do some type mapping */ + + dir->fd_dir.d_type = entry.d_type; + } + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_rewindir + * + * Description: Reset directory read to the first entry + * + ****************************************************************************/ + +static int hostfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir) +{ + /* Sanity checks */ + + DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); + + /* Call the host and let it do all the work */ + + host_rewinddir(dir->u.hostfs.fs_dir); + + return OK; +} + +/**************************************************************************** + * Name: hostfs_bind + * + * Description: This implements a portion of the mount operation. This + * function allocates and initializes the mountpoint private data and + * binds the blockdriver inode to the filesystem private data. The final + * binding of the private data (containing the blockdriver) to the + * mountpoint is performed by mount(). + * + ****************************************************************************/ + +static int hostfs_bind(FAR struct inode *blkdriver, const void *data, + void **handle) +{ + struct hostfs_mountpt_s *fs; + struct host_stat_s buf; + int ret, len; + const char * options; + + /* Validate the block driver is NULL */ + + if (blkdriver || !data) + { + return -ENODEV; + } + + /* The only options we suppor are "-o fs=whatever", so search + * for the 'dir=' portion + */ + + options = (const char *) data; + if ((strncmp(options, "fs=", 3) != 0) || (strlen(options) < 5)) + { + return -ENODEV; + } + + /* Create an instance of the mountpt state structure */ + + fs = (struct hostfs_mountpt_s *)kmm_zalloc(sizeof(struct hostfs_mountpt_s)); + if (!fs) + { + return -ENOMEM; + } + + /* If the global semaphore hasn't been initialized, then + * initialized it now. */ + + fs->fs_sem = &g_sem; + if (!g_seminitialized) + { + /* Initialize the semaphore that controls access */ + + sem_init(&g_sem, 0, 0); + g_seminitialized = TRUE; + } + else + { + /* Take the semaphore for the mount */ + + hostfs_semtake(fs); + } + + /* Initialize the allocated mountpt state structure. The filesystem is + * responsible for one reference ont the blkdriver inode and does not + * have to addref() here (but does have to release in ubind(). + */ + + fs->fs_head = NULL; + + /* Now perform the mount. */ + + strncpy(fs->fs_root, &options[3], sizeof(fs->fs_root)); + len = strlen(fs->fs_root); + if (len && fs->fs_root[len-1] == '/') + { + /* Remove trailing '/' */ + + fs->fs_root[len-1] = '\0'; + } + + /* Try to stat the file in the host FS */ + + ret = host_stat(fs->fs_root, &buf); + if ((ret != 0) || ((buf.st_mode & HOST_ST_MODE_DIR) == 0)) + { + hostfs_semgive(fs); + kmm_free(fs); + return -ENOENT; + } + + /* Append a '/' to the name now */ + + strcat(fs->fs_root, "/"); + + *handle = (FAR void *)fs; + hostfs_semgive(fs); + return OK; +} + +/**************************************************************************** + * Name: hostfs_unbind + * + * Description: This implements the filesystem portion of the umount + * operation. + * + ****************************************************************************/ + +static int hostfs_unbind(FAR void *handle, FAR struct inode **blkdriver, + unsigned int flags) +{ + FAR struct hostfs_mountpt_s *fs = (FAR struct hostfs_mountpt_s *)handle; + int ret; + + if (!fs) + { + return -EINVAL; + } + + /* Check if there are sill any files opened on the filesystem. */ + + ret = OK; /* Assume success */ + hostfs_semtake(fs); + if (fs->fs_head != NULL) + { + /* We cannot unmount now.. there are open files */ + + hostfs_semgive(fs); + + /* This implementation currently only supports unmounting if there are + * no open file references. + */ + + return (flags != 0) ? -ENOSYS : -EBUSY; + } + + hostfs_semgive(fs); + kmm_free(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_statfs + * + * Description: Return filesystem statistics + * + ****************************************************************************/ + +static int hostfs_statfs(struct inode *mountpt, struct statfs *buf) +{ + struct hostfs_mountpt_s *fs; + struct host_statfs_s host_buf; + int ret; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + hostfs_semtake(fs); + + /* Implement the logic!! */ + + memset(buf, 0, sizeof(struct statfs)); + buf->f_type = HOSTFS_MAGIC; + + /* Call the host fs to perform the statfs */ + + ret = host_statfs(fs->fs_root, &host_buf); + + buf->f_namelen = host_buf.f_namelen; + buf->f_bsize = host_buf.f_bsize; + buf->f_blocks = host_buf.f_blocks; + buf->f_bfree = host_buf.f_bfree; + buf->f_bavail = host_buf.f_bavail; + buf->f_files = host_buf.f_files; + buf->f_ffree = host_buf.f_ffree; + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_unlink + * + * Description: Remove a file + * + ****************************************************************************/ + +static int hostfs_unlink(struct inode *mountpt, const char *relpath) +{ + struct hostfs_mountpt_s *fs; + int ret; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Call the host fs to perform the unlink */ + + ret = host_unlink(path); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_mkdir + * + * Description: Create a directory + * + ****************************************************************************/ + +static int hostfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) +{ + struct hostfs_mountpt_s *fs; + int ret; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Call the host FS to do the mkdir */ + + ret = host_mkdir(path, mode); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_rmdir + * + * Description: Remove a directory + * + ****************************************************************************/ + +int hostfs_rmdir(struct inode *mountpt, const char *relpath) +{ + struct hostfs_mountpt_s *fs; + int ret; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + /* Take the semaphore */ + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Call the host FS to do the mkdir */ + + ret = host_rmdir(path); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_rename + * + * Description: Rename a file or directory + * + ****************************************************************************/ + +int hostfs_rename(struct inode *mountpt, const char *oldrelpath, + const char *newrelpath) +{ + struct hostfs_mountpt_s *fs; + int ret; + char oldpath[HOSTFS_MAX_PATH]; + char newpath[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + strncpy(oldpath, fs->fs_root, sizeof(oldpath)); + strncat(oldpath, oldrelpath, sizeof(oldpath)-strlen(oldpath)-1); + strncpy(newpath, fs->fs_root, sizeof(newpath)); + strncat(newpath, newrelpath, sizeof(newpath)-strlen(newpath)-1); + + /* Call the host FS to do the mkdir */ + + ret = host_rename(oldpath, newpath); + + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Name: hostfs_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int hostfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf) +{ + struct hostfs_mountpt_s *fs; + int ret; + struct host_stat_s host_buf; + char path[HOSTFS_MAX_PATH]; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + + hostfs_semtake(fs); + + /* Append to the host's root directory */ + + hostfs_mkpath(fs, relpath, path, sizeof(path)); + + /* Call the host FS to do the mkdir */ + + ret = host_stat(path, &host_buf); + + if (ret != 0) + { + goto errout_with_semaphore; + } + + /* Initialize the stat structure */ + + memset(buf, 0, sizeof(struct stat)); + + buf->st_mode = host_buf.st_mode & 0xFFF; + + if (host_buf.st_mode & HOST_ST_MODE_DIR) + { + buf->st_mode |= S_IFDIR; + } + + if (host_buf.st_mode & HOST_ST_MODE_REG) + { + buf->st_mode |= S_IFREG; + } + + if (host_buf.st_mode & HOST_ST_MODE_CHR) + { + buf->st_mode |= S_IFCHR; + } + + if (host_buf.st_mode & HOST_ST_MODE_BLK) + { + buf->st_mode |= S_IFBLK; + } + + if (host_buf.st_mode & HOST_ST_MODE_LINK) + { + buf->st_mode |= S_IFLNK; + } + + if (host_buf.st_mode & HOST_ST_MODE_PIPE) + { + buf->st_mode |= S_IFIFO; + } + + buf->st_size = host_buf.st_size; + buf->st_blksize = host_buf.st_blksize; + buf->st_blocks = host_buf.st_blocks; + buf->st_atime = host_buf.st_atim; + buf->st_ctime = host_buf.st_ctim; + + ret = OK; + +errout_with_semaphore: + hostfs_semgive(fs); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h new file mode 100644 index 0000000000000000000000000000000000000000..17227611a10e70c3debbe299c186023c5fcc7a89 --- /dev/null +++ b/fs/hostfs/hostfs.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * nuttx/fs/hostfs/hostfs.h + * + * Copyright (C) 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * 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 __FS_HOSTFS_HOSTFS_H +#define __FS_HOSTFS_HOSTFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Quasi-standard definitions */ + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +#ifndef MAX +# define MAX(a,b) (a > b ? a : b) +#endif + +#define HOSTFS_MAX_PATH 256 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This structure describes the state of one open file. This structure + * is protected by the volume semaphore. + */ + +struct hostfs_ofile_s +{ + struct hostfs_ofile_s *fnext; /* Supports a singly linked list */ + int16_t crefs; /* Reference count */ + mode_t oflags; /* Open mode */ + int fd; +}; + +/* This structure represents the overall mountpoint state. An instance of this + * structure is retained as inode private data on each mountpoint that is + * mounted with a hostfs filesystem. + */ + +struct hostfs_mountpt_s +{ + sem_t *fs_sem; /* Used to assure thread-safe access */ + FAR struct hostfs_ofile_s *fs_head; /* A singly-linked list of open files */ + char fs_root[HOSTFS_MAX_PATH]; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Internal function prototypes + ****************************************************************************/ + +/* Semaphore access for internal use */ + +void hostfs_semtake(struct hostfs_mountpt_s *fs); +void hostfs_semgive(struct hostfs_mountpt_s *fs); + +/* Forward references for utility functions */ + +struct hostfs_mountpt_s; + +struct file; /* Forward references */ +struct inode; +struct fs_dirent_s; +struct statfs; +struct stat; + +#endif /* __FS_HOSTFS_HOSTFS_H */ diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 4f82b15126e87436dbed5d57c1fac09b0e7455e5..8366b55ce70684a1bd77213d52fb7b4b91304cc4 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -60,11 +60,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -385,7 +385,7 @@ void files_release(int fd) list = sched_getfiles(); DEBUGASSERT(list); - if (fd >=0 && fd < CONFIG_NFILE_DESCRIPTORS) + if (fd >= 0 && fd < CONFIG_NFILE_DESCRIPTORS) { _files_semtake(list); list->fl_files[fd].f_oflags = 0; diff --git a/fs/inode/fs_foreachinode.c b/fs/inode/fs_foreachinode.c index 49f33ad30e4c6b267958dd7d4f223a93dd95501a..41ef0f0160a4b44af0bae65daba5a45a8f0f27a0 100644 --- a/fs/inode/fs_foreachinode.c +++ b/fs/inode/fs_foreachinode.c @@ -72,17 +72,10 @@ struct inode_path_s char path[CONFIG_PATH_MAX]; }; -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ + /**************************************************************************** * Name: foreach_inodelevel * diff --git a/fs/inode/fs_inode.c b/fs/inode/fs_inode.c index c16d35bcc46cde40924c33ae4a01f6f1463df6d3..52985f8ad70ff36fd752b65a0d7f35a77143bf49 100644 --- a/fs/inode/fs_inode.c +++ b/fs/inode/fs_inode.c @@ -73,13 +73,13 @@ struct inode_sem_s }; /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static struct inode_sem_s g_inode_sem; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ FAR struct inode *g_root_inode = NULL; @@ -111,7 +111,7 @@ static int _inode_compare(FAR const char *fname, return -1; } - for (;;) + for (; ; ) { /* At end of node name? */ @@ -133,7 +133,7 @@ static int _inode_compare(FAR const char *fname, } } - /* At end of find name?*/ + /* At end of find name? */ else if (!*fname || *fname == '/') { @@ -421,19 +421,19 @@ FAR const char *inode_nextname(FAR const char *name) * path segment. */ - while (*name && *name != '/') - { - name++; - } + while (*name && *name != '/') + { + name++; + } - /* If we found the '/' delimiter, then the path segment we want begins at - * the next character (which might also be the NUL terminator). - */ + /* If we found the '/' delimiter, then the path segment we want begins at + * the next character (which might also be the NUL terminator). + */ - if (*name) - { - name++; - } + if (*name) + { + name++; + } - return name; + return name; } diff --git a/fs/inode/fs_inodeaddref.c b/fs/inode/fs_inodeaddref.c index 493c81e297dfdb63f0eedb1f8662ed1eb3b3c964..b34a32c9f8a16208346a8ecdc958eceafaeb6c96 100644 --- a/fs/inode/fs_inodeaddref.c +++ b/fs/inode/fs_inodeaddref.c @@ -48,11 +48,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/inode/fs_inodebasename.c b/fs/inode/fs_inodebasename.c index 517d968d2b3fd93b423e7f64fd16642d83e5e34e..13a4486ba570a3405f674875a919c6ddd54b36ac 100644 --- a/fs/inode/fs_inodebasename.c +++ b/fs/inode/fs_inodebasename.c @@ -41,32 +41,16 @@ #include "inode/inode.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: inode_nextname + * Name: inode_basename * * Description: - * Given a path with node names separated by '/', return the next node - * name. + * Given a path with node names separated by '/', return name of last + * segment in the path. "" * ****************************************************************************/ @@ -74,7 +58,7 @@ FAR const char *inode_basename(FAR const char *name) { FAR const char *basename = NULL; - for (;;) + for (; ; ) { /* Get the name for the next path segment */ @@ -84,13 +68,19 @@ FAR const char *inode_basename(FAR const char *name) * previous name that we saved is the basename. */ - if (*name == '\0') + if (name == NULL || *name == '\0') { - return basename; + /* Break out of the loop with basename pointer to the final + * segment of the path. + */ + + break; } - } - /* We won't get here */ + /* Set basename to point to the remainder of the path */ + + basename = name; + } - return NULL; + return basename; } diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index 7534a3441d7182fa4d7e5a21dad1520bffb2200e..533e2ef2222434ec42c373c7c474069db96822c7 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -49,11 +49,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/inode/fs_inoderelease.c b/fs/inode/fs_inoderelease.c index e459fddd073902e959d2718ffc53d4c92206c60f..97eadfaac0ef352c7959257da32d9b4b3dfdbaf9 100644 --- a/fs/inode/fs_inoderelease.c +++ b/fs/inode/fs_inoderelease.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index ac76a20594343b81c74c401ddc84ba2ca00cf1b1..e0b12299c02e012b878fc27179f11aba9dcb5a2d 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index 104a42e0e7e00384a717a0aee0b07c36ab7b0be9..9bf601e0c0a4dad488788b39c849d267eaf42e87 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -70,7 +70,11 @@ static int inode_namelen(FAR const char *name) { const char *tmp = name; - while (*tmp && *tmp != '/') tmp++; + while (*tmp && *tmp != '/') + { + tmp++; + } + return tmp - name; } @@ -80,8 +84,12 @@ static int inode_namelen(FAR const char *name) static void inode_namecpy(char *dest, const char *src) { - while (*src && *src != '/') *dest++ = *src++; - *dest='\0'; + while (*src && *src != '/') + { + *dest++ = *src++; + } + + *dest = '\0'; } /**************************************************************************** @@ -91,7 +99,7 @@ static void inode_namecpy(char *dest, const char *src) static FAR struct inode *inode_alloc(FAR const char *name) { int namelen = inode_namelen(name); - FAR struct inode *node = (FAR struct inode*)kmm_zalloc(FSNODE_SIZE(namelen)); + FAR struct inode *node = (FAR struct inode *)kmm_zalloc(FSNODE_SIZE(namelen)); if (node) { inode_namecpy(node->i_name, name); @@ -145,9 +153,8 @@ static void inode_insert(FAR struct inode *node, * Name: inode_reserve * * Description: - * Reserve an (initialized) inode the pseudo file system. - * - * NOTE: Caller must hold the inode semaphore + * Reserve an (initialized) inode the pseudo file system. The initial + * reference count on the new inode is zero. * * Input parameters: * path - The path to the inode to create @@ -161,6 +168,9 @@ static void inode_insert(FAR struct inode *node, * EEXIST - An inode already exists at 'path' * ENOMEM - Failed to allocate in-memory resources for the operation * + * Assumptions: + * Caller must hold the inode semaphore + * ****************************************************************************/ int inode_reserve(FAR const char *path, FAR struct inode **inode) @@ -192,7 +202,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode) /* Now we now where to insert the subtree */ - for (;;) + for (; ; ) { FAR struct inode *node; diff --git a/fs/inode/inode.h b/fs/inode/inode.h index a76b1b22facbe90ac2688ae86042eb5e8b24fe6e..3437c3858bce368447bd16080000ffc7ffe583b8 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -111,7 +111,7 @@ typedef int (*foreach_inode_t)(FAR struct inode *node, FAR void *arg); /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ #undef EXTERN diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c index 762b0d83258ad00760d56caab5c165ed8bbee9f1..501db4028233a76b0d6b481ed8487c3585e0f1a6 100644 --- a/fs/mmap/fs_mmap.c +++ b/fs/mmap/fs_mmap.c @@ -50,7 +50,7 @@ #include "fs_rammap.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -133,7 +133,7 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags, #ifdef CONFIG_DEBUG if (prot == PROT_NONE || - (flags & (MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_DENYWRITE)) != 0) + (flags & (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS | MAP_DENYWRITE)) != 0) { fdbg("Unsupported options, prot=%x flags=%04x\n", prot, flags); set_errno(ENOSYS); @@ -170,5 +170,5 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags, /* Return the offset address */ - return (void*)(((uint8_t*)addr) + offset); + return (FAR void *)(((FAR uint8_t *)addr) + offset); } diff --git a/fs/mmap/fs_munmap.c b/fs/mmap/fs_munmap.c index ecd0e6d71f1d6313c3422d2992006a17a571859e..12b084d85b7d443585b4041c28ea9c4c61d5bf8a 100644 --- a/fs/mmap/fs_munmap.c +++ b/fs/mmap/fs_munmap.c @@ -55,7 +55,7 @@ #ifdef CONFIG_FS_RAMMAP /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -196,7 +196,7 @@ int munmap(FAR void *start, size_t length) else { newaddr = kumm_realloc(curr->addr, sizeof(struct fs_rammap_s) + length); - DEBUGASSERT(newaddr == (FAR void*)(curr->addr)); + DEBUGASSERT(newaddr == (FAR void *)(curr->addr)); curr->length = length; } diff --git a/fs/mmap/fs_rammap.c b/fs/mmap/fs_rammap.c index e0b32504fde2b9269628ffc3d9f90f7fb2e5da4f..5f00032553bc95c27aafd64cfb1958cd48644116 100644 --- a/fs/mmap/fs_rammap.c +++ b/fs/mmap/fs_rammap.c @@ -55,7 +55,7 @@ #ifdef CONFIG_FS_RAMMAP /**************************************************************************** - * Global Data + * Public Data ****************************************************************************/ /* This is the list of all mapped files */ @@ -63,7 +63,7 @@ struct fs_allmaps_s g_rammaps; /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -177,24 +177,24 @@ FAR void *rammap(int fd, size_t length, off_t offset) nread = read(fd, rdbuffer, length); if (nread < 0) { - /* Handle the special case where the read was interrupted by a - * signal. - */ - - err = get_errno(); - if (err != EINTR) - { - /* All other read errors are bad. errno is already set. - * (but maybe should be forced to EINVAL?). NOTE that if - * FS DEBUG is enabled, then the following fdbg() macro will - * destroy the errno value. - */ - - fdbg("Read failed: offset=%d errno=%d\n", (int)offset, err); + /* Handle the special case where the read was interrupted by a + * signal. + */ + + err = get_errno(); + if (err != EINTR) + { + /* All other read errors are bad. errno is already set. + * (but maybe should be forced to EINVAL?). NOTE that if + * FS DEBUG is enabled, then the following fdbg() macro will + * destroy the errno value. + */ + + fdbg("Read failed: offset=%d errno=%d\n", (int)offset, err); #ifdef CONFIG_DEBUG_FS - goto errout_with_region; + goto errout_with_region; #else - goto errout_with_errno; + goto errout_with_errno; #endif } } diff --git a/fs/mmap/fs_rammap.h b/fs/mmap/fs_rammap.h index 4f9df6007016283570761fa8af8483452e6fd4c2..d4a7b05a379328dc6c915abde90391e3b55163c8 100644 --- a/fs/mmap/fs_rammap.h +++ b/fs/mmap/fs_rammap.h @@ -92,7 +92,7 @@ struct fs_allmaps_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* This is the list of all mapped files */ diff --git a/fs/mount/fs_automount.c b/fs/mount/fs_automount.c index 1efa80ada05699e31a455ac0931790604bfef7ff..e961fb5db8a35872a49e52b1823b79e8c1252940 100644 --- a/fs/mount/fs_automount.c +++ b/fs/mount/fs_automount.c @@ -249,7 +249,7 @@ static void automount_mount(FAR struct automounter_state_s *priv) priv->mounted = true; break; - + default: fdbg("ERROR: automount_findinode failed: %d\n", ret); break; diff --git a/fs/mount/fs_foreachmountpoint.c b/fs/mount/fs_foreachmountpoint.c index b3ab33abc7b6d9975241eacece39e72d4d562f8b..db6e386f7cefd3fc4e76e462342ff7985ff5b433 100644 --- a/fs/mount/fs_foreachmountpoint.c +++ b/fs/mount/fs_foreachmountpoint.c @@ -71,14 +71,6 @@ struct enum_mountpoint_s FAR void *arg; }; -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -142,7 +134,7 @@ static int mountpoint_filter(FAR struct inode *node, * Public Functions ****************************************************************************/ - /**************************************************************************** +/**************************************************************************** * Name: foreach_mountpoint * * Description: diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index 3a5602968caa30fb6d51b499026b7a465dd9acf3..abf7b9446e10620a7b0662ebd66ed57da8c964d7 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/mount/fs_mount.c * - * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -77,7 +77,8 @@ /* These file systems do not require block drivers */ #if defined(CONFIG_FS_NXFFS) || defined(CONFIG_FS_BINFS) || \ - defined(CONFIG_FS_PROCFS) || defined(CONFIG_NFS) + defined(CONFIG_FS_PROCFS) || defined(CONFIG_NFS) || \ + defined(CONFIG_FS_TMPFS) # define NONBDFS_SUPPORT #endif @@ -92,7 +93,7 @@ struct fsmap_t }; /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ #ifdef BDFS_SUPPORT @@ -102,6 +103,9 @@ extern const struct mountpt_operations fat_operations; #ifdef CONFIG_FS_ROMFS extern const struct mountpt_operations romfs_operations; #endif +#ifdef CONFIG_FS_TMPFS +extern const struct mountpt_operations tmpfs_operations; +#endif #ifdef CONFIG_FS_SMARTFS extern const struct mountpt_operations smartfs_operations; #endif @@ -134,12 +138,18 @@ extern const struct mountpt_operations binfs_operations; #ifdef CONFIG_FS_PROCFS extern const struct mountpt_operations procfs_operations; #endif +#ifdef CONFIG_FS_HOSTFS +extern const struct mountpt_operations hostfs_operations; +#endif static const struct fsmap_t g_nonbdfsmap[] = { #ifdef CONFIG_FS_NXFFS { "nxffs", &nxffs_operations }, #endif +#ifdef CONFIG_FS_TMPFS + { "tmpfs", &tmpfs_operations }, +#endif #ifdef CONFIG_NFS { "nfs", &nfs_operations }, #endif @@ -148,13 +158,16 @@ static const struct fsmap_t g_nonbdfsmap[] = #endif #ifdef CONFIG_FS_PROCFS { "procfs", &procfs_operations }, +#endif +#ifdef CONFIG_FS_HOSTFS + { "hostfs", &hostfs_operations }, #endif { NULL, NULL }, }; #endif /* NONBDFS_SUPPORT */ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -296,6 +309,8 @@ int mount(FAR const char *source, FAR const char *target, /* Insert a dummy node -- we need to hold the inode semaphore * to do this because we will have a momentarily bad structure. + * NOTE that the new inode will be created with an initial reference + * count of zero. */ { @@ -379,11 +394,11 @@ int mount(FAR const char *source, FAR const char *target, mountpt_inode->i_private = fshandle; inode_semgive(); - /* We can release our reference to the blkdrver_inode, if the filesystem - * wants to retain the blockdriver inode (which it should), then it must - * have called inode_addref(). There is one reference on mountpt_inode - * that will persist until umount2() is called. - */ + /* We can release our reference to the blkdrver_inode, if the filesystem + * wants to retain the blockdriver inode (which it should), then it must + * have called inode_addref(). There is one reference on mountpt_inode + * that will persist until umount2() is called. + */ #ifdef BDFS_SUPPORT #ifdef NONBDFS_SUPPORT diff --git a/fs/mount/fs_umount2.c b/fs/mount/fs_umount2.c index 796d7e37b243a583801b7aa3a04f1e33a975551d..a60dfc2a09a04f56271b0c0f671bee86f9e42405 100644 --- a/fs/mount/fs_umount2.c +++ b/fs/mount/fs_umount2.c @@ -56,11 +56,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/mqueue/mq_close.c b/fs/mqueue/mq_close.c index 00a29bbe6be4030f37dff5f310e6d3a8b7cff1f1..0d0a471461733588be0c06bb47957b1a651489e6 100644 --- a/fs/mqueue/mq_close.c +++ b/fs/mqueue/mq_close.c @@ -58,11 +58,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -136,7 +136,7 @@ int mq_close(mqd_t mqdes) } /**************************************************************************** - * Name: mq_close + * Name: mq_inode_release * * Description: * Release a reference count on a message queue inode. @@ -164,25 +164,25 @@ void mq_inode_release(FAR struct inode *inode) * the inode now. */ - if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0) - { - FAR struct mqueue_inode_s *msgq = inode->u.i_mqueue; - DEBUGASSERT(msgq); + if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0) + { + FAR struct mqueue_inode_s *msgq = inode->u.i_mqueue; + DEBUGASSERT(msgq); - /* Free the message queue (and any messages left in it) */ + /* Free the message queue (and any messages left in it) */ - mq_msgqfree(msgq); - inode->u.i_mqueue = NULL; + mq_msgqfree(msgq); + inode->u.i_mqueue = NULL; - /* Release and free the inode container. If it has been properly - * unlinked, then the peer pointer should be NULL. - */ + /* Release and free the inode container. If it has been properly + * unlinked, then the peer pointer should be NULL. + */ - inode_semgive(); + inode_semgive(); - DEBUGASSERT(inode->i_peer == NULL); - inode_free(inode); - return; + DEBUGASSERT(inode->i_peer == NULL); + inode_free(inode); + return; } inode_semgive(); diff --git a/fs/mqueue/mq_open.c b/fs/mqueue/mq_open.c index f2b95b9b5adb28f251a70910802129858bc3554d..ca4ef46bdd18bcb3cfd981d3f2b0d7719fcb581a 100644 --- a/fs/mqueue/mq_open.c +++ b/fs/mqueue/mq_open.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/mqueue/mq_open.c * - * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -139,7 +139,8 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...) sched_lock(); /* Get the inode for this mqueue. This should succeed if the message - * queue has already been created. + * queue has already been created. In this case, inode_finde() will + * have incremented the reference count on the inode. */ inode = inode_find(fullpath, &relpath); @@ -157,7 +158,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...) * create a new mqueue with this name. */ - if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { errcode = EEXIST; goto errout_with_inode; @@ -185,13 +186,13 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...) goto errout_with_lock; } - /* Create the mqueue. First we have to extract the additional - * parameters from the variable argument list. - */ + /* Create the mqueue. First we have to extract the additional + * parameters from the variable argument list. + */ va_start(ap, oflags); mode = va_arg(ap, mode_t); - attr = va_arg(ap, FAR struct mq_attr*); + attr = va_arg(ap, FAR struct mq_attr *); va_end(ap); /* Create an inode in the pseudo-filesystem at this path */ @@ -206,9 +207,11 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...) goto errout_with_lock; } - /* Allocate memory for the new message queue. */ + /* Allocate memory for the new message queue. The new inode will + * be created with a reference count of zero. + */ - msgq = (FAR struct mqueue_inode_s*)mq_msgqalloc(mode, attr); + msgq = (FAR struct mqueue_inode_s *)mq_msgqalloc(mode, attr); if (!msgq) { errcode = ENOSPC; @@ -230,6 +233,9 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...) inode->u.i_mqueue = msgq; msgq->inode = inode; + /* Set the initial reference count on this inode to one */ + + inode->i_crefs = 1; } sched_unlock(); diff --git a/fs/mqueue/mq_unlink.c b/fs/mqueue/mq_unlink.c index 496571163cbb75c0caa1fc2dab2220d90e9f83d7..e9cce12c89bf179eddcf96a73995a0c4b5218afd 100644 --- a/fs/mqueue/mq_unlink.c +++ b/fs/mqueue/mq_unlink.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * fs/mqueue/mq_unlink.c * * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -49,31 +49,31 @@ #include "inode/inode.h" #include "mqueue/mqueue.h" -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_unlink * * Description: @@ -90,7 +90,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int mq_unlink(FAR const char *mq_name) { diff --git a/fs/mqueue/mqueue.h b/fs/mqueue/mqueue.h index 775ff220ebe12e9c237ef07758d68ca72ad1eebb..4392412ddffa315d88e64e9068ba645d8e543522 100644 --- a/fs/mqueue/mqueue.h +++ b/fs/mqueue/mqueue.h @@ -60,7 +60,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef __cplusplus diff --git a/fs/nfs/nfs_util.c b/fs/nfs/nfs_util.c index 46ee56db6dd1023d231626529ca1b462716cd04b..eb339cee6978ad1e5105fcc1bb49703584f1085e 100644 --- a/fs/nfs/nfs_util.c +++ b/fs/nfs/nfs_util.c @@ -69,11 +69,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -90,7 +90,7 @@ static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer, /* Loop until the name is successfully parsed or an error occurs */ - for (;;) + for (; ; ) { /* Get the next byte from the path */ @@ -102,7 +102,7 @@ static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer, { /* This logic just suppors "//" sequences in the path name */ - if (ch == '\0' || nbytes > 0 ) + if (ch == '\0' || nbytes > 0) { /* NULL terminate the parsed path segment */ @@ -433,7 +433,7 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath, * to the path is found. */ - for (;;) + for (; ; ) { /* Extract the next path segment name. */ @@ -494,7 +494,7 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath, * Desciption: * Given a path to something that may or may not be in the file system, * return the handle of the entry of the directory containing the requested -* object. + * object. * * Return Value: * Zero on success; a positive errno value on failure. @@ -527,7 +527,7 @@ int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath, /* Loop until the directory entry containing the path is found. */ - for (;;) + for (; ; ) { /* Extract the next path segment name. */ diff --git a/fs/nfs/nfs_vfsops.c b/fs/nfs/nfs_vfsops.c index 029885dea76793111975807e70b79a38957a9958..934cea664bf65be3b14530628266ab8479fb887f 100644 --- a/fs/nfs/nfs_vfsops.c +++ b/fs/nfs/nfs_vfsops.c @@ -104,7 +104,7 @@ #endif /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ uint32_t nfs_true; @@ -495,7 +495,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, */ tmp = fxdr_unsigned(uint32_t, fattr.fa_mode); - if ((tmp & (NFSMODE_IWOTH|NFSMODE_IWGRP|NFSMODE_IWUSR)) == 0) + if ((tmp & (NFSMODE_IWOTH | NFSMODE_IWGRP | NFSMODE_IWUSR)) == 0) { fdbg("ERROR: File is read-only: %08x\n", tmp); return EACCES; @@ -504,7 +504,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, /* It would be an error if we are asked to create the file exclusively */ - if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { /* Already exists -- can't create it exclusively */ @@ -528,7 +528,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np, * access is ignored. */ - if ((oflags & (O_TRUNC|O_WRONLY)) == (O_TRUNC|O_WRONLY)) + if ((oflags & (O_TRUNC | O_WRONLY)) == (O_TRUNC | O_WRONLY)) { /* Truncate the file to zero length. I think we can do this with * the SETATTR call by setting the length to zero. @@ -567,7 +567,7 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, * mountpoint private data from the inode structure */ - nmp = (struct nfsmount*)filep->f_inode->i_private; + nmp = (FAR struct nfsmount *)filep->f_inode->i_private; DEBUGASSERT(nmp != NULL); /* Pre-allocate the file private data to describe the opened file. */ @@ -690,8 +690,8 @@ static int nfs_close(FAR struct file *filep) /* Recover our private data from the struct file instance */ - nmp = (struct nfsmount*) filep->f_inode->i_private; - np = (struct nfsnode*) filep->f_priv; + nmp = (FAR struct nfsmount *) filep->f_inode->i_private; + np = (FAR struct nfsnode *) filep->f_priv; DEBUGASSERT(nmp != NULL); @@ -787,8 +787,8 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) /* Recover our private data from the struct file instance */ - nmp = (struct nfsmount*)filep->f_inode->i_private; - np = (struct nfsnode*)filep->f_priv; + nmp = (FAR struct nfsmount *)filep->f_inode->i_private; + np = (FAR struct nfsnode *)filep->f_priv; DEBUGASSERT(nmp != NULL); @@ -835,7 +835,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) /* Initialize the request */ - ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.read.read; + ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.read.read; reqlen = 0; /* Copy the variable length, file handle */ @@ -963,8 +963,8 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, /* Recover our private data from the struct file instance */ - nmp = (struct nfsmount*)filep->f_inode->i_private; - np = (struct nfsnode*)filep->f_priv; + nmp = (FAR struct nfsmount *)filep->f_inode->i_private; + np = (FAR struct nfsnode *)filep->f_priv; DEBUGASSERT(nmp != NULL); @@ -1143,8 +1143,8 @@ static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp) /* Recover our private data from the struct file instance */ - nmp = (struct nfsmount*)oldp->f_inode->i_private; - np = (struct nfsnode*)oldp->f_priv; + nmp = (FAR struct nfsmount *)oldp->f_inode->i_private; + np = (FAR struct nfsnode *)oldp->f_priv; DEBUGASSERT(nmp != NULL); @@ -1305,7 +1305,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) * the dirent structure. */ - ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.readdir.readdir; + ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.readdir.readdir; reqlen = 0; /* Copy the variable length, directory file handle */ @@ -1421,7 +1421,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) tmp = *ptr++; length = fxdr_unsigned(uint32_t, tmp); - name = (uint8_t*)ptr; + name = (FAR uint8_t *)ptr; /* Increment the pointer past the name (allowing for padding). ptr * now points to the cookie. @@ -1702,8 +1702,9 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data, nfs_decode_args(&nprmt, argp); - /* Determine the size of a buffer that will hold one RPC data transfer. - * First, get the maximum size of a read and a write transfer */ + /* Determine the size of a buffer that will hold one RPC data transfer. + * First, get the maximum size of a read and a write transfer. + */ buflen = SIZEOF_rpc_call_write(nprmt.wsize); tmp = SIZEOF_rpc_reply_read(nprmt.rsize); @@ -1817,7 +1818,7 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data, error = nfs_request(nmp, NFSPROC_GETATTR, (FAR void *)&getattr, sizeof(struct FS3args), - (FAR void*)&resok, sizeof(struct rpc_reply_getattr)); + (FAR void *)&resok, sizeof(struct rpc_reply_getattr)); if (error) { fdbg("ERROR: nfs_request failed: %d\n", error); @@ -1830,7 +1831,7 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data, /* Mounted! */ - *handle = (void*)nmp; + *handle = (FAR void *)nmp; nfs_semgive(nmp); fvdbg("Successfully mounted\n"); @@ -2045,7 +2046,7 @@ static int nfs_statfs(FAR struct inode *mountpt, FAR struct statfs *sbp) /* Get the mountpoint private data from the inode structure */ - nmp = (struct nfsmount*)mountpt->i_private; + nmp = (FAR struct nfsmount *)mountpt->i_private; /* Check if the mount is still healthy */ @@ -2123,7 +2124,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) /* Get the mountpoint private data from the inode structure */ - nmp = (struct nfsmount*)mountpt->i_private; + nmp = (FAR struct nfsmount *)mountpt->i_private; /* Check if the mount is still healthy */ @@ -2209,7 +2210,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) /* Get the mountpoint private data from the inode structure */ - nmp = (struct nfsmount*) mountpt->i_private; + nmp = (FAR struct nfsmount *) mountpt->i_private; /* Check if the mount is still healthy */ @@ -2536,7 +2537,7 @@ static int nfs_stat(struct inode *mountpt, const char *relpath, /* Get the mountpoint private data from the inode structure */ - nmp = (struct nfsmount*)mountpt->i_private; + nmp = (FAR struct nfsmount *)mountpt->i_private; DEBUGASSERT(nmp && buf); /* Check if the mount is still healthy */ @@ -2568,9 +2569,9 @@ static int nfs_stat(struct inode *mountpt, const char *relpath, * as in the NFSv3 spec. */ - mode = tmp & (NFSMODE_IXOTH|NFSMODE_IWOTH|NFSMODE_IROTH| - NFSMODE_IXGRP|NFSMODE_IWGRP|NFSMODE_IRGRP| - NFSMODE_IXUSR|NFSMODE_IWUSR|NFSMODE_IRUSR); + mode = tmp & (NFSMODE_IXOTH | NFSMODE_IWOTH | NFSMODE_IROTH | + NFSMODE_IXGRP | NFSMODE_IWGRP | NFSMODE_IRGRP | + NFSMODE_IXUSR | NFSMODE_IWUSR | NFSMODE_IRUSR); /* Handle the cases that are not the same */ diff --git a/fs/nfs/rpc_clnt.c b/fs/nfs/rpc_clnt.c index 7e7c96739a1406ad66f572c84df98dbddc38c7f7..030d9bafb2953ca65a2fb697f5e7c2cd03dd99f1 100644 --- a/fs/nfs/rpc_clnt.c +++ b/fs/nfs/rpc_clnt.c @@ -415,9 +415,9 @@ int rpcclnt_connect(struct rpcclnt *rpc) so->s_crefs = 1; rpc->rc_so = so; - /* Always set receive timeout to detect server crash and reconnect. - * Otherwise, we can get stuck in psock_receive forever. - */ + /* Always set receive timeout to detect server crash and reconnect. + * Otherwise, we can get stuck in psock_receive forever. + */ tv.tv_sec = 1; tv.tv_usec = 0; diff --git a/fs/nxffs/README.txt b/fs/nxffs/README.txt index af631a94b055621ca02a74e0bd780a1f655b1f20..e7d38e4e634687a3d8462ad6824336ecd5c84b25 100644 --- a/fs/nxffs/README.txt +++ b/fs/nxffs/README.txt @@ -175,6 +175,6 @@ Things to Do done. That garbarge collection should search for valid blocks that no longer contain valid data. It should pre-erase them, put them in a good but empty state... all ready for file system re-organization. - - +- And worse, when NXFSS reorganization the FLASH a power cycle can + damage the file system content if it happens at the wrong time. diff --git a/fs/nxffs/nxffs.h b/fs/nxffs/nxffs.h index 89adb6dac11be224dee641b9a72d6f9307739446..04dba9f3afab27f924d3ccd7449dbc08544d6d44 100644 --- a/fs/nxffs/nxffs.h +++ b/fs/nxffs/nxffs.h @@ -316,7 +316,7 @@ struct nxffs_blkstats_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* The magic number that appears that the beginning of each NXFFS (logical) diff --git a/fs/nxffs/nxffs_block.c b/fs/nxffs/nxffs_block.c index ff62811b8b02bd6335848940946be53658c1e6a5..8dd6a47ee8dc8e35bca0eb150f7a587ea1d27e70 100644 --- a/fs/nxffs/nxffs_block.c +++ b/fs/nxffs/nxffs_block.c @@ -59,7 +59,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/nxffs/nxffs_blockstats.c b/fs/nxffs/nxffs_blockstats.c index 62753e5a87d1cf2c6bead1534c76ef39c8f528ee..4ff1bd8b3a154e7eb56f879fa41046ffc2ea2cbb 100644 --- a/fs/nxffs/nxffs_blockstats.c +++ b/fs/nxffs/nxffs_blockstats.c @@ -58,7 +58,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -125,7 +125,7 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, * in the NXFFS data. */ - FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)bptr; + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)bptr; /* Increment the total count of blocks examined */ @@ -203,7 +203,7 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, * in the NXFFS data. */ - FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)volume->pack; + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)volume->pack; /* Collect statistics */ /* Check if this is a block that should be recognized by NXFFS */ diff --git a/fs/nxffs/nxffs_cache.c b/fs/nxffs/nxffs_cache.c index 5d87cb23938cf33d3afd4851fb55f223852404e2..2a04d6b0a9f93c0554010511cba743012d8c6cbf 100644 --- a/fs/nxffs/nxffs_cache.c +++ b/fs/nxffs/nxffs_cache.c @@ -58,7 +58,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/nxffs/nxffs_dirent.c b/fs/nxffs/nxffs_dirent.c index 2afc694e52172b5cb67c4d5652bbed1b0ec70a93..34d8654bf5816edab4c8a138b18216e1c90f2d04 100644 --- a/fs/nxffs/nxffs_dirent.c +++ b/fs/nxffs/nxffs_dirent.c @@ -62,7 +62,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/nxffs/nxffs_dump.c b/fs/nxffs/nxffs_dump.c index 19e4d4b5ce68ce74d08c48f8bac02e164f0ccbdf..1be0e294ac610fe4a4c01930e81c0a510402c016 100644 --- a/fs/nxffs/nxffs_dump.c +++ b/fs/nxffs/nxffs_dump.c @@ -149,16 +149,16 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, return ERROR; } - spaceleft = (blkinfo->nblocks - blkinfo->block) * blkinfo->geo.blocksize; - spaceleft -= (offset + SIZEOF_NXFFS_BLOCK_HDR); - if (datlen > spaceleft) - { - /* The data length is greater than what would fit in the rest of FLASH - * (even ignoring block and data header sizes. - */ + spaceleft = (blkinfo->nblocks - blkinfo->block) * blkinfo->geo.blocksize; + spaceleft -= (offset + SIZEOF_NXFFS_BLOCK_HDR); + if (datlen > spaceleft) + { + /* The data length is greater than what would fit in the rest of FLASH + * (even ignoring block and data header sizes. + */ - return ERROR; - } + return ERROR; + } /* The name begins after the inode header. Does it begin in this block? */ diff --git a/fs/nxffs/nxffs_initialize.c b/fs/nxffs/nxffs_initialize.c index 13081b6c1d535ab41457ee2bd10432ba83b4f801..b453b38b9b0b7015e48b2514fcbb2421468748fe 100644 --- a/fs/nxffs/nxffs_initialize.c +++ b/fs/nxffs/nxffs_initialize.c @@ -66,7 +66,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -103,24 +103,33 @@ const struct mountpt_operations nxffs_operations = }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* The magic number that appears that the beginning of each NXFFS (logical) * block */ -const uint8_t g_blockmagic[NXFFS_MAGICSIZE] = { 'B', 'l', 'c', 'k' }; +const uint8_t g_blockmagic[NXFFS_MAGICSIZE] = +{ + 'B', 'l', 'c', 'k' +}; /* The magic number that appears that the beginning of each NXFFS inode */ -const uint8_t g_inodemagic[NXFFS_MAGICSIZE] = { 'I', 'n', 'o', 'd' }; +const uint8_t g_inodemagic[NXFFS_MAGICSIZE] = +{ + 'I', 'n', 'o', 'd' +}; /* The magic number that appears that the beginning of each NXFFS inode * data block. */ -const uint8_t g_datamagic[NXFFS_MAGICSIZE] = { 'D', 'a', 't', 'a' }; +const uint8_t g_datamagic[NXFFS_MAGICSIZE] = +{ + 'D', 'a', 't', 'a' +}; /* If CONFIG_NXFFS_PREALLOCATED is defined, then this is the single, pre- * allocated NXFFS volume instance. @@ -427,7 +436,7 @@ int nxffs_limits(FAR struct nxffs_volume_s *volume) nxffs_ioseek(volume, offset); nerased = 0; - for (;;) + for (; ; ) { int ch = nxffs_getc(volume, 1); if (ch < 0) diff --git a/fs/nxffs/nxffs_inode.c b/fs/nxffs/nxffs_inode.c index fb184789399f3b77885167fd47d451a4c18fc903..63ba8cbb466b623620d1ba541e68e7800c224a5f 100644 --- a/fs/nxffs/nxffs_inode.c +++ b/fs/nxffs/nxffs_inode.c @@ -61,7 +61,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -276,7 +276,7 @@ int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset, nerased = 0; nmagic = 0; - for (;;) + for (; ; ) { /* Read the next character */ @@ -401,7 +401,7 @@ int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name, * media. */ - for (;;) + for (; ; ) { /* Get the next, valid NXFFS inode entry */ diff --git a/fs/nxffs/nxffs_ioctl.c b/fs/nxffs/nxffs_ioctl.c index 96d39c3392203f0c198d4c7054c27779c760ec62..ec2cd041de8a40d2f5548e4a058aed2541627705 100644 --- a/fs/nxffs/nxffs_ioctl.c +++ b/fs/nxffs/nxffs_ioctl.c @@ -61,7 +61,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/nxffs/nxffs_open.c b/fs/nxffs/nxffs_open.c index 07e115a154b9353b379317bbe31f00c79a0802ec..f665623a06342bac3a30f169f1180c31ada2e847 100644 --- a/fs/nxffs/nxffs_open.c +++ b/fs/nxffs/nxffs_open.c @@ -450,7 +450,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * exclusively. */ - else if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + else if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { fdbg("ERROR: File exists, can't create O_EXCL\n"); ret = -EEXIST; @@ -462,7 +462,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * we will not re-create the file unless O_CREAT is also specified. */ - else if ((oflags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC)) + else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) { /* Just schedule the removal the file and fall through to re-create it. * Note that the old file of the same name will not actually be removed @@ -546,7 +546,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, */ packed = false; - for (;;) + for (; ; ) { /* File a valid location to position the inode header. Start with the * first byte in the free FLASH region. @@ -600,7 +600,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * Note that nothing is written to FLASH. */ - for (;;) + for (; ; ) { /* File a valid location to position the inode name. Start with the * first byte in the free FLASH region. @@ -853,7 +853,7 @@ static inline void nxffs_freeofile(FAR struct nxffs_volume_s *volume, */ #ifdef CONFIG_NXFFS_PREALLOCATED - if ((FAR struct nxffs_wrfile_s*)ofile != &g_wrfile) + if ((FAR struct nxffs_wrfile_s *)ofile != &g_wrfile) #endif { kmm_free(ofile); @@ -1022,7 +1022,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath, * file structure */ - volume = (FAR struct nxffs_volume_s*)filep->f_inode->i_private; + volume = (FAR struct nxffs_volume_s *)filep->f_inode->i_private; DEBUGASSERT(volume != NULL); #ifdef CONFIG_FILE_MODE @@ -1036,7 +1036,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath, * extension is supported. */ - switch (oflags & (O_WROK|O_RDOK)) + switch (oflags & (O_WROK | O_RDOK)) { case 0: default: @@ -1051,7 +1051,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath, ret = nxffs_rdopen(volume, relpath, &ofile); break; - case O_WROK|O_RDOK: + case O_WROK | O_RDOK: fdbg("ERROR: O_RDWR is not supported\n"); return -ENOSYS; } @@ -1092,7 +1092,7 @@ int nxffs_dup(FAR const struct file *oldp, FAR struct file *newp) * file structure */ - volume = (FAR struct nxffs_volume_s*)oldp->f_inode->i_private; + volume = (FAR struct nxffs_volume_s *)oldp->f_inode->i_private; DEBUGASSERT(volume != NULL); #endif diff --git a/fs/nxffs/nxffs_pack.c b/fs/nxffs/nxffs_pack.c index 373b480bb55242263fc0688fdebaf1cd3fdd4dc6..14c9e8d8f1ef12d01f9bd169af9717f1999146e1 100644 --- a/fs/nxffs/nxffs_pack.c +++ b/fs/nxffs/nxffs_pack.c @@ -89,7 +89,7 @@ struct nxffs_pack_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -286,7 +286,7 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume, * compacting. */ - for (;;) + for (; ; ) { /* Is there wasted space between the offset where the we could have * valid data and the offset to the beginning of the first valid @@ -358,12 +358,12 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume, ret = nxffs_validblock(volume, &volume->ioblock); if (ret < 0) { - /* No valid blocks? Then there is nothing we can do. Return - * the end-of-flash indication. - */ + /* No valid blocks? Then there is nothing we can do. Return + * the end-of-flash indication. + */ - *froffset = volume->froffset; - return -ENOSPC; + *froffset = volume->froffset; + return -ENOSPC; } volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR; @@ -933,7 +933,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, * block is full, or (3) an error occurs. */ - for (;;) + for (; ; ) { /* Transfer data from the source buffer to the destination buffer */ @@ -1186,39 +1186,39 @@ static inline int nxffs_packwriter(FAR struct nxffs_volume_s *volume, * block is full, or (3) an error occurs. */ - for (;;) + for (; ; ) { - /* Transfer data from the source buffer to the destination buffer */ + /* Transfer data from the source buffer to the destination buffer */ - nxffs_packtransfer(volume, pack); + nxffs_packtransfer(volume, pack); - /* Now, either the (1) src block has been fully transferred, (2) all - * of the source data has been transferred, or (3) the destination - * block is full, .. or all three. - * - * Check if all of the bytes in the source inode have been transferred. - */ + /* Now, either the (1) src block has been fully transferred, (2) all + * of the source data has been transferred, or (3) the destination + * block is full, .. or all three. + * + * Check if all of the bytes in the source inode have been transferred. + */ - if (pack->src.fpos >= pack->src.entry.datlen) - { - /* Write the final destination data block header and inode - * headers. - */ + if (pack->src.fpos >= pack->src.entry.datlen) + { + /* Write the final destination data block header and inode + * headers. + */ - nxffs_wrdathdr(volume, pack); + nxffs_wrdathdr(volume, pack); - /* Set the new offsets in the open file instance. */ + /* Set the new offsets in the open file instance. */ - wrfile->ofile.entry.hoffset = pack->dest.entry.hoffset; - wrfile->ofile.entry.noffset = pack->dest.entry.noffset; - wrfile->ofile.entry.doffset = pack->dest.entry.doffset; + wrfile->ofile.entry.hoffset = pack->dest.entry.hoffset; + wrfile->ofile.entry.noffset = pack->dest.entry.noffset; + wrfile->ofile.entry.doffset = pack->dest.entry.doffset; - /* Return an end-of-flash error to indicate that all of the write - * data has been transferred. - */ + /* Return an end-of-flash error to indicate that all of the write + * data has been transferred. + */ - return -ENOSPC; - } + return -ENOSPC; + } /* Not at the end of the source data stream. Check if we are at the * end of the current source data block. @@ -1312,7 +1312,7 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume) /* No, there is no write in progress. We just have an empty flash * full of deleted files. In this case, the media needs to be re- * formatted. - */ + */ ret = nxffs_reformat(volume); if (ret == OK) @@ -1359,19 +1359,19 @@ int nxffs_pack(FAR struct nxffs_volume_s *volume) if (iooffset + CONFIG_NXFFS_TAILTHRESHOLD < volume->froffset) { - /* Setting 'packed' to true will supress normal inode packing - * operation. - */ + /* Setting 'packed' to true will supress normal inode packing + * operation. + */ - packed = true; + packed = true; - /* Writing is performed at the end of the free FLASH region. - * If we are not packing files, we could still need to pack - * the partially written file at the end of FLASH. - */ + /* Writing is performed at the end of the free FLASH region. + * If we are not packing files, we could still need to pack + * the partially written file at the end of FLASH. + */ - wrfile = nxffs_setupwriter(volume, &pack); - } + wrfile = nxffs_setupwriter(volume, &pack); + } /* Otherwise return OK.. meaning that there is nothing more we can * do to recover FLASH space. @@ -1422,7 +1422,7 @@ start_pack: ret = MTD_BREAD(volume->mtd, pack.block0, volume->blkper, volume->pack); if (ret < 0) { - fdbg("ERROR: Failed to read erase block %d: %d\n", eblock,-ret); + fdbg("ERROR: Failed to read erase block %d: %d\n", eblock, -ret); goto errout_with_pack; } @@ -1462,120 +1462,120 @@ start_pack: i < volume->blkper; i++, block++, pack.iobuffer += volume->geo.blocksize) { - /* The first time here, the ioblock may point to an offset into - * the erase block. We just need to skip over those cases. - */ - - if (block >= pack.ioblock) - { - /* Set the I/O position. Note on the first time we get - * pack.iooffset will hold the offset in the first I/O block - * to the first inode header. After that, it will always - * refer to the first byte after the block header. - */ - - pack.ioblock = block; - - /* If this is not a valid block or if we have already - * finished packing the valid inode entries, then just fall - * through, reset the FLASH memory to the erase state, and - * write the reset values to FLASH. (The first block that - * we want to process will always be valid -- we have - * already verified that). - */ - - if (nxffs_packvalid(&pack)) - { - /* Have we finished packing inodes? */ - - if (!packed) - { - DEBUGASSERT(wrfile == NULL); - - /* Pack inode data into this block */ - - ret = nxffs_packblock(volume, &pack); - if (ret < 0) - { - /* The error -ENOSPC is a special value that simply - * means that there is nothing further to be packed. - */ - - if (ret == -ENOSPC) - { - packed = true; - - /* Writing is performed at the end of the free - * FLASH region and this implemenation is restricted - * to a single writer. The new inode is not - * written to FLASH until the writer is closed - * and so will not be found by nxffs_packblock(). - */ - - wrfile = nxffs_setupwriter(volume, &pack); - } - else - { - /* Otherwise, something really bad happened */ - - fdbg("ERROR: Failed to pack into block %d: %d\n", - block, ret); - goto errout_with_pack; - } - } - } - - /* If all of the "normal" inodes have been packed, then check if - * we need to pack the current, in-progress write operation. - */ - - if (wrfile) - { - DEBUGASSERT(packed == true); - - /* Pack write data into this block */ - - ret = nxffs_packwriter(volume, &pack, wrfile); - if (ret < 0) - { - /* The error -ENOSPC is a special value that simply - * means that there is nothing further to be packed. - */ - - if (ret == -ENOSPC) - { - wrfile = NULL; - } - else - { - /* Otherwise, something really bad happened */ - - fdbg("ERROR: Failed to pack into block %d: %d\n", - block, ret); - goto errout_with_pack; - } - } - } - } - - /* Set any unused portion at the end of the block to the - * erased state. - */ - - if (pack.iooffset < volume->geo.blocksize) - { - memset(&pack.iobuffer[pack.iooffset], - CONFIG_NXFFS_ERASEDSTATE, - volume->geo.blocksize - pack.iooffset); - } - - /* Next time through the loop, pack.iooffset will point to the - * first byte after the block header. - */ - - pack.iooffset = SIZEOF_NXFFS_BLOCK_HDR; - } - } + /* The first time here, the ioblock may point to an offset into + * the erase block. We just need to skip over those cases. + */ + + if (block >= pack.ioblock) + { + /* Set the I/O position. Note on the first time we get + * pack.iooffset will hold the offset in the first I/O block + * to the first inode header. After that, it will always + * refer to the first byte after the block header. + */ + + pack.ioblock = block; + + /* If this is not a valid block or if we have already + * finished packing the valid inode entries, then just fall + * through, reset the FLASH memory to the erase state, and + * write the reset values to FLASH. (The first block that + * we want to process will always be valid -- we have + * already verified that). + */ + + if (nxffs_packvalid(&pack)) + { + /* Have we finished packing inodes? */ + + if (!packed) + { + DEBUGASSERT(wrfile == NULL); + + /* Pack inode data into this block */ + + ret = nxffs_packblock(volume, &pack); + if (ret < 0) + { + /* The error -ENOSPC is a special value that simply + * means that there is nothing further to be packed. + */ + + if (ret == -ENOSPC) + { + packed = true; + + /* Writing is performed at the end of the free + * FLASH region and this implemenation is restricted + * to a single writer. The new inode is not + * written to FLASH until the writer is closed + * and so will not be found by nxffs_packblock(). + */ + + wrfile = nxffs_setupwriter(volume, &pack); + } + else + { + /* Otherwise, something really bad happened */ + + fdbg("ERROR: Failed to pack into block %d: %d\n", + block, ret); + goto errout_with_pack; + } + } + } + + /* If all of the "normal" inodes have been packed, then check if + * we need to pack the current, in-progress write operation. + */ + + if (wrfile) + { + DEBUGASSERT(packed == true); + + /* Pack write data into this block */ + + ret = nxffs_packwriter(volume, &pack, wrfile); + if (ret < 0) + { + /* The error -ENOSPC is a special value that simply + * means that there is nothing further to be packed. + */ + + if (ret == -ENOSPC) + { + wrfile = NULL; + } + else + { + /* Otherwise, something really bad happened */ + + fdbg("ERROR: Failed to pack into block %d: %d\n", + block, ret); + goto errout_with_pack; + } + } + } + } + + /* Set any unused portion at the end of the block to the + * erased state. + */ + + if (pack.iooffset < volume->geo.blocksize) + { + memset(&pack.iobuffer[pack.iooffset], + CONFIG_NXFFS_ERASEDSTATE, + volume->geo.blocksize - pack.iooffset); + } + + /* Next time through the loop, pack.iooffset will point to the + * first byte after the block header. + */ + + pack.iooffset = SIZEOF_NXFFS_BLOCK_HDR; + } + } /* We now have an in-memory image of how we want this erase block to * appear. Now it is safe to erase the block. diff --git a/fs/nxffs/nxffs_read.c b/fs/nxffs/nxffs_read.c index c548f5e50e1ed2b74b5b7b3f1875dfaa138c3783..6bd09374f9146bc7e091258fe06f803e3547bc8d 100644 --- a/fs/nxffs/nxffs_read.c +++ b/fs/nxffs/nxffs_read.c @@ -62,7 +62,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -294,7 +294,7 @@ int nxffs_nextblock(FAR struct nxffs_volume_s *volume, off_t offset, nerased = 0; nmagic = 0; - for (;;) + for (; ; ) { /* Read the next character */ diff --git a/fs/nxffs/nxffs_reformat.c b/fs/nxffs/nxffs_reformat.c index ec85ee05c9bd40ac11edf82eacd32abf05c56974..ba151f4cc9c8e50e6a0fa645180c6b8961e93909 100644 --- a/fs/nxffs/nxffs_reformat.c +++ b/fs/nxffs/nxffs_reformat.c @@ -58,7 +58,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -190,7 +190,7 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume) i++, block++, blkptr += volume->geo.blocksize) #endif { - FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)blkptr; + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)blkptr; /* Assume that this is a good block until we learn otherwise */ @@ -330,7 +330,7 @@ int nxffs_reformat(FAR struct nxffs_volume_s *volume) void nxffs_blkinit(FAR struct nxffs_volume_s *volume, FAR uint8_t *blkptr, uint8_t state) { - FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)blkptr; + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s *)blkptr; memset(blkptr, CONFIG_NXFFS_ERASEDSTATE, volume->geo.blocksize); memcpy(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE); diff --git a/fs/nxffs/nxffs_stat.c b/fs/nxffs/nxffs_stat.c index 2a5b610449164ab6b698d557d47a217fe7b9bfe7..f4a16a2117ae7f493ec79b348c800d421eced08a 100644 --- a/fs/nxffs/nxffs_stat.c +++ b/fs/nxffs/nxffs_stat.c @@ -63,7 +63,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -166,7 +166,7 @@ int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath, } buf->st_blocks = entry.datlen / (volume->geo.blocksize - SIZEOF_NXFFS_BLOCK_HDR); - buf->st_mode = S_IFREG|S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode = S_IFREG | S_IXOTH | S_IXGRP | S_IXUSR; buf->st_size = entry.datlen; buf->st_atime = entry.utc; buf->st_mtime = entry.utc; @@ -180,7 +180,8 @@ int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath, { /* It's a read/execute-only directory name */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR | S_IXOTH | + S_IXGRP | S_IXUSR; } ret = OK; diff --git a/fs/nxffs/nxffs_unlink.c b/fs/nxffs/nxffs_unlink.c index ec61979596bf64ae483e86d3b71ca98f007524d6..8422616057d9b9df053790ed2f5df549a8694a34 100644 --- a/fs/nxffs/nxffs_unlink.c +++ b/fs/nxffs/nxffs_unlink.c @@ -60,7 +60,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/nxffs/nxffs_util.c b/fs/nxffs/nxffs_util.c index f424e71e070aae9eb01509bd1c134f8611d28822..52354d33f94e4f75fe31de7520e61c94b4a1abc6 100644 --- a/fs/nxffs/nxffs_util.c +++ b/fs/nxffs/nxffs_util.c @@ -54,7 +54,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -121,7 +121,7 @@ void nxffs_wrle16(uint8_t *dest, uint16_t val) uint32_t nxffs_rdle32(FAR const uint8_t *val) { - /* Little endian means LS halfword first in byte stream */ + /* Little endian means LS halfword first in byte stream */ return (uint32_t)nxffs_rdle16(&val[2]) << 16 | (uint32_t)nxffs_rdle16(val); } diff --git a/fs/nxffs/nxffs_write.c b/fs/nxffs/nxffs_write.c index 7f081b92d8d77f068ab91f785c4b1f8710c9ac1d..561fb58bea0f16e610630544598ddb2120ab1327 100644 --- a/fs/nxffs/nxffs_write.c +++ b/fs/nxffs/nxffs_write.c @@ -227,7 +227,7 @@ static inline int nxffs_wralloc(FAR struct nxffs_volume_s *volume, */ packed = false; - for (;;) + for (; ; ) { size_t mindata = MIN(NXFFS_MINDATA, size); diff --git a/fs/procfs/Kconfig b/fs/procfs/Kconfig index 9b6b433b107388937025e9c2bd14f0a3ce28f226..b218c405b9ab19bc8ff8590fd2ab2d637c1f4a09 100644 --- a/fs/procfs/Kconfig +++ b/fs/procfs/Kconfig @@ -15,6 +15,13 @@ config FS_PROCFS if FS_PROCFS +config FS_PROCFS_REGISTER + bool "Run-time registration" + default n + ---help--- + Support run-time registration of the new entries in the procfs file + system. + menu "Exclude individual procfs entries" config FS_PROCFS_EXCLUDE_PROCESS @@ -25,6 +32,13 @@ config FS_PROCFS_EXCLUDE_PROCESS This will reduce code space, but then giving access to process info was kinda the whole point of procfs, but hey, whatever. +config FS_PROCFS_EXCLUDE_MODULE + bool "Exclude module information" + depends on MODULE + default n + ---help--- + Causes the module information to be excluded from the procfs system. + config FS_PROCFS_EXCLUDE_UPTIME bool "Exclude uptime" default n @@ -34,11 +48,21 @@ config FS_PROCFS_EXCLUDE_CPULOAD default n depends on SCHED_CPULOAD +config FS_PROCFS_EXCLUDE_KMM + bool "Exclude kmm" + default n + depends on MM_KERNEL_HEAP + config FS_PROCFS_EXCLUDE_MOUNTS bool "Exclude mounts" default n depends on !DISABLE_MOUNTPOINT +config FS_PROCFS_EXCLUDE_NET + bool "Exclude network" + depends on NET + default n + config FS_PROCFS_EXCLUDE_MTD bool "Exclude mtd" depends on MTD @@ -54,10 +78,5 @@ config FS_PROCFS_EXCLUDE_SMARTFS depends on FS_SMARTFS default n -config FS_PROCFS_EXCLUDE_CCM - bool "Exclude CCM memory usage" - depends on STM32_CCM_PROCFS - default n - endmenu # endif # FS_PROCFS diff --git a/fs/procfs/Make.defs b/fs/procfs/Make.defs index 63cd07eb91a8f041f571ba0531bcad6fe54b2216..434e85799e8b6365f297f2888ee9348fd0829117 100644 --- a/fs/procfs/Make.defs +++ b/fs/procfs/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # fs/procfs/Make.defs # -# Copyright (C) 2013 Gregory Nutt. All rights reserved. +# Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -38,7 +38,7 @@ ifeq ($(CONFIG_FS_PROCFS),y) ASRCS += CSRCS += fs_procfs.c fs_procfsutil.c fs_procfsproc.c fs_procfsuptime.c -CSRCS += fs_procfscpuload.c +CSRCS += fs_procfscpuload.c fs_procfskmm.c # Include procfs build support diff --git a/fs/procfs/fs_procfs.c b/fs/procfs/fs_procfs.c index 6ed06f389159558640881b01c5077667dbac6c13..506ab9fcb5412da70a2f8ab95323eee0e576eba8 100644 --- a/fs/procfs/fs_procfs.c +++ b/fs/procfs/fs_procfs.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/procfs/fs_procfs.c * - * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -61,8 +62,6 @@ #include #include -#include - #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) /**************************************************************************** @@ -77,12 +76,17 @@ extern const struct procfs_operations proc_operations; extern const struct procfs_operations cpuload_operations; +extern const struct procfs_operations kmm_operations; +extern const struct procfs_operations module_operations; extern const struct procfs_operations uptime_operations; -/* This is not good. These are implemented in drivers/mtd. Having to - * deal with them here is not a good coupling. +/* This is not good. These are implemented in other sub-systems. Having to + * deal with them here is not a good coupling. What is really needed is a + * run-time procfs registration system vs. a build time, fixed procfs + * configuration. */ +extern const struct procfs_operations net_procfsoperations; extern const struct procfs_operations mtd_procfsoperations; extern const struct procfs_operations part_procfsoperations; extern const struct procfs_operations smartfs_procfsoperations; @@ -101,7 +105,11 @@ extern const struct procfs_operations ccm_procfsoperations; ****************************************************************************/ /* Table of all known / pre-registered procfs handlers / participants. */ -static const struct procfs_entry_s g_procfsentries[] = +#ifdef CONFIG_FS_PROCFS_REGISTER +static const struct procfs_entry_s g_base_entries[] = +#else +static const struct procfs_entry_s g_procfs_entries[] = +#endif { #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS { "[0-9]*/**", &proc_operations }, @@ -112,11 +120,24 @@ static const struct procfs_entry_s g_procfsentries[] = { "cpuload", &cpuload_operations }, #endif +#if defined(CONFIG_MM_KERNEL_HEAP) && !defined(CONFIG_FS_PROCFS_EXCLUDE_KMM) + { "kmm", &kmm_operations }, +#endif + +#if defined(CONFIG_MODULE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + { "modules", &module_operations }, +#endif + #if defined(CONFIG_FS_SMARTFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS) //{ "fs/smartfs", &smartfs_procfsoperations }, { "fs/smartfs**", &smartfs_procfsoperations }, #endif +#if defined(CONFIG_NET) && !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) + { "net", &net_procfsoperations }, + { "net/**", &net_procfsoperations }, +#endif + #if defined(CONFIG_MTD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MTD) { "mtd", &mtd_procfsoperations }, #endif @@ -128,14 +149,18 @@ static const struct procfs_entry_s g_procfsentries[] = #if !defined(CONFIG_FS_PROCFS_EXCLUDE_UPTIME) { "uptime", &uptime_operations }, #endif - -#if defined(CONFIG_STM32_CCM_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_CCM) - { "ccm", &ccm_procfsoperations }, -#endif }; -static const uint8_t g_procfsentrycount = sizeof(g_procfsentries) / +#ifdef CONFIG_FS_PROCFS_REGISTER +static const uint8_t g_base_entrycount = sizeof(g_base_entries) / + sizeof(struct procfs_entry_s); + +static FAR struct procfs_entry_s *g_procfs_entries; +static uint8_t g_procfs_entrycount; +#else +static const uint8_t g_procfs_entrycount = sizeof(g_procfs_entries) / sizeof(struct procfs_entry_s); +#endif /**************************************************************************** * Private Function Prototypes @@ -178,12 +203,20 @@ static int procfs_statfs(FAR struct inode *mountpt, static int procfs_stat(FAR struct inode *mountpt, FAR const char *relpath, FAR struct stat *buf); +/* Initialization */ + +#ifdef CONFIG_FS_PROCFS_REGISTER +int procfs_initialize(void); +#else +# define procfs_initialize() +#endif + /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -293,25 +326,25 @@ static int procfs_open(FAR struct file *filep, FAR const char *relpath, /* Perform the stat based on the procfs_entry operations */ - for (x = 0; x < g_procfsentrycount; x++) + for (x = 0; x < g_procfs_entrycount; x++) { /* Test if the path matches this entry's specification */ - if (match(g_procfsentries[x].pathpattern, relpath)) + if (match(g_procfs_entries[x].pathpattern, relpath)) { /* Match found! Stat using this procfs entry */ - DEBUGASSERT(g_procfsentries[x].ops && - g_procfsentries[x].ops->open); + DEBUGASSERT(g_procfs_entries[x].ops && + g_procfs_entries[x].ops->open); - ret = g_procfsentries[x].ops->open(filep, relpath, oflags, mode); + ret = g_procfs_entries[x].ops->open(filep, relpath, oflags, mode); if (ret == OK) { DEBUGASSERT(filep->f_priv); ((struct procfs_file_s *) filep->f_priv)->procfsentry = - &g_procfsentries[x]; + &g_procfs_entries[x]; } } } @@ -475,15 +508,15 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, */ #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS - flags = irqsave(); + flags = enter_critical_section(); sched_foreach(procfs_enum, level0); - irqrestore(flags); + leave_critical_section(flags); #else level0->base.index = 0; level0->base.nentries = 0; #endif - /* Initialze lastread entries */ + /* Initialize lastread entries */ level0->lastread = ""; level0->lastlen = 0; @@ -498,19 +531,19 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, /* Search the static array of procfs_entries */ - for (x = 0; x < g_procfsentrycount; x++) + for (x = 0; x < g_procfs_entrycount; x++) { /* Test if the path matches this entry's specification */ - if (match(g_procfsentries[x].pathpattern, relpath)) + if (match(g_procfs_entries[x].pathpattern, relpath)) { /* Match found! Call the handler's opendir routine. If successful, * this opendir routine will create an entry derived from struct * procfs_dir_priv_s as dir->u.procfs. */ - DEBUGASSERT(g_procfsentries[x].ops && g_procfsentries[x].ops->opendir); - ret = g_procfsentries[x].ops->opendir(relpath, dir); + DEBUGASSERT(g_procfs_entries[x].ops && g_procfs_entries[x].ops->opendir); + ret = g_procfs_entries[x].ops->opendir(relpath, dir); if (ret == OK) { @@ -519,7 +552,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, /* Set the procfs_entry handler */ dirpriv = (FAR struct procfs_dir_priv_s *)dir->u.procfs; - dirpriv->procfsentry = &g_procfsentries[x]; + dirpriv->procfsentry = &g_procfs_entries[x]; } return ret; @@ -527,13 +560,13 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, /* Test for a sub-string match (e.g. "ls /proc/fs") */ - else if (strncmp(g_procfsentries[x].pathpattern, relpath, len) == 0) + else if (strncmp(g_procfs_entries[x].pathpattern, relpath, len) == 0) { FAR struct procfs_level1_s *level1; /* Doing an intermediate directory search */ - /* The path refers to the top level directory. Allocate the level0 + /* The path refers to the top level directory. Allocate the level1 * dirent structure. */ @@ -627,9 +660,9 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) * directory name. */ - while (index < priv->nentries + g_procfsentrycount) + while (index < priv->nentries + g_procfs_entrycount) { - name = g_procfsentries[index - priv->nentries].pathpattern; + name = g_procfs_entries[index - priv->nentries].pathpattern; while (*name != '/' && *name != '\0') { if (*name == '*' || *name == '[' || *name == '?') @@ -647,38 +680,38 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) /* Test if we skipped this entry */ if (name != NULL) - { - /* This entry is okay to report. Test if it has a duplicate - * first level name as the one we just reported. This could - * happen in the event of procfs_entry_s such as: - * - * fs/smartfs - * fs/nfs - * fs/nxffs - */ - - name = g_procfsentries[index - priv->nentries].pathpattern; - if (!level0->lastlen || (strncmp(name, level0->lastread, + { + /* This entry is okay to report. Test if it has a duplicate + * first level name as the one we just reported. This could + * happen in the event of procfs_entry_s such as: + * + * fs/smartfs + * fs/nfs + * fs/nxffs + */ + + name = g_procfs_entries[index - priv->nentries].pathpattern; + if (!level0->lastlen || (strncmp(name, level0->lastread, level0->lastlen) != 0)) - { - /* Not a duplicate, return the first segment of this - * entry - */ - - break; - } - else - { - /* Skip this entry ... duplicate 1st level name found */ - - index++; - } - } + { + /* Not a duplicate, return the first segment of this + * entry + */ + + break; + } + else + { + /* Skip this entry ... duplicate 1st level name found */ + + index++; + } + } } /* Test if we are at the end of the directory */ - if (index >= priv->nentries + g_procfsentrycount) + if (index >= priv->nentries + g_procfs_entrycount) { /* We signal the end of the directory by returning the special * error -ENOENT @@ -718,9 +751,9 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) pid = level0->pid[index]; - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(pid); - irqrestore(flags); + leave_critical_section(flags); if (!tcb) { @@ -755,13 +788,13 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) * subdirectory are listed in order in the procfs_entry array. */ - if (strncmp(g_procfsentries[level1->base.index].pathpattern, - g_procfsentries[level1->firstindex].pathpattern, - level1->subdirlen) == 0) + if (strncmp(g_procfs_entries[level1->base.index].pathpattern, + g_procfs_entries[level1->firstindex].pathpattern, + level1->subdirlen) == 0) { /* This entry matches. Report the subdir entry */ - name = &g_procfsentries[level1->base.index].pathpattern[ + name = &g_procfs_entries[level1->base.index].pathpattern[ level1->subdirlen + 1]; level1->lastlen = strcspn(name, "/"); level1->lastread = name; @@ -851,6 +884,9 @@ static int procfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir) static int procfs_bind(FAR struct inode *blkdriver, const void *data, void **handle) { + /* Make sure that we are properly initialized */ + + procfs_initialize(); return OK; } @@ -915,7 +951,7 @@ static int procfs_stat(struct inode *mountpt, const char *relpath, /* The path refers to the top level directory */ /* It's a read-only directory */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; ret = OK; } else @@ -925,27 +961,27 @@ static int procfs_stat(struct inode *mountpt, const char *relpath, /* Perform the stat based on the procfs_entry operations */ - for (x = 0; x < g_procfsentrycount; x++) + for (x = 0; x < g_procfs_entrycount; x++) { /* Test if the path matches this entry's specification */ - if (match(g_procfsentries[x].pathpattern, relpath)) + if (match(g_procfs_entries[x].pathpattern, relpath)) { /* Match found! Stat using this procfs entry */ - DEBUGASSERT(g_procfsentries[x].ops && - g_procfsentries[x].ops->stat); + DEBUGASSERT(g_procfs_entries[x].ops && + g_procfs_entries[x].ops->stat); - return g_procfsentries[x].ops->stat(relpath, buf); + return g_procfs_entries[x].ops->stat(relpath, buf); } /* Test for an internal subdirectory stat */ - else if (strncmp(g_procfsentries[x].pathpattern, relpath, len) == 0) + else if (strncmp(g_procfs_entries[x].pathpattern, relpath, len) == 0) { /* It's an internal subdirectory */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; ret = OK; break; } @@ -960,8 +996,120 @@ static int procfs_stat(struct inode *mountpt, const char *relpath, return ret; } +/**************************************************************************** + * Name: procfs_initialize + * + * Description: + * Configure the initial set of entries in the procfs file system. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef CONFIG_FS_PROCFS_REGISTER +int procfs_initialize(void) +{ + /* Are we already initialized? */ + + if (g_procfs_entries == NULL) + { + /* No.. allocate a modifyable list of entries */ + + g_procfs_entries = (FAR struct procfs_entry_s *) + kmm_malloc(sizeof(g_base_entries)); + + if (g_procfs_entries == NULL) + { + return -ENOMEM; + } + + /* And copy the fixed entries into the allocated array */ + + memcpy(g_procfs_entries, g_base_entries, sizeof(g_base_entries)); + g_procfs_entrycount = g_base_entrycount; + } + + return OK; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: procfs_register + * + * Description: + * Add a new entry to the procfs file system. + * + * NOTE: This function should be called *prior* to mounting the procfs + * file system to prevent concurrency problems with the modification of + * the procfs data set while it is in use. + * + * Input Parameters: + * entry - Describes the entry to be registered. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef CONFIG_FS_PROCFS_REGISTER +int procfs_register(FAR const struct procfs_entry_s *entry) +{ + FAR struct procfs_entry_s *newtable; + unsigned int newcount; + size_t newsize; + int ret; + + /* Make sure that we are properly initialized */ + + procfs_initialize(); + + /* realloc the table of procfs entries. + * + * REVISIT: This reallocation may free memory previously used for the + * procfs entry table. If that table were actively in use, then that + * could cause procfs logic to use a stale memory pointer! We avoid that + * problem by requiring that the procfs file be unmounted when the new + * entry is added. That requirment, however, is not enforced explicitly. + * + * Locking the scheduler as done below is insufficient. As would be just + * marking the entries as volatile. + */ + + newcount = g_procfs_entrycount + 1; + newsize = newcount * sizeof(struct procfs_entry_s); + + sched_lock(); + newtable = (FAR struct procfs_entry_s *)kmm_realloc(g_procfs_entries, newsize); + if (newtable == NULL) + { + /* Reallocation failed! */ + + ret = -ENOMEM; + } + else + { + /* Copy the new entry at the end of the reallocated table */ + + memcpy(&newtable[g_procfs_entrycount], entry, sizeof(struct procfs_entry_s)); + + /* Instantiate the reallocated table */ + + g_procfs_entries = newtable; + g_procfs_entrycount = newcount; + ret = OK; + } + + sched_unlock(); + return ret; +} +#endif + #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS */ diff --git a/fs/procfs/fs_procfscpuload.c b/fs/procfs/fs_procfscpuload.c index 8641f3933562e1cfe59ed3a4faa866f92a6b2587..f33986d71605ec7eff2b67e7387a7baa7a87322e 100644 --- a/fs/procfs/fs_procfscpuload.c +++ b/fs/procfs/fs_procfscpuload.c @@ -100,11 +100,11 @@ static int cpuload_dup(FAR const struct file *oldp, static int cpuload_stat(FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -337,7 +337,7 @@ static int cpuload_stat(const char *relpath, struct stat *buf) /* "cpuload" is the name for a read-only file */ - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; buf->st_size = 0; buf->st_blksize = 0; buf->st_blocks = 0; diff --git a/fs/procfs/fs_procfskmm.c b/fs/procfs/fs_procfskmm.c new file mode 100644 index 0000000000000000000000000000000000000000..3424338dc04893213f7cac08a77849179eb50829 --- /dev/null +++ b/fs/procfs/fs_procfskmm.c @@ -0,0 +1,326 @@ +/**************************************************************************** + * fs/procfs/fs_procfskmm.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_MM_KERNEL_HEAP) && defined(CONFIG_FS_PROCFS) && \ + !defined(CONFIG_FS_PROCFS_EXCLUDE_KMM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define KMM_LINELEN 54 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct kmm_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + unsigned int linesize; /* Number of valid characters in line[] */ + char line[KMM_LINELEN]; /* Pre-allocated buffer for formatted lines */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* File system methods */ + +static int kmm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int kmm_close(FAR struct file *filep); +static ssize_t kmm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int kmm_dup(FAR const struct file *oldp, + FAR struct file *newp); +static int kmm_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* See fs_mount.c -- this structure is explicitly externed there. + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct procfs_operations kmm_operations = +{ + kmm_open, /* open */ + kmm_close, /* close */ + kmm_read, /* read */ + NULL, /* write */ + kmm_dup, /* dup */ + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + kmm_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kmm_open + ****************************************************************************/ + +static int kmm_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct kmm_file_s *procfile; + + fvdbg("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) + { + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "kmm" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "kmm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* Allocate a container to hold the file attributes */ + + procfile = (FAR struct kmm_file_s *)kmm_zalloc(sizeof(struct kmm_file_s)); + if (!procfile) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the attributes as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)procfile; + return OK; +} + +/**************************************************************************** + * Name: kmm_close + ****************************************************************************/ + +static int kmm_close(FAR struct file *filep) +{ + FAR struct kmm_file_s *procfile; + + /* Recover our private data from the struct file instance */ + + procfile = (FAR struct kmm_file_s *)filep->f_priv; + DEBUGASSERT(procfile); + + /* Release the file attributes structure */ + + kmm_free(procfile); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: kmm_read + ****************************************************************************/ + +static ssize_t kmm_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct kmm_file_s *procfile; + struct mallinfo mem; + size_t linesize; + size_t copysize; + size_t totalsize; + off_t offset; + + fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); + + DEBUGASSERT(filep != NULL && buffer != NULL && buflen > 0); + offset = filep->f_pos; + + /* Recover our private data from the struct file instance */ + + procfile = (FAR struct kmm_file_s *)filep->f_priv; + DEBUGASSERT(procfile); + + /* The first line is the headers */ + + linesize = snprintf(procfile->line, KMM_LINELEN, + " total used free largest\n"); + copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, + &offset); + totalsize = copysize; + + if (totalsize < buflen) + { + buffer += copysize; + buflen -= copysize; + + /* The second line is the memory data */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mem = kmm_mallinfo(); +#else + (void)kmm_mallinfo(&mem); +#endif + + linesize = snprintf(procfile->line, KMM_LINELEN, + "Mem: %11d%11d%11d%11d\n", + mem.arena, mem.uordblks, mem.fordblks, + mem.mxordblk); + copysize = procfs_memcpy(procfile->line, linesize, buffer, buflen, + &offset); + totalsize += copysize; + } + + /* Update the file offset */ + + filep->f_pos += totalsize; + return totalsize; +} + +/**************************************************************************** + * Name: kmm_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int kmm_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct kmm_file_s *oldattr; + FAR struct kmm_file_s *newattr; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldattr = (FAR struct kmm_file_s *)oldp->f_priv; + DEBUGASSERT(oldattr); + + /* Allocate a new container to hold the task and attribute selection */ + + newattr = (FAR struct kmm_file_s *)kmm_malloc(sizeof(struct kmm_file_s)); + if (!newattr) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attributes from the old attributes to the new */ + + memcpy(newattr, oldattr, sizeof(struct kmm_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newattr; + return OK; +} + +/**************************************************************************** + * Name: kmm_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int kmm_stat(FAR const char *relpath, FAR struct stat *buf) +{ + /* "kmm" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "kmm") != 0) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* "kmm" is the name for a read-only file */ + + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + buf->st_size = 0; + buf->st_blksize = 0; + buf->st_blocks = 0; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_MM_KERNEL_HEAP && CONFIG_FS_PROCFS && !CONFIG_FS_PROCFS_EXCLUDE_KMM */ diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 869d00f9b4841725c160c01745b45fe69c3373bc..720c5174384692c6253b74fca29506f5a15857d5 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/procfs/fs_procfsproc.c * - * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -64,14 +65,24 @@ # include #endif -#include - #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) #ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* See include/nuttx/sched.h: */ + +#undef HAVE_GROUPID + +#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) +# define HAVE_GROUPID 1 +#endif + +#ifdef CONFIG_DISABLE_PTHREAD +# undef HAVE_GROUPID +#endif + /* Determines the size of an intermediate buffer that must be large enough * to handle the longest line generated by this logic. */ @@ -125,9 +136,9 @@ struct proc_file_s struct proc_dir_s { - struct procfs_dir_priv_s base; /* Base directory private data */ + struct procfs_dir_priv_s base; /* Base directory private data */ FAR const struct proc_node_s *node; /* Directory node description */ - pid_t pid; /* ID of task/thread for attributes */ + pid_t pid; /* ID of task/thread for attributes */ }; /**************************************************************************** @@ -186,11 +197,11 @@ static int proc_rewinddir(FAR struct fs_dirent_s *dir); static int proc_stat(FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -303,17 +314,17 @@ static const struct proc_node_s * const g_groupinfo[] = static const char *g_statenames[] = { "Invalid", - "Pending unlock", + "Waiting,Unlock", "Ready", "Running", "Inactive", - "Semaphore wait", -#ifndef CONFIG_DISABLE_MQUEUE - "Signal wait", + "Waiting,Semaphore", +#ifndef CONFIG_DISABLE_SIGNALS + "Waiting,Signal", #endif #ifndef CONFIG_DISABLE_MQUEUE - "MQ not empty wait", - "MQ no full wait" + "Waiting,MQ empty", + "Waiting,MQ full" #endif }; @@ -321,8 +332,8 @@ static const char *g_ttypenames[4] = { "Task", "pthread", - "Kernel thread", - "--?--" + "Kthread", + "Invalid" }; /**************************************************************************** @@ -354,12 +365,33 @@ static FAR const struct proc_node_s *proc_findnode(FAR const char *relpath) /**************************************************************************** * Name: proc_status + * + * Description: + * Format: + * + * 111111111122222222223 + * 123456789012345678901234567890 + * Name: xxxx... Task/thread name (See CONFIG_TASK_NAME_SIZE) + * Type: xxxxxxx {Task, pthread, Kthread, Invalid} + * PPID: xxxxx Parent thread ID + * Group: xxxxx Group ID + * CPU: xxx CPU (CONFIG_SMP only) + * State: xxxxxxxx,xxxxxxxxx {Invalid, Waiting, Ready, Running, Inactive}, + * {Unlock, Semaphore, Signal, MQ empty, MQ full} + * Flags: xxx N,P,X + * Priority: nnn Decimal, 0-255 + * Scheduler: xxxxxxxxxxxxxx {SCHED_FIFO, SCHED_RR, SCHED_SPORADIC, SCHED_OTHER} + * Sigmask: nnnnnnnn Hexadecimal, 32-bit + * ****************************************************************************/ static ssize_t proc_status(FAR struct proc_file_s *procfile, FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen, off_t offset) { +#ifdef HAVE_GROUPID + FAR struct task_group_s *group; +#endif FAR const char *policy; FAR const char *name; size_t remaining; @@ -406,6 +438,54 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, return totalsize; } +#ifdef CONFIG_SCHED_HAVE_PARENT +#ifdef HAVE_GROUPID + group = tcb->group; + DEBUGASSERT(group); + + linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n", "Group:", + group->tg_pgid); +#else + linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n", "PPID:", + tcb->ppid); +#endif + + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); + + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + + if (totalsize >= buflen) + { + return totalsize; + } +#endif + +#ifdef CONFIG_SMP + if (tcb->task_state >= FIRST_ASSIGNED_STATE && + tcb->task_state <= LAST_ASSIGNED_STATE) + { + linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n", "CPU:", + tcb->cpu); + } + else + { + linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s---\n", "CPU:"); + } + + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); + + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + + if (totalsize >= buflen) + { + return totalsize; + } +#endif + /* Show the thread state */ linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n", "State:", @@ -416,6 +496,24 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, buffer += copysize; remaining -= copysize; + if (totalsize >= buflen) + { + return totalsize; + } + + /* Show task flags */ + + linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%c%c%c\n", "Flags:", + tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : '-', + tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : '-', + tcb->flags & TCB_FLAG_EXIT_PROCESSING ? 'P' : '-'); + + copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); + + totalsize += copysize; + buffer += copysize; + remaining -= copysize; + if (totalsize >= buflen) { return totalsize; @@ -958,9 +1056,9 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath, pid = (pid_t)tmp; - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(pid); - irqrestore(flags); + leave_critical_section(flags); if (!tcb) { @@ -981,9 +1079,9 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath, /* The node must be a file, not a directory */ - if (node->dtype != DTYPE_FILE) + if (!DIRENT_ISFILE(node->dtype)) { - fdbg("ERROR: Path \"%s\" is a directory\n", relpath); + fdbg("ERROR: Path \"%s\" is not a regular file\n", relpath); return -EISDIR; } @@ -1048,13 +1146,13 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer, /* Verify that the thread is still valid */ - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(procfile->pid); if (!tcb) { fdbg("ERROR: PID %d is not valid\n", (int)procfile->pid); - irqrestore(flags); + leave_critical_section(flags); return -ENODEV; } @@ -1092,7 +1190,7 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer, break; } - irqrestore(flags); + leave_critical_section(flags); /* Update the file offset */ @@ -1197,9 +1295,9 @@ static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir) pid = (pid_t)tmp; - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(pid); - irqrestore(flags); + leave_critical_section(flags); if (!tcb) { @@ -1238,7 +1336,7 @@ static int proc_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir) /* The node must be a directory, not a file */ - if (node->dtype != DTYPE_DIRECTORY) + if (!DIRENT_ISDIRECTORY(node->dtype)) { fdbg("ERROR: Path \"%s\" is not a directory\n", relpath); kmm_free(procdir); @@ -1329,9 +1427,9 @@ static int proc_readdir(struct fs_dirent_s *dir) pid = procdir->pid; - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(pid); - irqrestore(flags); + leave_critical_section(flags); if (!tcb) { @@ -1439,9 +1537,9 @@ static int proc_stat(const char *relpath, struct stat *buf) pid = (pid_t)tmp; - flags = irqsave(); + flags = enter_critical_section(); tcb = sched_gettcb(pid); - irqrestore(flags); + leave_critical_section(flags); if (!tcb) { @@ -1455,7 +1553,7 @@ static int proc_stat(const char *relpath, struct stat *buf) { /* Yes ... It's a read-only directory */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } /* Verify that the process ID is followed by valid path segment delimiter */ @@ -1492,11 +1590,11 @@ static int proc_stat(const char *relpath, struct stat *buf) if (node->dtype == DTYPE_FILE) { - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; } else { - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } } diff --git a/fs/procfs/fs_procfsuptime.c b/fs/procfs/fs_procfsuptime.c index 0135e07178b94d7723a90afc069129a5386e7d18..3e725c1473f797f90702a1557d9832c3e170a532 100644 --- a/fs/procfs/fs_procfsuptime.c +++ b/fs/procfs/fs_procfsuptime.c @@ -102,11 +102,11 @@ static int uptime_dup(FAR const struct file *oldp, static int uptime_stat(FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -212,23 +212,16 @@ static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer, size_t linesize; off_t offset; ssize_t ret; - -#ifdef CONFIG_SYSTEM_TIME64 - uint64_t ticktime; -#if !defined(CONFIG_HAVE_DOUBLE) || !defined(CONFIG_LIBC_FLOATINGPOINT) - uint64_t sec; -#endif - -#else - uint32_t ticktime; -#if !defined(CONFIG_HAVE_DOUBLE) || !defined(CONFIG_LIBC_FLOATINGPOINT) - uint32_t sec; -#endif -#endif + systime_t ticktime; #if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT) double now; #else +# if defined(CONFIG_SYSTEM_TIME64) + uint64_t sec; +# else + uint32_t sec; +# endif unsigned int remainder; unsigned int csec; #endif @@ -249,15 +242,9 @@ static ssize_t uptime_read(FAR struct file *filep, FAR char *buffer, if (filep->f_pos == 0) { -#ifdef CONFIG_SYSTEM_TIME64 - /* 64-bit timer */ - - ticktime = clock_systimer64(); -#else - /* 32-bit timer */ + /* System time */ ticktime = clock_systimer(); -#endif #if defined(CONFIG_HAVE_DOUBLE) && defined(CONFIG_LIBC_FLOATINGPOINT) /* Convert the system up time to a seconds + hundredths of seconds string */ @@ -351,7 +338,7 @@ static int uptime_dup(FAR const struct file *oldp, FAR struct file *newp) * ****************************************************************************/ -static int uptime_stat(const char *relpath, struct stat *buf) +static int uptime_stat(FAR const char *relpath, FAR struct stat *buf) { /* "uptime" is the only acceptable value for the relpath */ @@ -363,7 +350,7 @@ static int uptime_stat(const char *relpath, struct stat *buf) /* "uptime" is the name for a read-only file */ - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; buf->st_size = 0; buf->st_blksize = 0; buf->st_blocks = 0; diff --git a/fs/procfs/fs_skeleton.c b/fs/procfs/fs_skeleton.c index 6034bd8404ac4b3393006434ea5e1d3df6eede30..052eb1f0f75fd54b26edc313b04eace7476b983a 100644 --- a/fs/procfs/fs_skeleton.c +++ b/fs/procfs/fs_skeleton.c @@ -110,7 +110,8 @@ static ssize_t skel_read(FAR struct file *filep, FAR char *buffer, static int skel_dup(FAR const struct file *oldp, FAR struct file *newp); -static int skel_opendir(const char *relpath, FAR struct fs_dirent_s *dir); +static int skel_opendir(FAR const char *relpath, + FAR struct fs_dirent_s *dir); static int skel_closedir(FAR struct fs_dirent_s *dir); static int skel_readdir(FAR struct fs_dirent_s *dir); static int skel_rewinddir(FAR struct fs_dirent_s *dir); @@ -118,11 +119,11 @@ static int skel_rewinddir(FAR struct fs_dirent_s *dir); static int skel_stat(FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See include/nutts/fs/procfs.h @@ -158,7 +159,7 @@ const struct procfs_operations skel_procfsoperations = ****************************************************************************/ static int skel_open(FAR struct file *filep, FAR const char *relpath, - int oflags, mode_t mode) + int oflags, mode_t mode) { FAR struct skel_file_s *priv; @@ -177,7 +178,7 @@ static int skel_open(FAR struct file *filep, FAR const char *relpath, return -EACCES; } - /* Allocate a container to hold the task and attribute selection */ + /* Allocate the open file structure */ priv = (FAR struct skel_file_s *)kmm_zalloc(sizeof(struct skel_file_s)); if (!priv) @@ -189,7 +190,9 @@ static int skel_open(FAR struct file *filep, FAR const char *relpath, /* TODO: Initialize the context specific data here */ - /* Save the index as the open-specific state in filep->f_priv */ + /* Save the open file structure as the open-specific state in + * filep->f_priv. + */ filep->f_priv = (FAR void *)priv; return OK; @@ -220,7 +223,7 @@ static int skel_close(FAR struct file *filep) ****************************************************************************/ static ssize_t skel_read(FAR struct file *filep, FAR char *buffer, - size_t buflen) + size_t buflen) { FAR struct skel_file_s *priv; ssize_t ret; @@ -356,11 +359,12 @@ static int skel_closedir(FAR struct fs_dirent_s *dir) * ****************************************************************************/ -static int skel_readdir(struct fs_dirent_s *dir) +static int skel_readdir(FAR struct fs_dirent_s *dir) { FAR struct skel_level1_s *level1; char filename[16]; - int ret, index; + int index; + int ret; DEBUGASSERT(dir && dir->u.procfs); level1 = dir->u.procfs; @@ -396,12 +400,13 @@ static int skel_readdir(struct fs_dirent_s *dir) /* TODO: Specify the type of entry */ dir->fd_dir.d_type = DTYPE_FILE; - strncpy(dir->fd_dir.d_name, filename, NAME_MAX+1); + strncpy(dir->fd_dir.d_name, filename, NAME_MAX + 1); /* Set up the next directory entry offset. NOTE that we could use the * standard f_pos instead of our own private index. */ + level1->base.index = index + 1; ret = OK; } @@ -415,7 +420,7 @@ static int skel_readdir(struct fs_dirent_s *dir) * ****************************************************************************/ -static int skel_rewinddir(struct fs_dirent_s *dir) +static int skel_rewinddir(FAR struct fs_dirent_s *dir) { FAR struct skel_level1_s *priv; @@ -433,7 +438,7 @@ static int skel_rewinddir(struct fs_dirent_s *dir) * ****************************************************************************/ -static int skel_stat(const char *relpath, struct stat *buf) +static int skel_stat(FAR const char *relpath, FAR truct stat *buf) { int ret = -ENOENT; @@ -441,7 +446,7 @@ static int skel_stat(const char *relpath, struct stat *buf) * or a directory and set it's permissions. */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; ret = OK; /* File/directory size, access block size */ diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index 3a65adfc2b7e85339877e10783e67172a37f1b18..84c786671c1426cf9e2f545057774530c7d5c188 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -101,11 +101,11 @@ static int romfs_stat(FAR struct inode *mountpt, FAR const char *relpath, FAR struct stat *buf); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -167,7 +167,7 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath, * structure */ - rm = (FAR struct romfs_mountpt_s*)filep->f_inode->i_private; + rm = (FAR struct romfs_mountpt_s *)filep->f_inode->i_private; DEBUGASSERT(rm != NULL); @@ -344,7 +344,7 @@ static ssize_t romfs_read(FAR struct file *filep, FAR char *buffer, uint32_t offset; size_t bytesleft; off_t sector; - FAR uint8_t *userbuffer = (FAR uint8_t*)buffer; + FAR uint8_t *userbuffer = (FAR uint8_t *)buffer; int sectorndx; int ret; @@ -586,7 +586,7 @@ static int romfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * the file. */ - *ppv = (void*)(rm->rm_xipbase + rf->rf_startoffset); + *ppv = (FAR void *)(rm->rm_xipbase + rf->rf_startoffset); return OK; } @@ -617,7 +617,7 @@ static int romfs_dup(FAR const struct file *oldp, FAR struct file *newp) * structure */ - rm = (FAR struct romfs_mountpt_s*)newp->f_inode->i_private; + rm = (FAR struct romfs_mountpt_s *)newp->f_inode->i_private; DEBUGASSERT(rm != NULL); /* Check if the mount is still healthy */ @@ -656,6 +656,7 @@ static int romfs_dup(FAR const struct file *oldp, FAR struct file *newp) ret = romfs_fileconfigure(rm, newrf); if (ret < 0) { + kmm_free(newrf); fdbg("Failed configure buffering: %d\n", ret); goto errout_with_semaphore; } @@ -788,7 +789,7 @@ static int romfs_readdir(FAR struct inode *mountpt, /* Loop, skipping over unsupported items in the file system */ - for (;;) + for (; ; ) { /* Have we reached the end of the directory */ @@ -954,7 +955,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, /* Mounted! */ - *handle = (void*)rm; + *handle = (FAR void *)rm; romfs_semgive(rm); return OK; @@ -981,7 +982,7 @@ errout_with_sem: static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, unsigned int flags) { - FAR struct romfs_mountpt_s *rm = (FAR struct romfs_mountpt_s*)handle; + FAR struct romfs_mountpt_s *rm = (FAR struct romfs_mountpt_s *)handle; int ret; fvdbg("Entry\n"); @@ -1158,20 +1159,20 @@ static int romfs_stat(FAR struct inode *mountpt, FAR const char *relpath, { /* It's a read-only directory name */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; if (IS_EXECUTABLE(dirinfo.rd_next)) { - buf->st_mode |= S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode |= S_IXOTH | S_IXGRP | S_IXUSR; } } else if (IS_FILE(dirinfo.rd_next)) { /* It's a read-only file name */ - buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; if (IS_EXECUTABLE(dirinfo.rd_next)) { - buf->st_mode |= S_IXOTH|S_IXGRP|S_IXUSR; + buf->st_mode |= S_IXOTH | S_IXGRP | S_IXUSR; } } else diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h index 88e673b10dfe0b1c0a96034745bc06c7d2461568..12ab8d88239e8f18d58a545ea45e68ce3965e71c 100644 --- a/fs/romfs/fs_romfs.h +++ b/fs/romfs/fs_romfs.h @@ -185,42 +185,43 @@ struct romfs_dirinfo_s }; /**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes + * Public Data ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif -EXTERN void romfs_semtake(struct romfs_mountpt_s *rm); -EXTERN void romfs_semgive(struct romfs_mountpt_s *rm); -EXTERN int romfs_hwread(struct romfs_mountpt_s *rm, uint8_t *buffer, - uint32_t sector, unsigned int nsectors); -EXTERN int romfs_filecacheread(struct romfs_mountpt_s *rm, - struct romfs_file_s *rf, uint32_t sector); -EXTERN int romfs_hwconfigure(struct romfs_mountpt_s *rm); -EXTERN int romfs_fsconfigure(struct romfs_mountpt_s *rm); -EXTERN int romfs_fileconfigure(struct romfs_mountpt_s *rm, - struct romfs_file_s *rf); -EXTERN int romfs_checkmount(struct romfs_mountpt_s *rm); -EXTERN int romfs_finddirentry(struct romfs_mountpt_s *rm, - struct romfs_dirinfo_s *dirinfo, - const char *path); -EXTERN int romfs_parsedirentry(struct romfs_mountpt_s *rm, - uint32_t offset, uint32_t *poffset, uint32_t *pnext, - uint32_t *pinfo, uint32_t *psize); -EXTERN int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32_t offset, - char *pname); -EXTERN int romfs_datastart(struct romfs_mountpt_s *rm, uint32_t offset, - uint32_t *start); +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void romfs_semtake(FAR struct romfs_mountpt_s *rm); +void romfs_semgive(FAR struct romfs_mountpt_s *rm); +int romfs_hwread(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, + uint32_t sector, unsigned int nsectors); +int romfs_filecacheread(FAR struct romfs_mountpt_s *rm, + FAR struct romfs_file_s *rf, uint32_t sector); +int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm); +int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm); +int romfs_fileconfigure(FAR struct romfs_mountpt_s *rm, + FAR struct romfs_file_s *rf); +int romfs_checkmount(FAR struct romfs_mountpt_s *rm); +int romfs_finddirentry(FAR struct romfs_mountpt_s *rm, + FAR struct romfs_dirinfo_s *dirinfo, + FAR const char *path); +int romfs_parsedirentry(FAR struct romfs_mountpt_s *rm, + uint32_t offset, FAR uint32_t *poffset, FAR uint32_t *pnext, + FAR uint32_t *pinfo, FAR uint32_t *psize); +int romfs_parsefilename(FAR struct romfs_mountpt_s *rm, uint32_t offset, + FAR char *pname); +int romfs_datastart(FAR struct romfs_mountpt_s *rm, uint32_t offset, + FAR uint32_t *start); #undef EXTERN #if defined(__cplusplus) diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index ce945a6694b09676a870a5ff668fbcc2b912db8f..9e19b7a447376b0e7475057eba73a1cf69d832a3 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -66,11 +66,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -108,7 +108,7 @@ static uint32_t romfs_devread32(struct romfs_mountpt_s *rm, int ndx) { /* Extract the value */ - uint32_t value = *(uint32_t*)&rm->rm_buffer[ndx]; + uint32_t value = *(FAR uint32_t *)&rm->rm_buffer[ndx]; /* Value is begin endian -- return the native host endian-ness. */ #ifdef CONFIG_ENDIAN_BIG @@ -228,7 +228,7 @@ int16_t romfs_devcacheread(struct romfs_mountpt_s *rm, uint32_t offset) } else { - /* In non-XIP mode, we will have to read the new sector.*/ + /* In non-XIP mode, we will have to read the new sector. */ ret = romfs_hwread(rm, rm->rm_buffer, sector, 1); if (ret < 0) @@ -477,7 +477,7 @@ int romfs_filecacheread(struct romfs_mountpt_s *rm, struct romfs_file_s *rf, } else { - /* In non-XIP mode, we will have to read the new sector.*/ + /* In non-XIP mode, we will have to read the new sector. */ fvdbg("Calling romfs_hwread\n"); ret = romfs_hwread(rm, rf->rf_buffer, sector, 1); @@ -560,7 +560,7 @@ int romfs_hwconfigure(struct romfs_mountpt_s *rm) /* Allocate the device cache buffer for normal sector accesses */ - rm->rm_buffer = (uint8_t*)kmm_malloc(rm->rm_hwsectorsize); + rm->rm_buffer = (FAR uint8_t *)kmm_malloc(rm->rm_hwsectorsize); if (!rm->rm_buffer) { return -ENOMEM; @@ -608,7 +608,7 @@ int romfs_fsconfigure(struct romfs_mountpt_s *rm) /* The root directory entry begins right after the header */ - name = (const char*)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; + name = (FAR const char *)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; rm->rm_rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); /* and return success */ @@ -648,7 +648,7 @@ int romfs_fileconfigure(struct romfs_mountpt_s *rm, struct romfs_file_s *rf) /* Create a file buffer to support partial sector accesses */ - rf->rf_buffer = (uint8_t*)kmm_malloc(rm->rm_hwsectorsize); + rf->rf_buffer = (FAR uint8_t *)kmm_malloc(rm->rm_hwsectorsize); if (!rf->rf_buffer) { return -ENOMEM; @@ -738,7 +738,7 @@ int romfs_finddirentry(struct romfs_mountpt_s *rm, entryname = path; terminator = NULL; - for (;;) + for (; ; ) { /* Find the start of the next path component */ @@ -876,7 +876,7 @@ int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32_t offset, */ offset += ROMFS_FHDR_NAME; - for (namelen = 0, done = false; namelen < NAME_MAX && !done;) + for (namelen = 0, done = false; namelen < NAME_MAX && !done; ) { /* Read the sector into memory */ @@ -892,7 +892,7 @@ int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32_t offset, { /* Yes.. then this chunk is less than 16 */ - chunklen = strlen((char*)&rm->rm_buffer[ndx]); + chunklen = strlen((FAR char *)&rm->rm_buffer[ndx]); done = true; } else @@ -948,7 +948,7 @@ int romfs_datastart(struct romfs_mountpt_s *rm, uint32_t offset, /* Loop until the header size is obtained. */ offset += ROMFS_FHDR_NAME; - for (;;) + for (; ; ) { /* Read the sector into memory */ diff --git a/fs/semaphore/sem_close.c b/fs/semaphore/sem_close.c index d1a7ed4f453356326b1970dd98c63ecb72d261db..3576cba2157d7a67914f2b6a42b000f29f1bf79f 100644 --- a/fs/semaphore/sem_close.c +++ b/fs/semaphore/sem_close.c @@ -60,11 +60,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -127,23 +127,23 @@ int sem_close(FAR sem_t *sem) * now. */ - if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0) - { - /* Destroy the semaphore and free the container */ + if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0) + { + /* Destroy the semaphore and free the container */ - sem_destroy(&nsem->ns_sem); - group_free(NULL, nsem); + sem_destroy(&nsem->ns_sem); + group_free(NULL, nsem); - /* Release and free the inode container. If it has been properly - * unlinked, then the peer pointer should be NULL. - */ + /* Release and free the inode container. If it has been properly + * unlinked, then the peer pointer should be NULL. + */ - inode_semgive(); + inode_semgive(); - DEBUGASSERT(inode->i_peer == NULL); - inode_free(inode); - return OK; - } + DEBUGASSERT(inode->i_peer == NULL); + inode_free(inode); + return OK; + } inode_semgive(); return OK; diff --git a/fs/semaphore/sem_open.c b/fs/semaphore/sem_open.c index 292eddc82c42cdaadf79dfdf3c0ce68032c4ca0e..6b3d6e0d3e4c20fc64a68a2d1c9d88d9a20b8b1c 100644 --- a/fs/semaphore/sem_open.c +++ b/fs/semaphore/sem_open.c @@ -66,11 +66,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -125,7 +125,7 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) FAR const char *relpath = NULL; mode_t mode; FAR struct nsem_inode_s *nsem; - FAR sem_t *sem = (FAR sem_t*)ERROR; + FAR sem_t *sem = (FAR sem_t *)ERROR; char fullpath[MAX_SEMPATH]; unsigned value; int errcode; @@ -148,8 +148,9 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name); - /* Get the inode for this semaphore. This should succeed if the semaphore - * has already been created. + /* Get the inode for this semaphore. This should succeed if the + * semaphore has already been created. In this case, inode_finde() + * will have incremented the reference count on the inode. */ inode = inode_find(fullpath, &relpath); @@ -167,7 +168,7 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) * create a new semaphore with this name. */ - if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { errcode = EEXIST; goto errout_with_inode; @@ -194,10 +195,10 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) goto errout_with_lock; } - /* Create the semaphore. First we have to extract the additional - * parameters from the variable argument list. - * REVISIT: Mode parameter is not currently used. - */ + /* Create the semaphore. First we have to extract the additional + * parameters from the variable argument list. + * REVISIT: Mode parameter is not currently used. + */ va_start(ap, oflags); mode = va_arg(ap, mode_t); @@ -214,7 +215,9 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) goto errout_with_lock; } - /* Create an inode in the pseudo-filesystem at this path */ + /* Create an inode in the pseudo-filesystem at this path. The new + * inode will be created with a reference count of zero. + */ inode_semtake(); ret = inode_reserve(fullpath, &inode); @@ -261,9 +264,9 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...) return sem; - errout_with_inode: +errout_with_inode: inode_release(inode); - errout_with_lock: +errout_with_lock: set_errno(errcode); sched_unlock(); return (FAR sem_t *)ERROR; diff --git a/fs/semaphore/sem_unlink.c b/fs/semaphore/sem_unlink.c index 393b435d4a211d5a58aa74f04e531c2635ebb06d..636c79308535815e43f90bdaf74648b7dd6adbc5 100644 --- a/fs/semaphore/sem_unlink.c +++ b/fs/semaphore/sem_unlink.c @@ -60,11 +60,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/semaphore/semaphore.h b/fs/semaphore/semaphore.h index de8985727cc27fd885af987e11f129011e06d30a..5ef28b3aac0ca7841f8b55a1f18f7831d81cb30a 100644 --- a/fs/semaphore/semaphore.h +++ b/fs/semaphore/semaphore.h @@ -53,7 +53,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef __cplusplus diff --git a/fs/smartfs/Kconfig b/fs/smartfs/Kconfig index 0ddffd23ff794aa0872b0306f866128d8acad196..6beb521d4bb6108db4da390deb49bcf7f3059a0d 100644 --- a/fs/smartfs/Kconfig +++ b/fs/smartfs/Kconfig @@ -53,7 +53,7 @@ config SMARTFS_MULTI_ROOT_DIRS Default: y. config SMARTFS_ALIGNED_ACCESS - bool "Ensure 16 and 32 bit accesses are alined" + bool "Ensure 16 and 32 bit accesses are aligned" default n ---help--- Performs little endian byte accesses to 16 and 32 values diff --git a/fs/smartfs/Make.defs b/fs/smartfs/Make.defs index 97bf50fbb910737bfba1f4e80898ecf4cc30ebbc..3be1487cde4a9f4b8665d431910822398b91557b 100644 --- a/fs/smartfs/Make.defs +++ b/fs/smartfs/Make.defs @@ -40,11 +40,6 @@ ifeq ($(CONFIG_FS_SMARTFS),y) ASRCS += CSRCS += smartfs_smart.c smartfs_utils.c smartfs_procfs.c -# Files required for mksmartfs utility function - -ASRCS += -CSRCS += smartfs_mksmartfs.c - # Include SMART build support DEPPATH += --dep-path smartfs diff --git a/fs/smartfs/smartfs.h b/fs/smartfs/smartfs.h index ac83a0c0cfb83b858d6b8b818a2ed14e000a465c..36ed65b41b872602825ac6feca15a550193af287 100644 --- a/fs/smartfs/smartfs.h +++ b/fs/smartfs/smartfs.h @@ -330,7 +330,7 @@ struct smartfs_mountpt_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/smartfs/smartfs_mksmartfs.c b/fs/smartfs/smartfs_mksmartfs.c deleted file mode 100644 index 620a6096fbb06fa57404792ad98f76a923370877..0000000000000000000000000000000000000000 --- a/fs/smartfs/smartfs_mksmartfs.c +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** - * fs/smartfs/smartfs_mksmartfs.c - * - * Copyright (C) 2013 Ken Pettit. All rights reserved. - * Author: Ken Pettit - * - * 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "smartfs.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mksmartfs - * - * Description: - * Make a SMART Flash file system image on the specified block device - * - * Inputs: - * pathname - the full path to a registered block driver - * nrootdirs - Number of root directory entries to create. - * - * Return: - * Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately: - * - * EINVAL - NULL block driver string, bad number of FATS in 'fmt', bad FAT - * size in 'fmt', bad cluster size in 'fmt' - * ENOENT - 'pathname' does not refer to anything in the filesystem. - * ENOTBLK - 'pathname' does not refer to a block driver - * EACCES - block driver does not support wrie or geometry methods - * - * Assumptions: - * - The caller must assure that the block driver is not mounted and not in - * use when this function is called. The result of formatting a mounted - * device is indeterminate (but likely not good). - * - ****************************************************************************/ - -#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS -int mksmartfs(FAR const char *pathname, uint8_t nrootdirs) -#else -int mksmartfs(FAR const char *pathname) -#endif -{ - struct inode* inode; - struct smart_format_s fmt; - int ret; - int x; - uint8_t type; - struct smart_read_write_s request; - - /* Find the inode of the block driver indentified by 'source' */ - - ret = open_blockdriver(pathname, 0, &inode); - if (ret < 0) - { - fdbg("Failed to open %s\n", pathname); - goto errout; - } - - /* Make sure that the inode supports the write and geometry methods at a minimum */ - - if (!inode->u.i_bops->write || !inode->u.i_bops->geometry) - { - fdbg("%s does not support write or geometry methods\n", pathname); - ret = -EACCES; - goto errout_with_driver; - } - - /* Validate the block device is a SMART device */ - - /* Perform a low-level SMART format */ - -#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, nrootdirs); -#else - ret = inode->u.i_bops->ioctl(inode, BIOC_LLFORMAT, 0); -#endif - if (ret != OK) - { - fdbg("Error creating low-level format: %d\n", ret); - goto errout_with_driver; - } - - /* Get the format information so we know how big the sectors are */ - - ret = inode->u.i_bops->ioctl(inode, BIOC_GETFORMAT, (unsigned long) &fmt); - - /* Now Write the filesystem to media. Loop for each root dir entry and - * allocate the reserved Root Dir Enty, then write a blank root dir for it. - */ - - type = SMARTFS_SECTOR_TYPE_DIR; - request.offset = 0; - request.count = 1; - request.buffer = &type; - x = 0; -#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - for (; x < nrootdirs; x++) -#endif - { - ret = inode->u.i_bops->ioctl(inode, BIOC_ALLOCSECT, SMARTFS_ROOT_DIR_SECTOR + x); - if (ret != SMARTFS_ROOT_DIR_SECTOR + x) - { - ret = -EIO; - goto errout_with_driver; - } - - /* Mark this block as a directory entry */ - - request.logsector = SMARTFS_ROOT_DIR_SECTOR + x; - - /* Issue a write to the sector, single byte */ - - ret = inode->u.i_bops->ioctl(inode, BIOC_WRITESECT, (unsigned long) &request); - if (ret != 0) - { - ret = -EIO; - goto errout_with_driver; - } - } - -errout_with_driver: - /* Close the driver */ - - (void)close_blockdriver(inode); - -errout: - /* Release all allocated memory */ - - /* Return any reported errors */ - - if (ret < 0) - { - set_errno(-ret); - return ERROR; - } - - return OK; -} diff --git a/fs/smartfs/smartfs_procfs.c b/fs/smartfs/smartfs_procfs.c index 6153cde80aac7074438fd479df5227cb101d2566..474d85009fa5cbf63b5a94678c1043f9ebc797c1 100644 --- a/fs/smartfs/smartfs_procfs.c +++ b/fs/smartfs/smartfs_procfs.c @@ -88,7 +88,7 @@ struct smartfs_level1_s * open / read / stat, etc. */ - struct smartfs_mountpt_s* mount; + FAR struct smartfs_mountpt_s *mount; uint8_t direntry; }; @@ -153,7 +153,7 @@ static size_t smartfs_files_read(FAR struct file *filep, FAR char *buffer, #endif /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static const struct smartfs_procfs_entry_s g_direntry[] = @@ -172,7 +172,7 @@ static const uint8_t g_direntrycount = sizeof(g_direntry) / sizeof(struct smartfs_procfs_entry_s); /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See include/nutts/fs/procfs.h @@ -216,7 +216,7 @@ static int smartfs_find_dirref(FAR const char *relpath, FAR struct smartfs_level1_s *level1) { int ret = -ENOENT; - FAR struct smartfs_mountpt_s* mount; + FAR struct smartfs_mountpt_s *mount; uint16_t x; FAR char * str; @@ -715,7 +715,7 @@ static int smartfs_stat(const char *relpath, struct stat *buf) ret = smartfs_find_dirref(relpath, &level1); - buf->st_mode = S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; if (ret == OK) { if (level1.base.level < 3) @@ -982,7 +982,6 @@ static size_t smartfs_erasemap_read(FAR struct file *filep, FAR char *buffer, copylen = 0; for (y = 0; y < rows; y++) { - //for (x = 0; x < 128; x++) for (x = 0; x < cols; x++) { /* Copy data to the buffer */ diff --git a/fs/smartfs/smartfs_smart.c b/fs/smartfs/smartfs_smart.c index 857c284e2b538a993908ac78fddb0f2e43ab15d0..122d6dca874ca153b554466910faa9f59279252b 100644 --- a/fs/smartfs/smartfs_smart.c +++ b/fs/smartfs/smartfs_smart.c @@ -110,14 +110,14 @@ static off_t smartfs_seek_internal(struct smartfs_mountpt_s *fs, off_t offset, int whence); /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static uint8_t g_seminitialized = FALSE; static sem_t g_sem; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* See fs_mount.c -- this structure is explicitly externed there. @@ -236,7 +236,7 @@ static int smartfs_open(FAR struct file *filep, const char *relpath, /* It would be an error if we are asked to create it exclusively */ - if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { /* Already exists -- can't create it exclusively */ @@ -435,7 +435,7 @@ static int smartfs_close(FAR struct file *filep) /* Now free the pointer */ - filep->f_priv = NULL;; + filep->f_priv = NULL; if (sf->entry.name != NULL) { /* Free the space for the name too */ @@ -1532,7 +1532,7 @@ static int smartfs_bind(FAR struct inode *blkdriver, const void *data, return ret; } - *handle = (void*)fs; + *handle = (FAR void *)fs; smartfs_semgive(fs); return OK; } @@ -1548,7 +1548,7 @@ static int smartfs_bind(FAR struct inode *blkdriver, const void *data, static int smartfs_unbind(FAR void *handle, FAR struct inode **blkdriver, unsigned int flags) { - struct smartfs_mountpt_s *fs = (struct smartfs_mountpt_s*)handle; + FAR struct smartfs_mountpt_s *fs = (FAR struct smartfs_mountpt_s *)handle; int ret; if (!fs) @@ -2105,7 +2105,8 @@ static int smartfs_stat(struct inode *mountpt, const char *relpath, struct stat { /* It's directory name of the mount point */ - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IWOTH|S_IWGRP|S_IWUSR; + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | + S_IWGRP | S_IWUSR; ret = OK; goto errout_with_semaphore; } diff --git a/fs/smartfs/smartfs_utils.c b/fs/smartfs/smartfs_utils.c index 23d0cff13a96ec332f27c3811906600ada7c17a9..dba35882bcc7ddc7803a6d865d168c4371236416 100644 --- a/fs/smartfs/smartfs_utils.c +++ b/fs/smartfs/smartfs_utils.c @@ -69,16 +69,16 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ #if defined(CONFIG_SMARTFS_MULTI_ROOT_DIRS) || \ (defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)) -static struct smartfs_mountpt_s* g_mounthead = NULL; +static struct smartfs_mountpt_s *g_mounthead = NULL; #endif /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -840,11 +840,11 @@ errout: * ****************************************************************************/ -int smartfs_createentry(struct smartfs_mountpt_s *fs, - uint16_t parentdirsector, const char* filename, - uint16_t type, - mode_t mode, struct smartfs_entry_s *direntry, - uint16_t sectorno, FAR struct smartfs_ofile_s *sf) +int smartfs_createentry(FAR struct smartfs_mountpt_s *fs, + uint16_t parentdirsector, FAR const char *filename, + uint16_t type, mode_t mode, + FAR struct smartfs_entry_s *direntry, + uint16_t sectorno, FAR struct smartfs_ofile_s *sf) { struct smart_read_write_s readwrite; int ret; @@ -908,9 +908,9 @@ int smartfs_createentry(struct smartfs_mountpt_s *fs, if ((entry->flags == SMARTFS_ERASEDSTATE_16BIT) || ((entry->flags & #endif - (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE) ) == + (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE)) == (~SMARTFS_ERASEDSTATE_16BIT & - (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE) ))) + (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE)))) { /* We found an empty entry. Use it. */ @@ -1034,7 +1034,8 @@ int smartfs_createentry(struct smartfs_mountpt_s *fs, ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite); if (ret < 0) { - fdbg("Error %d setting new sector type for sector %d\n",ret, nextsector); + fdbg("Error %d setting new sector type for sector %d\n", + ret, nextsector); goto errout; } } @@ -1122,7 +1123,7 @@ int smartfs_deleteentry(struct smartfs_mountpt_s *fs, struct smart_read_write_s readwrite; /* Okay, delete the file. Loop through each sector and release them - + * * TODO: We really should walk the list backward to avoid lost * sectors in the event we lose power. However this requires * allocating a buffer to build the sector list since we don't @@ -1493,7 +1494,7 @@ int smartfs_truncatefile(struct smartfs_mountpt_s *fs, } /* Now deal with the first sector in the event we are using a sector buffer - like we would be if CRC is enabled. + * like we would be if CRC is enabled. */ #ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER @@ -1531,7 +1532,7 @@ errout: ****************************************************************************/ #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS) -struct smartfs_mountpt_s* smartfs_get_first_mount(void) +FAR struct smartfs_mountpt_s *smartfs_get_first_mount(void) { return g_mounthead; } diff --git a/fs/tmpfs/Kconfig b/fs/tmpfs/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9eebf3b964c1a8bc4a35da622cdda6e4a6ca94c2 --- /dev/null +++ b/fs/tmpfs/Kconfig @@ -0,0 +1,64 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config FS_TMPFS + bool "TMPFS file system" + default n + depends on !DISABLE_MOUNTPOINT + select FS_READABLE + select FS_WRITABLE + ---help--- + Enable TMPFS filesystem support + +if FS_TMPFS + +config FS_TMPFS_BLOCKSIZE + int "Reported block size" + default 512 + ---help--- + Various queries expect the file system to report resources in units + of blocks. There are, of course, no blocks with the TMPFS. This + options is available to control how sizes are reported. For very + small TMPFS systems, you might want to set this to something smaller + the the usual 512 bytes. + +config FS_TMPFS_DIRECTORY_ALLOCGUARD + int "Directory object over-allocation" + default 64 + ---help--- + In order to avoid frequent reallocations, a little more memory than + needed is always allocated. This permits the directory to grow + without so many realloctions. + +config FS_TMPFS_DIRECTORY_FREEGUARD + int "Directory under free" + default 128 + ---help--- + In order to avoid frequent reallocations, a lot of free memory has + to be available before a directory entry shrinks (via reallocation) + little more memory than needed is always allocated. This permits + the directory to shrink without so many realloctions. + +config FS_TMPFS_FILE_ALLOCGUARD + int "Directory object over-allocation" + default 512 + ---help--- + In order to avoid frequent reallocations, a little more memory than + needed is always allocated. This permits the file to grow without + so many realloctions. + + You will probably want to use smaller value than the default on tiny + TMFPS systems. + +config FS_TMPFS_FILE_FREEGUARD + int "Directory under free" + default 1024 + ---help--- + In order to avoid frequent reallocations, a lot of free memory has + to be available before a directory entry shrinks (via reallocation) + little more memory than needed is always allocated. This permits + the file to shrink without so many realloctions. + +endif diff --git a/fs/tmpfs/Make.defs b/fs/tmpfs/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..f4f5d7b6ad8c2540f10123c75ef9d8b5e54be306 --- /dev/null +++ b/fs/tmpfs/Make.defs @@ -0,0 +1,47 @@ +############################################################################ +# fs/tmpfs/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_FS_TMPFS),y) +# Files required for TMPFS file system support + +ASRCS += +CSRCS += fs_tmpfs.c + +# Include TMPFS build support + +DEPPATH += --dep-path tmpfs +VPATH += :tmpfs + +endif diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c new file mode 100644 index 0000000000000000000000000000000000000000..529cdd5ee7151550de3092db3863d8fde217bdd5 --- /dev/null +++ b/fs/tmpfs/fs_tmpfs.c @@ -0,0 +1,2544 @@ +/**************************************************************************** + * fs/tmpfs/fs_tmpfs.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "fs_tmpfs.h" + +#ifndef CONFIG_DISABLE_MOUNTPOINT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if CONFIG_FS_TMPFS_DIRECTORY_FREEGUARD <= CONFIG_FS_TMPFS_DIRECTORY_ALLOCGUARD +# warning CONFIG_FS_TMPFS_DIRECTORY_FREEGUARD needs to be > ALLOCGUARD +#endif + +#if CONFIG_FS_TMPFS_FILE_FREEGUARD <= CONFIG_FS_TMPFS_FILE_ALLOCGUARD +# warning CONFIG_FS_TMPFS_FILE_FREEGUARD needs to be > ALLOCGUARD +#endif + +#define tmpfs_lock_file(tfo) \ + (tmpfs_lock_object((FAR struct tmpfs_object_s *)tfo)) +#define tmpfs_lock_directory(tdo) \ + (tmpfs_lock_object((FAR struct tmpfs_object_s *)tdo)) +#define tmpfs_unlock_file(tfo) \ + (tmpfs_unlock_object((FAR struct tmpfs_object_s *)tfo)) +#define tmpfs_unlock_directory(tdo) \ + (tmpfs_unlock_object((FAR struct tmpfs_object_s *)tdo)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* TMPFS helpers */ + +static void tmpfs_lock_reentrant(FAR struct tmpfs_sem_s *sem); +static void tmpfs_lock(FAR struct tmpfs_s *fs); +static void tmpfs_unlock_reentrant(FAR struct tmpfs_sem_s *sem); +static void tmpfs_unlock(FAR struct tmpfs_s *fs); +static void tmpfs_lock_object(FAR struct tmpfs_object_s *to); +static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to); +static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo, + unsigned int nentries); +static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo, + size_t newsize); +static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to); +static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo); +static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo, + FAR const char *name); +static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo, + FAR const char *name); +static int tmpfs_add_dirent(FAR struct tmpfs_directory_s **tdo, + FAR struct tmpfs_object_s *to, FAR const char *name); +static FAR struct tmpfs_file_s *tmpfs_alloc_file(void); +static int tmpfs_create_file(FAR struct tmpfs_s *fs, + FAR const char *relpath, FAR struct tmpfs_file_s **tfo); +static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void); +static int tmpfs_create_directory(FAR struct tmpfs_s *fs, + FAR const char *relpath, FAR struct tmpfs_directory_s **tdo); +static int tmpfs_find_object(FAR struct tmpfs_s *fs, + FAR const char *relpath, FAR struct tmpfs_object_s **object, + FAR struct tmpfs_directory_s **parent); +static int tmpfs_find_file(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_file_s **tfo, + FAR struct tmpfs_directory_s **parent); +static int tmpfs_find_directory(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_directory_s **tdo, + FAR struct tmpfs_directory_s **parent); +static int tmpfs_statfs_callout(FAR struct tmpfs_directory_s *tdo, + unsigned int index, FAR void *arg); +static int tmpfs_free_callout(FAR struct tmpfs_directory_s *tdo, + unsigned int index, FAR void *arg); +static int tmpfs_foreach(FAR struct tmpfs_directory_s *tdo, + tmpfs_foreach_t callout, FAR void *arg); + +/* File system operations */ + +static int tmpfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int tmpfs_close(FAR struct file *filep); +static ssize_t tmpfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t tmpfs_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static off_t tmpfs_seek(FAR struct file *filep, off_t offset, int whence); +static int tmpfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int tmpfs_dup(FAR const struct file *oldp, FAR struct file *newp); +static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, + FAR struct fs_dirent_s *dir); +static int tmpfs_closedir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int tmpfs_readdir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int tmpfs_rewinddir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir); +static int tmpfs_bind(FAR struct inode *blkdriver, FAR const void *data, + FAR void **handle); +static int tmpfs_unbind(FAR void *handle, FAR struct inode **blkdriver, + unsigned int flags); +static int tmpfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf); +static int tmpfs_unlink(FAR struct inode *mountpt, FAR const char *relpath); +static int tmpfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath, + mode_t mode); +static int tmpfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath); +static int tmpfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath, + FAR const char *newrelpath); +static int tmpfs_stat(FAR struct inode *mountpt, FAR const char *relpath, + FAR struct stat *buf); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct mountpt_operations tmpfs_operations = +{ + tmpfs_open, /* open */ + tmpfs_close, /* close */ + tmpfs_read, /* read */ + tmpfs_write, /* write */ + tmpfs_seek, /* seek */ + tmpfs_ioctl, /* ioctl */ + NULL, /* sync */ + tmpfs_dup, /* dup */ + tmpfs_opendir, /* opendir */ + tmpfs_closedir, /* closedir */ + tmpfs_readdir, /* readdir */ + tmpfs_rewinddir, /* rewinddir */ + tmpfs_bind, /* bind */ + tmpfs_unbind, /* unbind */ + tmpfs_statfs, /* statfs */ + tmpfs_unlink, /* unlink */ + tmpfs_mkdir, /* mkdir */ + tmpfs_rmdir, /* rmdir */ + tmpfs_rename, /* rename */ + tmpfs_stat, /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tmpfs_lock_reentrant + ****************************************************************************/ + +static void tmpfs_lock_reentrant(FAR struct tmpfs_sem_s *sem) +{ + pid_t me; + + /* Do we already hold the semaphore? */ + + me = getpid(); + if (me == sem->ts_holder) + { + /* Yes... just increment the count */ + + sem->ts_count++; + DEBUGASSERT(sem->ts_count > 0); + } + + /* Take the semaphore (perhaps waiting) */ + + else + { + while (sem_wait(&sem->ts_sem) != 0) + { + /* The only case that an error should occr here is if + * the wait was awakened by a signal. + */ + + DEBUGASSERT(get_errno() == EINTR); + } + + /* No we hold the semaphore */ + + sem->ts_holder = me; + sem->ts_count = 1; + } +} + +/**************************************************************************** + * Name: tmpfs_lock + ****************************************************************************/ + +static void tmpfs_lock(FAR struct tmpfs_s *fs) +{ + tmpfs_lock_reentrant(&fs->tfs_exclsem); +} + +/**************************************************************************** + * Name: tmpfs_lock_object + ****************************************************************************/ + +static void tmpfs_lock_object(FAR struct tmpfs_object_s *to) +{ + tmpfs_lock_reentrant(&to->to_exclsem); +} + +/**************************************************************************** + * Name: tmpfs_unlock_reentrant + ****************************************************************************/ + +static void tmpfs_unlock_reentrant(FAR struct tmpfs_sem_s *sem) +{ + DEBUGASSERT(sem->ts_holder == getpid()); + + /* Is this our last count on the semaphore? */ + + if (sem->ts_count > 1) + { + /* No.. just decrement the count */ + + sem->ts_count--; + } + + /* Yes.. then we can really release the semaphore */ + + else + { + sem->ts_holder = TMPFS_NO_HOLDER; + sem->ts_count = 0; + sem_post(&sem->ts_sem); + } +} + +/**************************************************************************** + * Name: tmpfs_unlock + ****************************************************************************/ + +static void tmpfs_unlock(FAR struct tmpfs_s *fs) +{ + tmpfs_unlock_reentrant(&fs->tfs_exclsem); +} + +/**************************************************************************** + * Name: tmpfs_unlock_object + ****************************************************************************/ + +static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to) +{ + tmpfs_unlock_reentrant(&to->to_exclsem); +} + +/**************************************************************************** + * Name: tmpfs_realloc_directory + ****************************************************************************/ + +static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo, + unsigned int nentries) +{ + FAR struct tmpfs_directory_s *oldtdo = *tdo; + FAR struct tmpfs_directory_s *newtdo; + size_t objsize; + int ret = oldtdo->tdo_nentries; + + /* Get the new object size */ + + objsize = SIZEOF_TMPFS_DIRECTORY(nentries); + if (objsize <= oldtdo->tdo_alloc) + { + /* Already big enough. + * REVISIT: Missing logic to shrink directory objects. + */ + + oldtdo->tdo_nentries = nentries; + return ret; + } + + /* Added some additional amount to the new size to account frequent + * reallocations. + */ + + objsize += CONFIG_FS_TMPFS_DIRECTORY_ALLOCGUARD; + + /* Realloc the directory object */ + + newtdo = (FAR struct tmpfs_directory_s *)kmm_realloc(oldtdo, objsize); + if (newtdo == NULL) + { + return -ENOMEM; + } + + /* Adjust the reference in the parent directory entry */ + + DEBUGASSERT(newtdo->tdo_dirent); + newtdo->tdo_dirent->tde_object = (FAR struct tmpfs_object_s *)newtdo; + + /* Return the new address of the reallocated directory object */ + + newtdo->tdo_alloc = objsize; + newtdo->tdo_nentries = nentries; + *tdo = newtdo; + + /* Adjust the reference in the parent directory entry */ + + DEBUGASSERT(newtdo->tdo_dirent); + newtdo->tdo_dirent->tde_object = (FAR struct tmpfs_object_s *)newtdo; + + /* Return the index to the first, newly allocated directory entry */ + + return ret; +} + +/**************************************************************************** + * Name: tmpfs_realloc_file + ****************************************************************************/ + +static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo, + size_t newsize) +{ + FAR struct tmpfs_file_s *oldtfo = *tfo; + FAR struct tmpfs_file_s *newtfo; + size_t objsize; + size_t allocsize; + size_t delta; + + /* Check if the current allocation is sufficent */ + + objsize = SIZEOF_TMPFS_FILE(newsize); + + /* Are we growing or shrinking the object? */ + + if (objsize <= oldtfo->tfo_alloc) + { + /* Shrinking ... Shrink unconditionally if the size is shrinking to + * zero. + */ + + if (newsize > 0) + { + /* Otherwise, don't realloc unless the object has shrunk by a + * lot. + */ + + delta = oldtfo->tfo_alloc - objsize; + if (delta <= CONFIG_FS_TMPFS_FILE_FREEGUARD) + { + /* Hasn't shrunk enough.. Return doing nothing for now */ + + oldtfo->tfo_size = newsize; + return OK; + } + } + } + + /* Added some additional amount to the new size to account frequent + * reallocations. + */ + + allocsize = objsize + CONFIG_FS_TMPFS_FILE_ALLOCGUARD; + + /* Realloc the file object */ + + newtfo = (FAR struct tmpfs_file_s *)kmm_realloc(oldtfo, allocsize); + if (newtfo == NULL) + { + return -ENOMEM; + } + + /* Adjust the reference in the parent directory entry */ + + DEBUGASSERT(newtfo->tfo_dirent); + newtfo->tfo_dirent->tde_object = (FAR struct tmpfs_object_s *)newtfo; + + /* Return the new address of the reallocated file object */ + + newtfo->tfo_alloc = allocsize; + newtfo->tfo_size = newsize; + *tfo = newtfo; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_release_lockedobject + ****************************************************************************/ + +static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to) +{ + DEBUGASSERT(to && to->to_refs > 0); + + /* Is this a file object? */ + + if (to->to_type == TMPFS_REGULAR) + { + tmpfs_release_lockedfile((FAR struct tmpfs_file_s *)to); + } + else + { + to->to_refs--; + tmpfs_unlock_object(to); + } +} + +/**************************************************************************** + * Name: tmpfs_release_lockedfile + ****************************************************************************/ + +static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo) +{ + DEBUGASSERT(tfo && tfo->tfo_refs > 0); + + /* If there are no longer any references to the file and the file has been + * unlinked from its parent directory, then free the file object now. + */ + + if (tfo->tfo_refs == 1 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0) + { + sem_destroy(&tfo->tfo_exclsem.ts_sem); + kmm_free(tfo); + } + + /* Otherwise, just decrement the reference count on the file object */ + + else + { + tfo->tfo_refs--; + tmpfs_unlock_file(tfo); + } +} + +/**************************************************************************** + * Name: tmpfs_find_dirent + ****************************************************************************/ + +static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo, + FAR const char *name) +{ + int i; + + /* Search the list of directory entries for a match */ + + for (i = 0; + i < tdo->tdo_nentries && + strcmp(tdo->tdo_entry[i].tde_name, name) != 0; + i++); + + /* Return what we found, if anything */ + + return i < tdo->tdo_nentries ? i : -ENOENT; +} + +/**************************************************************************** + * Name: tmpfs_remove_dirent + ****************************************************************************/ + +static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo, + FAR const char *name) +{ + int index; + int last; + + /* Search the list of directory entries for a match */ + + index = tmpfs_find_dirent(tdo, name); + if (index < 0) + { + return index; + } + + /* Free the object name */ + + if (tdo->tdo_entry[index].tde_name != NULL) + { + kmm_free(tdo->tdo_entry[index].tde_name); + } + + /* Remove by replacing this entry with the final directory entry */ + + last = tdo->tdo_nentries - 1; + if (index != last) + { + FAR struct tmpfs_dirent_s *newtde; + FAR struct tmpfs_dirent_s *oldtde; + FAR struct tmpfs_object_s *to; + + /* Move the directory entry */ + + newtde = &tdo->tdo_entry[index]; + oldtde = &tdo->tdo_entry[last]; + to = oldtde->tde_object; + + newtde->tde_object = to; + newtde->tde_name = oldtde->tde_name; + + /* Reset the backward link to the directory entry */ + + to->to_dirent = newtde; + } + + /* And decrement the count of directory entries */ + + tdo->tdo_nentries = last; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_add_dirent + ****************************************************************************/ + +static int tmpfs_add_dirent(FAR struct tmpfs_directory_s **tdo, + FAR struct tmpfs_object_s *to, + FAR const char *name) +{ + FAR struct tmpfs_directory_s *oldtdo; + FAR struct tmpfs_directory_s *newtdo; + FAR struct tmpfs_dirent_s *tde; + FAR char *newname; + unsigned int nentries; + int index; + + /* Copy the name string so that it will persist as long as the + * directory entry. + */ + + newname = strdup(name); + if (newname == NULL) + { + return -ENOMEM; + } + + /* Get the new number of entries */ + + oldtdo = *tdo; + nentries = oldtdo->tdo_nentries + 1; + + /* Reallocate the directory object (if necessary) */ + + index = tmpfs_realloc_directory(tdo, nentries); + if (index < 0) + { + kmm_free(newname); + return index; + } + + /* Save the new object info in the new directory entry */ + + newtdo = *tdo; + tde = &newtdo->tdo_entry[index]; + tde->tde_object = to; + tde->tde_name = newname; + + /* Add backward link to the directory entry to the object */ + + to->to_dirent = tde; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_alloc_file + ****************************************************************************/ + +static FAR struct tmpfs_file_s *tmpfs_alloc_file(void) +{ + FAR struct tmpfs_file_s *tfo; + size_t allocsize; + + /* Create a new zero length file object */ + + allocsize = SIZEOF_TMPFS_FILE(CONFIG_FS_TMPFS_FILE_ALLOCGUARD); + tfo = (FAR struct tmpfs_file_s *)kmm_malloc(allocsize); + if (tfo == NULL) + { + return NULL; + } + + /* Initialize the new file object. NOTE that the initial state is + * locked with one reference count. + */ + + tfo->tfo_alloc = allocsize; + tfo->tfo_type = TMPFS_REGULAR; + tfo->tfo_refs = 1; + tfo->tfo_flags = 0; + tfo->tfo_size = 0; + + tfo->tfo_exclsem.ts_holder = getpid(); + tfo->tfo_exclsem.ts_count = 1; + sem_init(&tfo->tfo_exclsem.ts_sem, 0, 0); + + return tfo; +} + +/**************************************************************************** + * Name: tmpfs_create_file + ****************************************************************************/ + +static int tmpfs_create_file(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_file_s **tfo) +{ + FAR struct tmpfs_directory_s *parent; + FAR struct tmpfs_file_s *newtfo; + FAR char *copy; + FAR char *name; + int ret; + + /* Duplicate the path variable so that we can modify it */ + + copy = strdup(relpath); + if (copy == NULL) + { + return -ENOMEM; + } + + /* Separate the path into the file name and the path to the parent + * directory. + */ + + name = strrchr(copy, '/'); + if (name == NULL) + { + /* No subdirectories... use the root directory */ + + name = copy; + parent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + + /* Lock the root directory to emulate the behavior of tmpfs_find_directory() */ + + tmpfs_lock_directory(parent); + parent->tdo_refs++; + } + else + { + /* Terminate the parent directory path */ + + *name++ = '\0'; + + /* Locate the parent directory that should contain this name. + * On success, tmpfs_find_directory() will lock the parent + * directory and increment the reference count. + */ + + ret = tmpfs_find_directory(fs, copy, &parent, NULL); + if (ret < 0) + { + goto errout_with_copy; + } + } + + /* Verify that no object of this name already exists in the directory */ + + ret = tmpfs_find_dirent(parent, name); + if (ret != -ENOENT) + { + /* Something with this name already exists in the directory. + * OR perhaps some fatal error occurred. + */ + + if (ret >= 0) + { + ret = -EEXIST; + } + + goto errout_with_parent; + } + + /* Allocate an empty file. The initial state of the file is locked with one + * reference count. + */ + + newtfo = tmpfs_alloc_file(); + if (newtfo == NULL) + { + ret = -ENOMEM; + goto errout_with_parent; + } + + /* Then add the new, empty file to the directory */ + + ret = tmpfs_add_dirent(&parent, (FAR struct tmpfs_object_s *)newtfo, name); + if (ret < 0) + { + goto errout_with_file; + } + + /* Release the reference and lock on the parent directory */ + + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + + /* Free the copy of the relpath and return success */ + + kmm_free(copy); + *tfo = newtfo; + return OK; + +/* Error exits */ + +errout_with_file: + sem_destroy(&newtfo->tfo_exclsem.ts_sem); + kmm_free(newtfo); + +errout_with_parent: + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + +errout_with_copy: + kmm_free(copy); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_alloc_directory + ****************************************************************************/ + +static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void) +{ + FAR struct tmpfs_directory_s *tdo; + size_t allocsize; + unsigned int nentries; + + /* Convert the pre-allocated memory to a number of directory entries */ + + nentries = (CONFIG_FS_TMPFS_DIRECTORY_ALLOCGUARD + + sizeof(struct tmpfs_dirent_s) - 1) / + sizeof(struct tmpfs_dirent_s); + + /* Create a new zero length directory object */ + + allocsize = SIZEOF_TMPFS_DIRECTORY(nentries); + tdo = (FAR struct tmpfs_directory_s *)kmm_malloc(allocsize); + if (tdo == NULL) + { + return NULL; + } + + /* Initialize the new directory object */ + + tdo->tdo_alloc = allocsize; + tdo->tdo_type = TMPFS_DIRECTORY; + tdo->tdo_refs = 0; + tdo->tdo_nentries = 0; + + tdo->tdo_exclsem.ts_holder = TMPFS_NO_HOLDER; + tdo->tdo_exclsem.ts_count = 0; + sem_init(&tdo->tdo_exclsem.ts_sem, 0, 1); + + return tdo; +} + +/**************************************************************************** + * Name: tmpfs_create_directory + ****************************************************************************/ + +static int tmpfs_create_directory(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_directory_s **tdo) +{ + FAR struct tmpfs_directory_s *parent; + FAR struct tmpfs_directory_s *newtdo; + FAR char *copy; + FAR char *name; + int ret; + + /* Duplicate the path variable so that we can modify it */ + + copy = strdup(relpath); + if (copy == NULL) + { + return -ENOMEM; + } + + /* Separate the path into the file name and the path to the parent + * directory. + */ + + name = strrchr(copy, '/'); + if (name == NULL) + { + /* No subdirectories... use the root directory */ + + name = copy; + parent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + + tmpfs_lock_directory(parent); + parent->tdo_refs++; + } + else + { + /* Terminate the parent directory path */ + + *name++ = '\0'; + + /* Locate the parent directory that should contain this name. + * On success, tmpfs_find_directory() will lockthe parent + * directory and increment the reference count. + */ + + ret = tmpfs_find_directory(fs, copy, &parent, NULL); + if (ret < 0) + { + goto errout_with_copy; + } + } + + /* Verify that no object of this name already exists in the directory */ + + ret = tmpfs_find_dirent(parent, name); + if (ret != -ENOENT) + { + /* Something with this name already exists in the directory. + * OR perhaps some fatal error occurred. + */ + + if (ret >= 0) + { + ret = -EEXIST; + } + + goto errout_with_parent; + } + + /* Allocate an empty directory object. NOTE that there is no reference on + * the new directory and the object is not locked. + */ + + newtdo = tmpfs_alloc_directory(); + if (newtdo == NULL) + { + ret = -ENOMEM; + goto errout_with_parent; + } + + /* Then add the new, empty file to the directory */ + + ret = tmpfs_add_dirent(&parent, (FAR struct tmpfs_object_s *)newtdo, name); + if (ret < 0) + { + goto errout_with_directory; + } + + /* Free the copy of the relpath, release our reference to the parent directory, + * and return success + */ + + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + kmm_free(copy); + + /* Return the (unlocked, unreferenced) directory object to the caller */ + + if (tdo != NULL) + { + *tdo = newtdo; + } + + return OK; + +/* Error exits */ + +errout_with_directory: + sem_destroy(&newtdo->tdo_exclsem.ts_sem); + kmm_free(newtdo); + +errout_with_parent: + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + +errout_with_copy: + kmm_free(copy); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_find_object + ****************************************************************************/ + +static int tmpfs_find_object(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_object_s **object, + FAR struct tmpfs_directory_s **parent) +{ + FAR struct tmpfs_object_s *to; + FAR struct tmpfs_directory_s *tdo; + FAR struct tmpfs_directory_s *next_tdo; + FAR char *segment; + FAR char *next_segment; + FAR char *tkptr; + FAR char *copy; + int index; + + /* Make a copy of the path (so that we can modify it via strtok) */ + + copy = strdup(relpath); + if (copy == NULL) + { + return -ENOMEM; + } + + /* Traverse the file system for any object with the matching name */ + + to = fs->tfs_root.tde_object; + next_tdo = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + + for (segment = strtok_r(copy, "/", &tkptr); + segment != NULL; + segment = next_segment) + { + /* Get the next segment after the one we are currently working on. + * This will be NULL is we are working on the final segment of the + * relpath. + */ + + next_segment = strtok_r(NULL, "/", &tkptr); + + /* Search the the next directory. */ + + tdo = next_tdo; + + /* Find the TMPFS object with the next segment name in the current + * directory. + */ + + index = tmpfs_find_dirent(tdo, segment); + if (index < 0) + { + /* No object with this name exists in the directory. */ + + kmm_free(copy); + return index; + } + + to = tdo->tdo_entry[index].tde_object; + + /* Is this object another directory? */ + + if (to->to_type != TMPFS_DIRECTORY) + { + /* No. Was this the final segment in the path? */ + + if (next_segment == NULL) + { + /* Then we can break out of the loop now */ + + break; + } + + /* No, this was not the final segement of the relpath. + * We cannot continue the search if any of the intermediate + * segments do no correspond to directories. + */ + + kmm_free(copy); + return -ENOTDIR; + } + + /* Search this directory for the next segement. If we + * exit the loop, tdo will still refer to the parent + * directory of to. + */ + + next_tdo = (FAR struct tmpfs_directory_s *)to; + } + + /* When we exit this loop (successfully), to will point to the TMPFS + * object associated with the terminal segment of the relpath. + * Increment the reference count on the located object. + */ + + /* Free the dup'ed string */ + + kmm_free(copy); + + /* Return what we found */ + + if (parent) + { + /* Get exclusive access to the parent and increment the reference + * count on the object. + */ + + tmpfs_lock_directory(tdo); + tdo->tdo_refs++; + + *parent = tdo; + } + + if (object) + { + /* Get exclusive access to the object and increment the reference + * count on the object. + */ + + tmpfs_lock_object(to); + to->to_refs++; + + *object = to; + } + + return OK; +} + +/**************************************************************************** + * Name: tmpfs_find_file + ****************************************************************************/ + +static int tmpfs_find_file(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_file_s **tfo, + FAR struct tmpfs_directory_s **parent) +{ + FAR struct tmpfs_object_s *to; + int ret; + + /* Find the object at this path. If successful, tmpfs_find_object() will + * lock both the object and the parent directory and will increment the + * reference count on both. + */ + + ret = tmpfs_find_object(fs, relpath, &to, parent); + if (ret >= 0) + { + /* We found it... but is it a regular file? */ + + if (to->to_type != TMPFS_REGULAR) + { + /* No... unlock the object and its parent and return an error */ + + tmpfs_release_lockedobject(to); + + if (parent) + { + FAR struct tmpfs_directory_s *tdo = *parent; + + tdo->tdo_refs--; + tmpfs_unlock_directory(tdo); + } + + ret = -EISDIR; + } + + /* Return the verified file object */ + + *tfo = (FAR struct tmpfs_file_s *)to; + } + + return ret; +} + +/**************************************************************************** + * Name: tmpfs_find_directory + ****************************************************************************/ + +static int tmpfs_find_directory(FAR struct tmpfs_s *fs, + FAR const char *relpath, + FAR struct tmpfs_directory_s **tdo, + FAR struct tmpfs_directory_s **parent) +{ + FAR struct tmpfs_object_s *to; + int ret; + + /* Find the object at this path */ + + ret = tmpfs_find_object(fs, relpath, &to, parent); + if (ret >= 0) + { + /* We found it... but is it a regular file? */ + + if (to->to_type != TMPFS_DIRECTORY) + { + /* No... unlock the object and its parent and return an error */ + + tmpfs_release_lockedobject(to); + + if (parent) + { + FAR struct tmpfs_directory_s *tmptdo = *parent; + + tmptdo->tdo_refs--; + tmpfs_unlock_directory(tmptdo); + } + + ret = -ENOTDIR; + } + + /* Return the verified file object */ + + *tdo = (FAR struct tmpfs_directory_s *)to; + } + + return ret; +} + +/**************************************************************************** + * Name: tmpfs_statfs_callout + ****************************************************************************/ + +static int tmpfs_statfs_callout(FAR struct tmpfs_directory_s *tdo, + unsigned int index, FAR void *arg) +{ + FAR struct tmpfs_object_s *to; + FAR struct tmpfs_statfs_s *tmpbuf; + + DEBUGASSERT(tdo != NULL && arg != NULL && index < tdo->tdo_nentries); + + to = tdo->tdo_entry[index].tde_object; + tmpbuf = (FAR struct tmpfs_statfs_s *)arg; + + DEBUGASSERT(to != NULL); + + /* Accumulate statistics. Save the total memory allocted for this object. */ + + tmpbuf->tsf_alloc += to->to_alloc; + + /* Is this directory entry a file object? */ + + if (to->to_type == TMPFS_REGULAR) + { + FAR struct tmpfs_file_s *tmptfo; + + /* It is a file object. Increment the number of files and update the + * amount of memory in use. + */ + + tmptfo = (FAR struct tmpfs_file_s *)to; + tmpbuf->tsf_inuse += tmptfo->tfo_size; + tmpbuf->tsf_files++; + } + else /* if (to->to_type == TMPFS_DIRECTORY) */ + { + FAR struct tmpfs_directory_s *tmptdo; + size_t inuse; + size_t avail; + + /* It is a directory object. Update the amount of memory in use + * for the directory and estimate the number of free directory nodes. + */ + + tmptdo = (FAR struct tmpfs_directory_s *)to; + inuse = SIZEOF_TMPFS_DIRECTORY(tmptdo->tdo_nentries); + avail = tmptdo->tdo_alloc - inuse; + + tmpbuf->tsf_inuse += inuse; + tmpbuf->tsf_ffree += avail / sizeof(struct tmpfs_dirent_s); + } + + return TMPFS_CONTINUE; +} + +/**************************************************************************** + * Name: tmpfs_free_callout + ****************************************************************************/ + +static int tmpfs_free_callout(FAR struct tmpfs_directory_s *tdo, + unsigned int index, FAR void *arg) +{ + FAR struct tmpfs_dirent_s *tde; + FAR struct tmpfs_object_s *to; + FAR struct tmpfs_file_s *tfo; + unsigned int last; + + /* Free the object name */ + + if (tdo->tdo_entry[index].tde_name != NULL) + { + kmm_free(tdo->tdo_entry[index].tde_name); + } + + /* Remove by replacing this entry with the final directory entry */ + + tde = &tdo->tdo_entry[index]; + to = tde->tde_object; + last = tdo->tdo_nentries - 1; + + if (index != last) + { + FAR struct tmpfs_dirent_s *oldtde; + FAR struct tmpfs_object_s *oldto; + + /* Move the directory entry */ + + oldtde = &tdo->tdo_entry[last]; + oldto = oldtde->tde_object; + + tde->tde_object = oldto; + tde->tde_name = oldtde->tde_name; + + /* Reset the backward link to the directory entry */ + + oldto->to_dirent = tde; + } + + /* And decrement the count of directory entries */ + + tdo->tdo_nentries = last; + + /* Is this directory entry a file object? */ + + if (to->to_type == TMPFS_REGULAR) + { + tfo = (FAR struct tmpfs_file_s *)to; + + /* Are there references to the file? */ + + if (tfo->tfo_refs > 0) + { + /* Yes.. We cannot delete the file now. Just mark it as unlinked. */ + + tfo->tfo_flags |= TFO_FLAG_UNLINKED; + return TMPFS_UNLINKED; + } + } + + /* Free the object now */ + + sem_destroy(&to->to_exclsem.ts_sem); + kmm_free(to); + return TMPFS_DELETED; +} + +/**************************************************************************** + * Name: tmpfs_foreach + ****************************************************************************/ + +static int tmpfs_foreach(FAR struct tmpfs_directory_s *tdo, + tmpfs_foreach_t callout, FAR void *arg) +{ + FAR struct tmpfs_object_s *to; + unsigned int index; + int ret; + + /* Visit each directory entry */ + + for (index = 0; index < tdo->tdo_nentries; ) + { + /* Lock the object and take a reference */ + + to = tdo->tdo_entry[index].tde_object; + tmpfs_lock_object(to); + to->to_refs++; + + /* Is the next entry a directory? */ + + if (to->to_type == TMPFS_DIRECTORY) + { + FAR struct tmpfs_directory_s *next = + (FAR struct tmpfs_directory_s *)to; + + /* Yes.. traverse its children first in the case the the final + * action will be to delete the directory. + */ + + ret = tmpfs_foreach(next, tmpfs_free_callout, NULL); + if (ret < 0) + { + return -ECANCELED; + } + } + + /* Perform the callout */ + + ret = callout(tdo, index, arg); + switch (ret) + { + case TMPFS_CONTINUE: /* Continue enumeration */ + /* Release the object and index to the next entry */ + + tmpfs_release_lockedobject(to); + index++; + break; + + case TMPFS_HALT: /* Stop enumeration */ + /* Release the object and cancel the traversal */ + + tmpfs_release_lockedobject(to); + return -ECANCELED; + + case TMPFS_UNLINKED: /* Only the directory entry was deleted */ + /* Release the object and continue with the same index */ + + tmpfs_release_lockedobject(to); + + case TMPFS_DELETED: /* Object and directory entry deleted */ + break; /* Continue with the same index */ + } + } + + return OK; +} + +/**************************************************************************** + * Name: tmpfs_open + ****************************************************************************/ + +static int tmpfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct inode *inode; + FAR struct tmpfs_s *fs; + FAR struct tmpfs_file_s *tfo; + off_t offset; + int ret; + + fvdbg("filep: %p\n", filep); + DEBUGASSERT(filep->f_priv == NULL && filep->f_inode != NULL); + + /* Get the mountpoint inode reference from the file structure and the + * mountpoint private data from the inode structure + */ + + inode = filep->f_inode; + fs = inode->i_private; + + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Skip over any leading directory separators (shouldn't be any) */ + + for (; *relpath == '/'; relpath++); + + /* Find the file object associated with this relative path. + * If successful, this action will lock both the parent directory and + * the file object, adding one to the reference count of both. + * In the event that -ENOENT, there will still be a reference and + * lock on the returned directory. + */ + + ret = tmpfs_find_file(fs, relpath, &tfo, NULL); + if (ret >= 0) + { + /* The file exists. We hold the lock and one reference count + * on the file object. + * + * It would be an error if we are asked to create it exclusively + */ + + if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + { + /* Already exists -- can't create it exclusively */ + + ret = -EEXIST; + goto errout_with_filelock; + } + + /* Check if the caller has sufficient privileges to open the file */ + /* REVISIT: No file protection implemented */ + + /* If O_TRUNC is specified and the file is opened for writing, + * then truncate the file. This operation requires that the file is + * writeable, but we have already checked that. O_TRUNC without write + * access is ignored. + */ + + if ((oflags & (O_TRUNC | O_WRONLY)) == (O_TRUNC | O_WRONLY)) + { + /* Truncate the file to zero length (if it is not already + * zero length) + */ + + if (tfo->tfo_size > 0) + { + ret = tmpfs_realloc_file(&tfo, 0); + if (ret < 0) + { + goto errout_with_filelock; + } + } + } + } + + /* ENOENT would be returned by tmpfs_find_file() if the full directory + * path was found, but the file was not found in the final directory. + */ + + else if (ret == -ENOENT) + { + /* The file does not exist. Were we asked to create it? */ + + if ((oflags & O_CREAT) == 0) + { + /* No.. then we fail with -ENOENT */ + + ret = -ENOENT; + goto errout_with_fslock; + } + + /* Yes.. create the file object. There will be a reference and a lock + * on the new file object. + */ + + ret = tmpfs_create_file(fs, relpath, &tfo); + if (ret < 0) + { + goto errout_with_fslock; + } + } + + /* Some other error occurred */ + + else + { + goto errout_with_fslock; + } + + /* Save the struct tmpfs_file_s instance as the file private data */ + + filep->f_priv = tfo; + + /* In write/append mode, we need to set the file pointer to the end of the + * file. + */ + + offset = 0; + if ((oflags & (O_APPEND | O_WRONLY)) == (O_APPEND | O_WRONLY)) + { + offset = tfo->tfo_size; + } + + filep->f_pos = offset; + + /* Unlock the file file object, but retain the reference count */ + + tmpfs_unlock_file(tfo); + tmpfs_unlock(fs); + return OK; + + /* Error exits */ + +errout_with_filelock: + tmpfs_release_lockedfile(tfo); + +errout_with_fslock: + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_close + ****************************************************************************/ + +static int tmpfs_close(FAR struct file *filep) +{ + FAR struct tmpfs_file_s *tfo; + + fvdbg("filep: %p\n", filep); + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = filep->f_priv; + + /* Get exclusive access to the file */ + + tmpfs_lock_file(tfo); + + /* Decrement the reference count on the file */ + + DEBUGASSERT(tfo->tfo_refs > 0); + if (tfo->tfo_refs > 0) + { + tfo->tfo_refs--; + } + + filep->f_priv = NULL; + + /* If the reference count decremented to zero and the file has been + * unlinked, then free the file allocation now. + */ + + if (tfo->tfo_refs == 0 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0) + { + /* Free the file object while we hold the lock? Weird but this + * should be safe because the object is unlinked and could not + * have any other references. + */ + + kmm_free(tfo); + return OK; + } + + /* Release the lock on the file */ + + tmpfs_unlock_file(tfo); + return OK; +} + +/**************************************************************************** + * Name: tmpfs_read + ****************************************************************************/ + +static ssize_t tmpfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct tmpfs_file_s *tfo; + ssize_t nread; + off_t startpos; + off_t endpos; + + fvdbg("filep: %p buffer: %p buflen: %lu\n", + filep, buffer, (unsigned long)buflen); + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = filep->f_priv; + + /* Get exclusive access to the file */ + + tmpfs_lock_file(tfo); + + /* Handle attempts to read beyond the end of the file. */ + + startpos = filep->f_pos; + nread = buflen; + endpos = startpos + buflen; + + if (endpos > tfo->tfo_size) + { + endpos = tfo->tfo_size; + nread = endpos - startpos; + } + + /* Copy data from the memory object to the user buffer */ + + memcpy(buffer, &tfo->tfo_data[startpos], nread); + filep->f_pos += nread; + + /* Release the lock on the file */ + + tmpfs_unlock_file(tfo); + return nread; +} + +/**************************************************************************** + * Name: tmpfs_write + ****************************************************************************/ + +static ssize_t tmpfs_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + FAR struct tmpfs_file_s *tfo; + ssize_t nwritten; + off_t startpos; + off_t endpos; + int ret; + + fvdbg("filep: %p buffer: %p buflen: %lu\n", + filep, buffer, (unsigned long)buflen); + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = filep->f_priv; + + /* Get exclusive access to the file */ + + tmpfs_lock_file(tfo); + + /* Handle attempts to read beyond the end of the file */ + + startpos = filep->f_pos; + nwritten = buflen; + endpos = startpos + buflen; + + if (endpos > tfo->tfo_size) + { + /* Reallocate the file to handle the write past the end of the file. */ + + ret = tmpfs_realloc_file(&tfo, (size_t)endpos); + if (ret < 0) + { + goto errout_with_lock; + } + + filep->f_priv = tfo; + } + + /* Copy data from the memory object to the user buffer */ + + memcpy(&tfo->tfo_data[startpos], buffer, nwritten); + filep->f_pos += nwritten; + + /* Release the lock on the file */ + + tmpfs_unlock_file(tfo); + return nwritten; + +errout_with_lock: + tmpfs_unlock_file(tfo); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: tmpfs_seek + ****************************************************************************/ + +static off_t tmpfs_seek(FAR struct file *filep, off_t offset, int whence) +{ + FAR struct tmpfs_file_s *tfo; + off_t position; + + fvdbg("filep: %p\n", filep); + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = filep->f_priv; + + /* Map the offset according to the whence option */ + + switch (whence) + { + case SEEK_SET: /* The offset is set to offset bytes. */ + position = offset; + break; + + case SEEK_CUR: /* The offset is set to its current location plus + * offset bytes. */ + position = offset + filep->f_pos; + break; + + case SEEK_END: /* The offset is set to the size of the file plus + * offset bytes. */ + position = offset + tfo->tfo_size; + break; + + default: + return -EINVAL; + } + + /* Attempts to set the position beyound the end of file will + * work if the file is open for write access. + * + * REVISIT: This simple implementation has no per-open storage that + * would be needed to retain the open flags. + */ + +#if 0 + if (position > tfo->tfo_size && (tfo->tfo_oflags & O_WROK) == 0) + { + /* Otherwise, the position is limited to the file size */ + + position = tfo->tfo_size; + } +#endif + + /* Save the new file position */ + + filep->f_pos = position; + return position; +} + +/**************************************************************************** + * Name: tmpfs_ioctl + ****************************************************************************/ + +static int tmpfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct tmpfs_file_s *tfo; + FAR void **ppv = (FAR void**)arg; + + fvdbg("filep: %p cmd: %d arg: %08lx\n", filep, cmd, arg); + DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = filep->f_inode->i_private; + + DEBUGASSERT(tfo != NULL); + + /* Only one ioctl command is supported */ + + if (cmd == FIOC_MMAP && ppv != NULL) + { + /* Return the address on the media corresponding to the start of + * the file. + */ + + *ppv = (FAR void *)tfo->tfo_data; + return OK; + } + + fdbg("Invalid cmd: %d\n", cmd); + return -ENOTTY; +} + +/**************************************************************************** + * Name: tmpfs_dup + ****************************************************************************/ + +static int tmpfs_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct tmpfs_file_s *tfo; + + fvdbg("Dup %p->%p\n", oldp, newp); + DEBUGASSERT(oldp->f_priv != NULL && oldp->f_inode != NULL && + newp->f_priv == NULL && newp->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + tfo = oldp->f_priv; + DEBUGASSERT(tfo != NULL); + + /* Increment the reference count (atomically)*/ + + tmpfs_lock_file(tfo); + tfo->tfo_refs++; + tmpfs_unlock_file(tfo); + + /* Save a copy of the file object as the dup'ed file. This + * simple implementation does not many any per-open data + * structures so there is not really much to the dup operation. + */ + + newp->f_priv = tfo; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_opendir + ****************************************************************************/ + +static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, + FAR struct fs_dirent_s *dir) +{ + FAR struct tmpfs_s *fs; + FAR struct tmpfs_directory_s *tdo; + int ret; + + fvdbg("mountpt: %p relpath: %s dir: %p\n", + mountpt, relpath, dir); + DEBUGASSERT(mountpt != NULL && relpath != NULL && dir != NULL); + + /* Get the mountpoint private data from the inode structure */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Skip over any leading directory separators (shouldn't be any) */ + + for (; *relpath == '/'; relpath++); + + /* Find the directory object associated with this relative path. + * If successful, this action will lock both the parent directory and + * the file object, adding one to the reference count of both. + * In the event that -ENOENT, there will still be a reference and + * lock on the returned directory. + */ + + ret = tmpfs_find_directory(fs, relpath, &tdo, NULL); + if (ret >= 0) + { + dir->u.tmpfs.tf_tdo = tdo; + dir->u.tmpfs.tf_index = 0; + } + + /* Release the lock on the file system and return the result */ + + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_closedir + ****************************************************************************/ + +static int tmpfs_closedir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir) +{ + FAR struct tmpfs_directory_s *tdo; + + fvdbg("mountpt: %p dir: %p\n", mountpt, dir); + DEBUGASSERT(mountpt != NULL && dir != NULL); + + /* Get the directory structure from the dir argument */ + + tdo = dir->u.tmpfs.tf_tdo; + DEBUGASSERT(tdo != NULL); + + /* Decrement the reference count on the directory object */ + + tmpfs_lock_directory(tdo); + tdo->tdo_refs--; + tmpfs_unlock_directory(tdo); + return OK; +} + +/**************************************************************************** + * Name: tmpfs_readdir + ****************************************************************************/ + +static int tmpfs_readdir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir) +{ + FAR struct tmpfs_directory_s *tdo; + unsigned int index; + int ret; + + fvdbg("mountpt: %p dir: %p\n", mountpt, dir); + DEBUGASSERT(mountpt != NULL && dir != NULL); + + /* Get the directory structure from the dir argument and lock it */ + + tdo = dir->u.tmpfs.tf_tdo; + DEBUGASSERT(tdo != NULL); + + tmpfs_lock_directory(tdo); + + /* Have we reached the end of the directory? */ + + index = dir->u.tmpfs.tf_index; + if (index >= tdo->tdo_nentries) + { + /* We signal the end of the directory by returning the special error: + * -ENOENT + */ + + fvdbg("End of directory\n"); + ret = -ENOENT; + } + else + { + FAR struct tmpfs_dirent_s *tde; + FAR struct tmpfs_object_s *to; + + /* Does this entry refer to a file or a directory object? */ + + tde = &tdo->tdo_entry[index]; + to = tde->tde_object; + DEBUGASSERT(to != NULL); + + if (to->to_type == TMPFS_DIRECTORY) + { + /* A directory */ + + dir->fd_dir.d_type = DTYPE_DIRECTORY; + } + else /* to->to_type == TMPFS_REGULAR) */ + { + /* A regular file */ + + dir->fd_dir.d_type = DTYPE_FILE; + } + + /* Copy the entry name */ + + strncpy(dir->fd_dir.d_name, tde->tde_name, NAME_MAX + 1); + + /* Increment the index for next time */ + + dir->u.tmpfs.tf_index = index + 1; + ret = OK; + } + + tmpfs_unlock_directory(tdo); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_rewinddir + ****************************************************************************/ + +static int tmpfs_rewinddir(FAR struct inode *mountpt, + FAR struct fs_dirent_s *dir) +{ + fvdbg("mountpt: %p dir: %p\n", mountpt, dir); + DEBUGASSERT(mountpt != NULL && dir != NULL); + + /* Set the readdir index to zero */ + + dir->u.tmpfs.tf_index = 0; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_bind + ****************************************************************************/ + +static int tmpfs_bind(FAR struct inode *blkdriver, FAR const void *data, + FAR void **handle) +{ + FAR struct tmpfs_directory_s *tdo; + FAR struct tmpfs_s *fs; + + fvdbg("blkdriver: %p data: %p handle: %p\n", blkdriver, data, handle); + DEBUGASSERT(blkdriver == NULL && handle != NULL); + + /* Create an instance of the tmpfs file system */ + + fs = (FAR struct tmpfs_s *)kmm_zalloc(sizeof(struct tmpfs_s)); + if (fs == NULL) + { + return -ENOMEM; + } + + /* Create a root file system. This is like a single directory entry in + * the file system structure. + */ + + tdo = tmpfs_alloc_directory(); + if (tdo == NULL) + { + kmm_free(fs); + return -ENOMEM; + } + + fs->tfs_root.tde_object = (FAR struct tmpfs_object_s *)tdo; + fs->tfs_root.tde_name = ""; + + /* Set up the backward link (to support reallocation) */ + + tdo->tdo_dirent = &fs->tfs_root; + + /* Initialize the file system state */ + + fs->tfs_exclsem.ts_holder = TMPFS_NO_HOLDER; + fs->tfs_exclsem.ts_count = 0; + sem_init(&fs->tfs_exclsem.ts_sem, 0, 1); + + /* Return the new file system handle */ + + *handle = (FAR void *)fs; + return OK; +} + +/**************************************************************************** + * Name: tmpfs_unbind + ****************************************************************************/ + +static int tmpfs_unbind(FAR void *handle, FAR struct inode **blkdriver, + unsigned int flags) +{ + FAR struct tmpfs_s *fs = (FAR struct tmpfs_s *)handle; + FAR struct tmpfs_directory_s *tdo; + int ret; + + fvdbg("handle: %p blkdriver: %p flags: %02x\n", + handle, blkdriver, flags); + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Lock the file system */ + + tmpfs_lock(fs); + + /* Traverse all directory entries (recursively), freeing all resources. */ + + tdo = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + ret = tmpfs_foreach(tdo, tmpfs_free_callout, NULL); + + /* Now we can destroy the root file system and the file system itself. */ + + sem_destroy(&tdo->tdo_exclsem.ts_sem); + kmm_free(tdo); + + sem_destroy(&fs->tfs_exclsem.ts_sem); + kmm_free(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_statfs + ****************************************************************************/ + +static int tmpfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) +{ + FAR struct tmpfs_s *fs; + FAR struct tmpfs_directory_s *tdo; + struct tmpfs_statfs_s tmpbuf; + size_t inuse; + size_t avail; + off_t blkalloc; + off_t blkused; + int ret; + + fvdbg("mountpt: %p buf: %p\n", mountpt, buf); + DEBUGASSERT(mountpt != NULL && buf != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Set up the memory use for the file system and root directory object */ + + tdo = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + inuse = sizeof(struct tmpfs_s) + + SIZEOF_TMPFS_DIRECTORY(tdo->tdo_nentries); + avail = sizeof(struct tmpfs_s) + + tdo->tdo_alloc - inuse; + + tmpbuf.tsf_alloc = tdo->tdo_alloc; + tmpbuf.tsf_inuse = inuse; + tmpbuf.tsf_files = 0; + tmpbuf.tsf_ffree = avail / sizeof(struct tmpfs_dirent_s); + + /* Traverse the file system to accurmulate statistics */ + + ret = tmpfs_foreach(tdo, tmpfs_statfs_callout, (FAR void *)&tmpbuf); + if (ret < 0) + { + return -ECANCELED; + } + + /* Return something for the file system description */ + + blkalloc = (tmpbuf.tsf_alloc + CONFIG_FS_TMPFS_BLOCKSIZE - 1) / + CONFIG_FS_TMPFS_BLOCKSIZE; + blkused = (tmpbuf.tsf_inuse + CONFIG_FS_TMPFS_BLOCKSIZE - 1) / + CONFIG_FS_TMPFS_BLOCKSIZE; + + buf->f_type = TMPFS_MAGIC; + buf->f_namelen = NAME_MAX; + buf->f_bsize = CONFIG_FS_TMPFS_BLOCKSIZE; + buf->f_blocks = blkalloc; + buf->f_bfree = blkalloc - blkused; + buf->f_bavail = blkalloc - blkused; + buf->f_files = tmpbuf.tsf_files; + buf->f_ffree = tmpbuf.tsf_ffree; + + /* Release the lock on the file system */ + + tmpfs_unlock(fs); + return OK; +} + +/**************************************************************************** + * Name: tmpfs_unlink + ****************************************************************************/ + +static int tmpfs_unlink(FAR struct inode *mountpt, FAR const char *relpath) +{ + FAR struct tmpfs_s *fs; + FAR struct tmpfs_directory_s *tdo; + FAR struct tmpfs_file_s *tfo; + FAR const char *name; + int ret; + + fvdbg("mountpt: %p relpath: %s\n", mountpt, relpath); + DEBUGASSERT(mountpt != NULL && relpath != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Find the file object and parent directory associated with this relative + * path. If successful, tmpfs_find_file will lock both the file object + * and the parent directory and take one reference count on each. + */ + + ret = tmpfs_find_file(fs, relpath, &tfo, &tdo); + if (ret < 0) + { + goto errout_with_lock; + } + + /* Get the file name from the relative path */ + + name = strrchr(relpath, '/'); + if (name != NULL) + { + /* Skip over the file '/' character */ + + name++; + } + else + { + /* The name must lie in the root directory */ + + name = relpath; + } + + /* Remove the file from parent directory */ + + ret = tmpfs_remove_dirent(tdo, name); + if (ret < 0) + { + goto errout_with_objects; + } + + /* If the reference count is not one, then just mark the file as + * unlinked + */ + + if (tfo->tfo_refs > 1) + { + /* Make the file object as unlinked */ + + tfo->tfo_flags |= TFO_FLAG_UNLINKED; + + /* Release the reference count on the file object */ + + tfo->tfo_refs--; + tmpfs_unlock_file(tfo); + } + + /* Otherwise we can free the object now */ + + else + { + sem_destroy(&tfo->tfo_exclsem.ts_sem); + kmm_free(tfo); + } + + /* Release the reference and lock on the parent directory */ + + tdo->tdo_refs--; + tmpfs_unlock_directory(tdo); + tmpfs_unlock(fs); + + return OK; + +errout_with_objects: + tmpfs_release_lockedfile(tfo); + + tdo->tdo_refs--; + tmpfs_unlock_directory(tdo); + +errout_with_lock: + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_mkdir + ****************************************************************************/ + +static int tmpfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath, + mode_t mode) +{ + FAR struct tmpfs_s *fs; + int ret; + + fvdbg("mountpt: %p relpath: %s mode: %04x\n", mountpt, relpath, mode); + DEBUGASSERT(mountpt != NULL && relpath != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Create the directory. */ + + ret = tmpfs_create_directory(fs, relpath, NULL); + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_rmdir + ****************************************************************************/ + +static int tmpfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath) +{ + FAR struct tmpfs_s *fs; + FAR struct tmpfs_directory_s *parent; + FAR struct tmpfs_directory_s *tdo; + FAR const char *name; + int ret; + + fvdbg("mountpt: %p relpath: %s\n", mountpt, relpath); + DEBUGASSERT(mountpt != NULL && relpath != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Find the directory object and parent directory associated with this + * relative path. If successful, tmpfs_find_file will lock both the + * directory object and the parent directory and take one reference count + * on each. + */ + + ret = tmpfs_find_directory(fs, relpath, &tdo, &parent); + if (ret < 0) + { + goto errout_with_lock; + } + + /* Is the directory empty? We cannot remove directories that still + * contain references to file system objects. No can we remove the + * directory if there are outstanding references on it (other than + * our reference). + */ + + if (tdo->tdo_nentries > 0 || tdo->tdo_refs > 1) + { + ret = -EBUSY; + goto errout_with_objects; + } + + /* Get the directory name from the relative path */ + + name = strrchr(relpath, '/'); + if (name != NULL) + { + /* Skip over the fidirectoryle '/' character */ + + name++; + } + else + { + /* The name must lie in the root directory */ + + name = relpath; + } + + /* Remove the directory from parent directory */ + + ret = tmpfs_remove_dirent(parent, name); + if (ret < 0) + { + goto errout_with_objects; + } + + /* Free the directory object */ + + sem_destroy(&tdo->tdo_exclsem.ts_sem); + kmm_free(tdo); + + /* Release the reference and lock on the parent directory */ + + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + tmpfs_unlock(fs); + + return OK; + +errout_with_objects: + tdo->tdo_refs--; + tmpfs_unlock_directory(tdo); + + parent->tdo_refs--; + tmpfs_unlock_directory(parent); + +errout_with_lock: + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_rename + ****************************************************************************/ + +static int tmpfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath, + FAR const char *newrelpath) +{ + FAR struct tmpfs_directory_s *oldparent; + FAR struct tmpfs_directory_s *newparent; + FAR struct tmpfs_object_s *to; + FAR struct tmpfs_s *fs; + FAR const char *oldname; + FAR char *newname; + FAR char *copy; + int ret; + + fvdbg("mountpt: %p oldrelpath: %s newrelpath: %s\n", + mountpt, oldrelpath, newrelpath); + DEBUGASSERT(mountpt != NULL && oldrelpath != NULL && newrelpath != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Duplicate the newpath variable so that we can modify it */ + + copy = strdup(newrelpath); + if (copy == NULL) + { + return -ENOMEM; + } + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Separate the new path into the new file name and the path to the new + * parent directory. + */ + + newname = strrchr(copy, '/'); + if (newname == NULL) + { + /* No subdirectories... use the root directory */ + + newname = copy; + newparent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; + + tmpfs_lock_directory(newparent); + newparent->tdo_refs++; + } + else + { + /* Terminate the parent directory path */ + + *newname++ = '\0'; + + /* Locate the parent directory that should contain this name. + * On success, tmpfs_find_directory() will lockthe parent + * directory and increment the reference count. + */ + + ret = tmpfs_find_directory(fs, copy, &newparent, NULL); + if (ret < 0) + { + goto errout_with_lock; + } + } + + /* Verify that no object of this name already exists in the destination + * directory. + */ + + ret = tmpfs_find_dirent(newparent, newname); + if (ret != -ENOENT) + { + /* Something with this name already exists in the directory. + * OR perhaps some fatal error occurred. + */ + + if (ret >= 0) + { + ret = -EEXIST; + } + + goto errout_with_newparent; + } + + /* Find the old object at oldpath. If successful, tmpfs_find_object() + * will lock both the object and the parent directory and will increment + * the reference count on both. + */ + + ret = tmpfs_find_object(fs, oldrelpath, &to, &oldparent); + if (ret < 0) + { + goto errout_with_newparent; + } + + /* Get the old file name from the relative path */ + + oldname = strrchr(oldrelpath, '/'); + if (oldname != NULL) + { + /* Skip over the file '/' character */ + + oldname++; + } + else + { + /* The name must lie in the root directory */ + + oldname = oldrelpath; + } + + /* Remove the entry from the parent directory */ + + ret = tmpfs_remove_dirent(oldparent, oldname); + if (ret < 0) + { + goto errout_with_oldparent; + } + + /* Add an entry to the new parent directory. */ + + ret = tmpfs_add_dirent(&newparent, to, newname); + +errout_with_oldparent: + oldparent->tdo_refs--; + tmpfs_unlock_directory(oldparent); + + tmpfs_release_lockedobject(to); + +errout_with_newparent: + newparent->tdo_refs--; + tmpfs_unlock_directory(newparent); + +errout_with_lock: + tmpfs_unlock(fs); + kmm_free(copy); + return ret; +} + +/**************************************************************************** + * Name: tmpfs_stat + ****************************************************************************/ + +static int tmpfs_stat(FAR struct inode *mountpt, FAR const char *relpath, + FAR struct stat *buf) +{ + FAR struct tmpfs_s *fs; + FAR struct tmpfs_object_s *to; + size_t objsize; + int ret; + + fvdbg("mountpt=%p relpath=%s buf=%p\n", mountpt, relpath, buf); + DEBUGASSERT(mountpt != NULL && relpath != NULL && buf != NULL); + + /* Get the file system structure from the inode reference. */ + + fs = mountpt->i_private; + DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); + + /* Get exclusive access to the file system */ + + tmpfs_lock(fs); + + /* Find the tmpfs object at the relpath. If successful, + * tmpfs_find_object() will lock the object and increment the + * reference count on the object. + */ + + ret = tmpfs_find_object(fs, relpath, &to, NULL); + if (ret < 0) + { + goto errout_with_fslock; + } + + /* We found it... Is the object a regular file? */ + + memset(buf, 0, sizeof(struct stat)); + + if (to->to_type == TMPFS_REGULAR) + { + FAR struct tmpfs_file_s *tfo = + (FAR struct tmpfs_file_s *)to; + + /* -rwxrwxrwx */ + + buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFREG; + + /* Get the size of the object */ + + objsize = tfo->tfo_size; + } + else /* if (to->to_type == TMPFS_DIRECTORY) */ + { + FAR struct tmpfs_directory_s *tdo = + (FAR struct tmpfs_directory_s *)to; + + /* drwxrwxrwx */ + + buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFDIR; + + /* Get the size of the object */ + + objsize = SIZEOF_TMPFS_DIRECTORY(tdo->tdo_nentries); + } + + /* Fake the rest of the information */ + + buf->st_size = objsize; + buf->st_blksize = CONFIG_FS_TMPFS_BLOCKSIZE; + buf->st_blocks = (objsize + CONFIG_FS_TMPFS_BLOCKSIZE - 1) / + CONFIG_FS_TMPFS_BLOCKSIZE; + + /* No... unlock the object and return success */ + + tmpfs_release_lockedobject(to); + ret = OK; + +errout_with_fslock: + tmpfs_unlock(fs); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_DISABLE_MOUNTPOINT */ diff --git a/fs/tmpfs/fs_tmpfs.h b/fs/tmpfs/fs_tmpfs.h new file mode 100644 index 0000000000000000000000000000000000000000..8e4b1a32f5f8283c02ffd9ffe37b537944ad8515 --- /dev/null +++ b/fs/tmpfs/fs_tmpfs.h @@ -0,0 +1,211 @@ +/**************************************************************************** + * fs/tmpfs/fs_tmpfs.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __FS_TMPFS_FS_TMPFS_H +#define __FS_TMPFS_FS_TMPFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Indicates that there is no holder of the re-entrant semaphore */ + +#define TMPFS_NO_HOLDER -1 + +/* Bit definitions for file object flags */ + +#define TFO_FLAG_UNLINKED (1 << 0) /* Bit 0: File is unlinked */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* TMPFS memory object types */ + +enum tmpfs_objtype_e +{ + TMPFS_DIRECTORY = 0, /* Directory */ + TMPFS_REGULAR /* Regular file */ +}; + +/* Values returned by tmpfs_foreach() */ + +enum tmpfs_foreach_e +{ + TMPFS_CONTINUE = 0, /* Continue enumeration */ + TMPFS_HALT, /* Stop enumeration */ + TMPFS_DELETED, /* Object and directory entry deleted */ + TMPFS_UNLINKED /* Only the directory entry was deleted */ +}; + +/* Re-entrant semaphore */ + +struct tmpfs_sem_s +{ + sem_t ts_sem; /* The actual semaphore */ + pid_t ts_holder; /* Current older (-1 if not held) */ + uint16_t ts_count; /* Number of counts held */ +}; + +/* The form of one directory entry */ + +struct tmpfs_dirent_s +{ + FAR struct tmpfs_object_s *tde_object; + FAR char *tde_name; +}; + +/* The generic form of a TMPFS memory object */ + +struct tmpfs_object_s +{ + FAR struct tmpfs_dirent_s *to_dirent; + struct tmpfs_sem_s to_exclsem; + + size_t to_alloc; /* Allocated size of the memory object */ + uint8_t to_type; /* See enum tmpfs_objtype_e */ + uint8_t to_refs; /* Reference count */ +}; + +/* The form of a directory memory object */ + +struct tmpfs_directory_s +{ + /* First fields must match common TMPFS object layout */ + + FAR struct tmpfs_dirent_s *tdo_dirent; + struct tmpfs_sem_s tdo_exclsem; + + size_t tdo_alloc; /* Allocated size of the directory object */ + uint8_t tdo_type; /* See enum tmpfs_objtype_e */ + uint8_t tdo_refs; /* Reference count */ + + /* Remaining fields are unique to a directory object */ + + uint16_t tdo_nentries; /* Number of directory entries */ + struct tmpfs_dirent_s tdo_entry[1]; +}; + +#define SIZEOF_TMPFS_DIRECTORY(n) \ + (sizeof(struct tmpfs_directory_s) + ((n) - 1) * sizeof(struct tmpfs_dirent_s)) + +/* The form of a regular file memory object + * + * NOTE that in this very simplified implementation, there is no per-open + * state. The file memory object also serves as the open file object, + * saving an allocation. This has the negative side effect that no per- + * open state can be retained (such as open flags). + */ + +struct tmpfs_file_s +{ + /* First fields must match common TMPFS object layout */ + + FAR struct tmpfs_dirent_s *tfo_dirent; + struct tmpfs_sem_s tfo_exclsem; + + size_t tfo_alloc; /* Allocated size of the file object */ + uint8_t tfo_type; /* See enum tmpfs_objtype_e */ + uint8_t tfo_refs; /* Reference count */ + + /* Remaining fields are unique to a directory object */ + + uint8_t tfo_flags; /* See TFO_FLAG_* definitions */ + size_t tfo_size; /* Valid file size */ + uint8_t tfo_data[1]; /* File data starts here */ +}; + +#define SIZEOF_TMPFS_FILE(n) (sizeof(struct tmpfs_file_s) + (n) - 1) + +/* This structure represents one instance of a TMPFS file system */ + +struct tmpfs_s +{ + /* The root directory */ + + FAR struct tmpfs_dirent_s tfs_root; + struct tmpfs_sem_s tfs_exclsem; +}; + +/* This is the type used the tmpfs_statfs_callout to accumulate memory usage */ + +struct tmpfs_statfs_s +{ + size_t tsf_alloc; /* Total memory allocated */ + size_t tsf_inuse; /* Total memory in use */ + off_t tsf_files; /* Total file nodes in the file system */ + off_t tsf_ffree; /* Free directory nodes in the file system */ +}; + +/* This is the type of the for tmpfs_foreach callback */ + +typedef int (*tmpfs_foreach_t)(FAR struct tmpfs_directory_s *tdo, + unsigned int index, FAR void *arg); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN const struct mountpt_operations tmpfs_operations; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __FS_TMPFS_FS_TMPFS_H */ diff --git a/fs/unionfs/fs_unionfs.c b/fs/unionfs/fs_unionfs.c index 9a3c8560b52a0522e22801b1c487b7b4a3c902d8..491d71f74a7dfdc4e1b83d7bda338e9450494d11 100644 --- a/fs/unionfs/fs_unionfs.c +++ b/fs/unionfs/fs_unionfs.c @@ -2085,7 +2085,8 @@ static int unionfs_unlink(FAR struct inode *mountpt, } /* Check if some exists at this path on file system 1. This might be - * a file or a directory*/ + * a file or a directory + */ um = &ui->ui_fs[0]; ret = unionfs_trystat(um->um_node, relpath, um->um_prefix, &buf); @@ -2444,7 +2445,7 @@ static int unionfs_stat(FAR struct inode *mountpt, FAR const char *relpath, static int unionfs_getmount(FAR const char *path, FAR struct inode **inode) { - FAR struct inode *minode; + FAR struct inode *minode; /* Find the mountpt */ @@ -2568,6 +2569,7 @@ int unionfs_mount(FAR const char *fspath1, FAR const char *prefix1, /* Insert a dummy node -- we need to hold the inode semaphore * to do this because we will have a momentarily bad structure. + * NOTE that the inode will be created with a refernce count of zero. */ inode_semtake(); @@ -2611,7 +2613,6 @@ int unionfs_mount(FAR const char *fspath1, FAR const char *prefix1, errout_with_semaphore: inode_semgive(); -//errout_with_prefix2: if (ui->ui_fs[1].um_prefix != NULL) { kmm_free(ui->ui_fs[1].um_prefix); diff --git a/fs/vfs/Make.defs b/fs/vfs/Make.defs index 4c3fca0258457815937ed56b99c8c425fbaac2e5..645e23f97e4c33632decaec96777ff6d6beeba92 100644 --- a/fs/vfs/Make.defs +++ b/fs/vfs/Make.defs @@ -41,7 +41,7 @@ ifneq ($(CONFIG_NSOCKET_DESCRIPTORS),0) # Socket descriptor support -CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_poll.c fs_select.c +CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c # Support for network access using streams @@ -49,6 +49,12 @@ ifneq ($(CONFIG_NFILE_STREAMS),0) CSRCS += fs_fdopen.c endif +# Support for poll() and select() (which derives from poll() + +ifneq ($(CONFIG_DISABLE_POLL),y) +CSRCS += fs_poll.c fs_select.c +endif + # Support for sendfile() ifeq ($(CONFIG_NET_SENDFILE),y) diff --git a/fs/vfs/fs_close.c b/fs/vfs/fs_close.c index dd346411979e85816fca7770c773f5814e5c9886..b784b2c9e0c5e4cc7ca15e9fde14d4c2677761a2 100644 --- a/fs/vfs/fs_close.c +++ b/fs/vfs/fs_close.c @@ -51,7 +51,7 @@ #include "inode/inode.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_dup.c b/fs/vfs/fs_dup.c index 5981dc8cd5ef2945269ac83f01ffadaac7d5eed5..03b8b751ab6ffb41e327f0b446914408d4da2729 100644 --- a/fs/vfs/fs_dup.c +++ b/fs/vfs/fs_dup.c @@ -55,7 +55,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -77,7 +77,8 @@ int dup(int fd) if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) { /* Its a valid file descriptor.. dup the file descriptor using any - * other file descriptor*/ + * other file descriptor + */ ret = fs_dupfd(fd, 0); } diff --git a/fs/vfs/fs_dup2.c b/fs/vfs/fs_dup2.c index 3164e0b2f5fa5b858e0c0519f023b73073fd1176..c81e7b6eae0fd2267bfc470177020f3c1b5f26dd 100644 --- a/fs/vfs/fs_dup2.c +++ b/fs/vfs/fs_dup2.c @@ -61,7 +61,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_dupfd2.c b/fs/vfs/fs_dupfd2.c index 6043430bdc548b46689cc22b7e95d7136735d661..8857c767f8df955dd66d2f65d2cdc2d76579f4c5 100644 --- a/fs/vfs/fs_dupfd2.c +++ b/fs/vfs/fs_dupfd2.c @@ -58,7 +58,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_fsync.c b/fs/vfs/fs_fsync.c index 4d2311ea0c29e858cfca83888129998f8cd1f43d..167daafa2175933f95889f28196af871bda9ebf0 100644 --- a/fs/vfs/fs_fsync.c +++ b/fs/vfs/fs_fsync.c @@ -56,11 +56,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index eb48d5c34343ff50958f8d358b922b0cf43c3d41..593eae963a33cd6e8894a356a95f0ad06f666d46 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -53,7 +53,7 @@ #include "inode/inode.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_mkdir.c b/fs/vfs/fs_mkdir.c index 6d037b37c1ac01c9239dacc44558c26e2026753b..886b4114a111ed916cd684e319d450144a2e2c1a 100644 --- a/fs/vfs/fs_mkdir.c +++ b/fs/vfs/fs_mkdir.c @@ -68,11 +68,11 @@ #ifdef FS_HAVE_MKDIR /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -154,7 +154,10 @@ int mkdir(const char *pathname, mode_t mode) else { - /* Create an inode in the pseudo-filesystem at this path */ + /* Create an inode in the pseudo-filesystem at this path. + * NOTE that the new inode will be created with a reference + * count of zero. + */ inode_semtake(); ret = inode_reserve(pathname, &inode); @@ -178,9 +181,9 @@ int mkdir(const char *pathname, mode_t mode) return OK; - errout_with_inode: +errout_with_inode: inode_release(inode); - errout: +errout: set_errno(errcode); return ERROR; } diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index 1fb0cb538aa026d0a5e70f350c2f1deba3e55a8b..81a2ef7f7cc62693ef896f88665ea8b8a9fec248 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -51,6 +51,7 @@ #include #include "inode/inode.h" +#include "driver/driver.h" /**************************************************************************** * Private Functions @@ -107,7 +108,7 @@ int open(const char *path, int oflags, ...) /* If the file is opened for creation, then get the mode bits */ - if ((oflags & (O_WRONLY|O_CREAT)) != 0) + if ((oflags & (O_WRONLY | O_CREAT)) != 0) { va_list ap; va_start(ap, oflags); @@ -130,9 +131,42 @@ int open(const char *path, int oflags, ...) goto errout; } - /* Verify that the inode is valid and either a "normal" character driver or a - * mountpoint. We specifically exclude block drivers and and "special" - * inodes (semaphores, message queues, shared memory). +#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \ + !defined(CONFIG_DISABLE_MOUNTPOINT) + /* If the inode is block driver, then we may return a character driver + * proxy for the block driver. block_proxy() will instantiate a BCH + * character driver wrapper around the block driver, open(), then + * unlink() the character driver. On success, block_proxy() will + * return the file descriptor of the opened character driver. + * + * NOTE: This will recurse to open the character driver proxy. + */ + + if (INODE_IS_BLOCK(inode)) + { + /* Release the inode reference */ + + inode_release(inode); + + /* Get the file descriptor of the opened character driver proxy */ + + fd = block_proxy(path, oflags); + if (fd < 0) + { + ret = fd; + goto errout; + } + + /* Return the file descriptor */ + + return fd; + } + else +#endif + + /* Verify that the inode is either a "normal" character driver or a + * mountpoint. We specifically "special" inodes (semaphores, message + * queues, shared memory). */ #ifndef CONFIG_DISABLE_MOUNTPOINT @@ -201,11 +235,11 @@ int open(const char *path, int oflags, ...) return fd; - errout_with_fd: +errout_with_fd: files_release(fd); - errout_with_inode: +errout_with_inode: inode_release(inode); - errout: +errout: set_errno(ret); return ERROR; } diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index f5873f3a78d51eecc426f3c67a5f2c461ea14657..2910b30551f7f8c1105b0b18b1b9dc882415db88 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_poll.c * - * Copyright (C) 2008-2009, 2012-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2012-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,16 +39,17 @@ #include -#include #include #include -#include +#include +#include #include -#include +#include -#include #include #include +#include +#include #include @@ -176,6 +177,9 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem) (void)poll_fdsetup(fds[j].fd, &fds[j], false); } + /* Indicate an error on the file descriptor */ + + fds[i].revents |= POLLERR; return ret; } } @@ -323,10 +327,9 @@ int file_poll(int fd, FAR struct pollfd *fds, bool setup) int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) { - struct timespec abstime; - irqstate_t flags; sem_t sem; int count = 0; + int err; int ret; sem_init(&sem, 0, 0); @@ -341,55 +344,26 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) } else if (timeout > 0) { - time_t sec; - uint32_t nsec; - /* Either wait for either a poll event(s), for a signal to occur, * or for the specified timeout to elapse with no event. * * NOTE: If a poll event is pending (i.e., the semaphore has already - * been incremented), sem_timedwait() will not wait, but will return + * been incremented), sem_tickwait() will not wait, but will return * immediately. */ - sec = timeout / MSEC_PER_SEC; - nsec = (timeout - MSEC_PER_SEC * sec) * NSEC_PER_MSEC; - - /* Make sure that the following are atomic by disabling interrupts. - * Interrupts will be re-enabled while we are waiting. - */ - - flags = irqsave(); - (void)clock_gettime(CLOCK_REALTIME, &abstime); - - abstime.tv_sec += sec; - abstime.tv_nsec += nsec; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ret = sem_timedwait(&sem, &abstime); + ret = sem_tickwait(&sem, clock_systimer(), MSEC2TICK(timeout)); if (ret < 0) { - int err = get_errno(); - - if (err == ETIMEDOUT) + if (ret == -ETIMEDOUT) { /* Return zero (OK) in the event of a timeout */ ret = OK; } - else - { - /* EINTR is the only other error expected in normal operation */ - ret = -err; - } + /* EINTR is the only other error expected in normal operation */ } - - irqrestore(flags); } else { @@ -400,9 +374,15 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) /* Teardown the poll operation and get the count of events. Zero will be * returned in the case of a timeout. + * + * Preserve ret, if negative, since it holds the result of the wait. */ - ret = poll_teardown(fds, nfds, &count, ret); + err = poll_teardown(fds, nfds, &count, ret); + if (err < 0 && ret >= 0) + { + ret = err; + } } sem_destroy(&sem); diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index c5cdc701e650caa9a99ff3445bb7a1499fa0d0d5..f1d6097236c3186bf45fbaad4b8448c55cba5ccf 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -101,7 +101,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) * signature and position in the operations vtable. */ - ret = (int)inode->u.i_ops->read(filep, (char*)buf, (size_t)nbytes); + ret = (int)inode->u.i_ops->read(filep, (FAR char *)buf, (size_t)nbytes); } /* If an error occurred, set errno and return -1 (ERROR) */ diff --git a/fs/vfs/fs_rename.c b/fs/vfs/fs_rename.c index cb9173dab972732faaa1cd612b9cc12599a6ec12..785898f2536707c1cc3e69f8352887c14c728af7 100644 --- a/fs/vfs/fs_rename.c +++ b/fs/vfs/fs_rename.c @@ -68,11 +68,11 @@ #ifdef FS_HAVE_RENAME /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -175,7 +175,10 @@ int rename(FAR const char *oldpath, FAR const char *newpath) #endif #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS { - /* Create a new, empty inode at the destination location */ + /* Create a new, empty inode at the destination location. + * NOTE that the new inode will be created with a reference count + * of zero. + */ inode_semtake(); ret = inode_reserve(newpath, &newinode); @@ -242,12 +245,12 @@ int rename(FAR const char *oldpath, FAR const char *newpath) return OK; #ifndef CONFIG_DISABLE_MOUNTPOINT - errout_with_newinode: +errout_with_newinode: inode_release(newinode); #endif - errout_with_oldinode: +errout_with_oldinode: inode_release(oldinode); - errout: +errout: set_errno(errcode); return ERROR; } diff --git a/fs/vfs/fs_rmdir.c b/fs/vfs/fs_rmdir.c index 685704e0debded229a59b0100fbbce847d5b3f24..ba46b25ee942b7ad15228119f475ad28a69bbec6 100644 --- a/fs/vfs/fs_rmdir.c +++ b/fs/vfs/fs_rmdir.c @@ -68,11 +68,11 @@ #ifdef FS_HAVE_RMDIR /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_select.c b/fs/vfs/fs_select.c index 60151232f2c95e20be6190a663bcfcc860ea4e06..d71d8e28a1c2921593dc5956afe106c21f41afcd 100644 --- a/fs/vfs/fs_select.c +++ b/fs/vfs/fs_select.c @@ -238,7 +238,7 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds, if (readfds) { - if (pollset[ndx].revents & (POLLIN|POLLHUP)) + if (pollset[ndx].revents & (POLLIN | POLLHUP)) { FD_SET(pollset[ndx].fd, readfds); ret++; diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index 05c3d976eb4c22b6bf7e9b87c951775d1f0fcda2..cf05b88868782ddfdb1d361608d88bdf04fd7b93 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * fs/vfs/fs_sendfile.c * * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -51,27 +51,27 @@ #if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_SENDFILE -/************************************************************************ +/**************************************************************************** * Private types - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sendfile * * Description: @@ -114,7 +114,7 @@ * EINVAL - Bad input parameters. * ENOMEM - Could not allocated an I/O buffer * - ************************************************************************/ + ****************************************************************************/ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count) { diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index b8b62080bbbaf546b5bbdf799dad41fe5bf418e2..a96cf3be71921556d560b7cca88acd6c70b23eb7 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -58,7 +58,7 @@ static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf) { /* Most of the stat entries just do not apply */ - memset(buf, 0, sizeof(struct stat) ); + memset(buf, 0, sizeof(struct stat)); if (INODE_IS_SPECIAL(inode)) { @@ -90,12 +90,12 @@ static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf) { if (inode->u.i_ops->read) { - buf->st_mode = S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR; } if (inode->u.i_ops->write) { - buf->st_mode |= S_IWOTH|S_IWGRP|S_IWUSR; + buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR; } if (INODE_IS_MOUNTPT(inode)) @@ -123,7 +123,7 @@ static inline int statpseudo(FAR struct inode *inode, FAR struct stat *buf) * write-able. */ - buf->st_mode |= S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + buf->st_mode |= S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; } return OK; @@ -137,13 +137,13 @@ static inline int statroot(FAR struct stat *buf) { /* There is no inode associated with the fake root directory */ - memset(buf, 0, sizeof(struct stat) ); - buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR; + memset(buf, 0, sizeof(struct stat)); + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; return OK; } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c index 0d70cfa606c12bce5393d319964f2be24ad8e84e..4c884c421bfed7c6c19c04f07b552924b1c12fd9 100644 --- a/fs/vfs/fs_unlink.c +++ b/fs/vfs/fs_unlink.c @@ -68,11 +68,11 @@ #ifdef FS_HAVE_UNLINK /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -225,9 +225,9 @@ int unlink(FAR const char *pathname) inode_release(inode); return OK; - errout_with_inode: +errout_with_inode: inode_release(inode); - errout: +errout: set_errno(errcode); return ERROR; } diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index 830e56dcc02b0775f3a3ac5c7607709ddd062cdf..b7f71a226567f862e408ea85ed9a31655cb2fabb 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -108,7 +108,7 @@ errout: return ERROR; } -/*************************************************************************** +/**************************************************************************** * Name: write * * Description: diff --git a/graphics/nxbe/nxbe_colormap.c b/graphics/nxbe/nxbe_colormap.c index 536c317541ee9f693948de25b70985b0b519ea44..1443206068fcc101f47ae7ec161204e9210a58f5 100644 --- a/graphics/nxbe/nxbe_colormap.c +++ b/graphics/nxbe/nxbe_colormap.c @@ -81,20 +81,22 @@ * ****************************************************************************/ -#if CONFIG_FB_CMAP +#ifdef CONFIG_FB_CMAP int nxbe_colormap(FAR NX_DRIVERTYPE *dev) { struct fb_cmap_s cmap; - uint8_t *alloc; - uint8_t *red; - uint8_t *green; - uint8_t *blue; + FAR uint8_t *alloc; + FAR uint8_t *red; + FAR uint8_t *green; + FAR uint8_t *blue; uint8_t rval; uint8_t gval; int size; int ndx; int ret; - int i, j, k; + int i; + int j; + int k; /* Allocate the color map tables in one allocation: * @@ -102,7 +104,7 @@ int nxbe_colormap(FAR NX_DRIVERTYPE *dev) */ size = 3 * CONFIG_NX_NCOLORS * sizeof(uint8_t); - alloc = (uint8_t*)kmm_malloc(size); + alloc = (FAR uint8_t *)kmm_malloc(size); if (alloc == NULL) { return -ENOMEM; diff --git a/graphics/nxglib/fb/nxglib_copyrectangle.c b/graphics/nxglib/fb/nxglib_copyrectangle.c index 0a6c12d414f5371e5eae8e3c086ec6d6f26f673a..ea0d1ad2e7e43458e983efb369a07abdce0ae144 100644 --- a/graphics/nxglib/fb/nxglib_copyrectangle.c +++ b/graphics/nxglib/fb/nxglib_copyrectangle.c @@ -79,7 +79,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_copyrectangle, NXGLIB_SUFFIX) (FAR struct fb_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *dest, FAR const void *src, FAR const struct nxgl_point_s *origin, unsigned int srcstride) @@ -131,7 +131,7 @@ void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) /* Then copy the image */ - sline = (const uint8_t*)src + NXGL_SCALEX(dest->pt1.x - origin->x) + (dest->pt1.y - origin->y) * srcstride; + sline = (FAR const uint8_t *)src + NXGL_SCALEX(dest->pt1.x - origin->x) + (dest->pt1.y - origin->y) * srcstride; dline = pinfo->fbmem + dest->pt1.y * deststride + NXGL_SCALEX(dest->pt1.x); while (rows--) @@ -171,7 +171,7 @@ void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) #else /* Copy the whole line */ - NXGL_MEMCPY((NXGL_PIXEL_T*)dline, (NXGL_PIXEL_T*)sline, width); + NXGL_MEMCPY((NXGL_PIXEL_T *)dline, (NXGL_PIXEL_T *)sline, width); #endif dline += deststride; sline += srcstride; diff --git a/graphics/nxglib/fb/nxglib_fillrectangle.c b/graphics/nxglib/fb/nxglib_fillrectangle.c index 3125004c9d9a36222b67caa6506b34d117b36f15..baaad84697ba5696360d3490ee14d216a5faa15c 100644 --- a/graphics/nxglib/fb/nxglib_fillrectangle.c +++ b/graphics/nxglib/fb/nxglib_fillrectangle.c @@ -82,7 +82,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_fillrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_fillrectangle, NXGLIB_SUFFIX) (FAR struct fb_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect, NXGL_PIXEL_T color) diff --git a/graphics/nxglib/fb/nxglib_filltrapezoid.c b/graphics/nxglib/fb/nxglib_filltrapezoid.c index 789ae7cee1d55a77cb18d822d088a384c1adc514..dcf29faad4fb8c8ee3fceb2574d486200df18495 100644 --- a/graphics/nxglib/fb/nxglib_filltrapezoid.c +++ b/graphics/nxglib/fb/nxglib_filltrapezoid.c @@ -70,7 +70,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX)( +void NXGL_FUNCNAME(nxgl_filltrapezoid, NXGLIB_SUFFIX)( FAR struct fb_planeinfo_s *pinfo, FAR const struct nxgl_trapezoid_s *trap, FAR const struct nxgl_rect_s *bounds, diff --git a/graphics/nxglib/fb/nxglib_getrectangle.c b/graphics/nxglib/fb/nxglib_getrectangle.c index c1a9e1ee2de3d346ee4b819a3635779c79861635..39386b4cbd74946244f5cd8ebddfed6cb92c9594 100644 --- a/graphics/nxglib/fb/nxglib_getrectangle.c +++ b/graphics/nxglib/fb/nxglib_getrectangle.c @@ -127,7 +127,7 @@ static inline void nxgl_lowresmemcpy(FAR uint8_t *dline, FAR const uint8_t *slin * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_getrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_getrectangle, NXGLIB_SUFFIX) (FAR struct fb_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect, FAR void *dest, unsigned int deststride) { diff --git a/graphics/nxglib/fb/nxglib_setpixel.c b/graphics/nxglib/fb/nxglib_setpixel.c index 29f83bbaa3bf6ea2ee9774c4326281e21423ac1b..c1c764f716f6e04e90f46634a1b342e01ab1d5b3 100644 --- a/graphics/nxglib/fb/nxglib_setpixel.c +++ b/graphics/nxglib/fb/nxglib_setpixel.c @@ -84,7 +84,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_setpixel,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_setpixel, NXGLIB_SUFFIX) (FAR struct fb_planeinfo_s *pinfo, FAR const struct nxgl_point_s *pos, NXGL_PIXEL_T color) diff --git a/graphics/nxglib/lcd/nxglib_copyrectangle.c b/graphics/nxglib/lcd/nxglib_copyrectangle.c index 1194ff8e1b75224f26c4ed34e9cb44fd713fbea3..0c5e266c6202b64541244eb0f707f35c9e5cd66f 100644 --- a/graphics/nxglib/lcd/nxglib_copyrectangle.c +++ b/graphics/nxglib/lcd/nxglib_copyrectangle.c @@ -81,7 +81,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_copyrectangle, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *dest, FAR const void *src, FAR const struct nxgl_point_s *origin, unsigned int srcstride) @@ -103,7 +103,7 @@ void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) /* Set up to copy the image */ xoffset = dest->pt1.x - origin->x; - sline = (const uint8_t*)src + NXGL_SCALEX(xoffset) + (dest->pt1.y - origin->y) * srcstride; + sline = (FAR const uint8_t *)src + NXGL_SCALEX(xoffset) + (dest->pt1.y - origin->y) * srcstride; #if NXGLIB_BITSPERPIXEL < 8 remainder = NXGL_REMAINDERX(xoffset); #endif @@ -119,7 +119,7 @@ void NXGL_FUNCNAME(nxgl_copyrectangle,NXGLIB_SUFFIX) if (remainder != 0) { - NXGL_FUNCNAME(nxgl_copyrun,NXGLIB_SUFFIX)(sline, pinfo->buffer, remainder, ncols); + NXGL_FUNCNAME(nxgl_copyrun, NXGLIB_SUFFIX)(sline, pinfo->buffer, remainder, ncols); (void)pinfo->putrun(row, dest->pt1.x, pinfo->buffer, ncols); } else diff --git a/graphics/nxglib/lcd/nxglib_fillrectangle.c b/graphics/nxglib/lcd/nxglib_fillrectangle.c index 6e0911713d141bc8c99206e960642b697491599e..6bc9a04fcb177cb8817840e7d708d2500082c276 100644 --- a/graphics/nxglib/lcd/nxglib_fillrectangle.c +++ b/graphics/nxglib/lcd/nxglib_fillrectangle.c @@ -84,7 +84,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_fillrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_fillrectangle, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect, NXGL_PIXEL_T color) @@ -98,7 +98,7 @@ void NXGL_FUNCNAME(nxgl_fillrectangle,NXGLIB_SUFFIX) /* Fill the run buffer with the selected color */ - NXGL_FUNCNAME(nxgl_fillrun,NXGLIB_SUFFIX)((NXGLIB_RUNTYPE*)pinfo->buffer, color, ncols); + NXGL_FUNCNAME(nxgl_fillrun, NXGLIB_SUFFIX)((NXGLIB_RUNTYPE *)pinfo->buffer, color, ncols); /* Then fill the rectangle line-by-line */ diff --git a/graphics/nxglib/lcd/nxglib_filltrapezoid.c b/graphics/nxglib/lcd/nxglib_filltrapezoid.c index df81971fb9f62e27834494ee50dc0490970d08f6..c88cae9542d87fab7822177b7c3a87b002897748 100644 --- a/graphics/nxglib/lcd/nxglib_filltrapezoid.c +++ b/graphics/nxglib/lcd/nxglib_filltrapezoid.c @@ -86,7 +86,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_filltrapezoid, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_trapezoid_s *trap, FAR const struct nxgl_rect_s *bounds, @@ -215,7 +215,7 @@ void NXGL_FUNCNAME(nxgl_filltrapezoid,NXGLIB_SUFFIX) ncols = botw; } - NXGL_FUNCNAME(nxgl_fillrun,NXGLIB_SUFFIX)((NXGLIB_RUNTYPE*)pinfo->buffer, color, ncols); + NXGL_FUNCNAME(nxgl_fillrun, NXGLIB_SUFFIX)((NXGLIB_RUNTYPE *)pinfo->buffer, color, ncols); /* Then fill the trapezoid row-by-row */ diff --git a/graphics/nxglib/lcd/nxglib_getrectangle.c b/graphics/nxglib/lcd/nxglib_getrectangle.c index 05bf78d666d765dd9b8d4ec26a178a78eb8beecd..1d6ecb5e60b6b72abc3ec4b5ea9cb9d7ae73c735 100644 --- a/graphics/nxglib/lcd/nxglib_getrectangle.c +++ b/graphics/nxglib/lcd/nxglib_getrectangle.c @@ -79,7 +79,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_getrectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_getrectangle, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect, FAR void *dest, unsigned int deststride) { diff --git a/graphics/nxglib/lcd/nxglib_moverectangle.c b/graphics/nxglib/lcd/nxglib_moverectangle.c index d634f2141c47f8302c54e1d0b2b7590fc9c6499b..02a84df098e43499b92b3d77eb55d04ba352590e 100644 --- a/graphics/nxglib/lcd/nxglib_moverectangle.c +++ b/graphics/nxglib/lcd/nxglib_moverectangle.c @@ -81,7 +81,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_moverectangle,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_moverectangle, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_rect_s *rect, FAR struct nxgl_point_s *offset) { diff --git a/graphics/nxglib/lcd/nxglib_setpixel.c b/graphics/nxglib/lcd/nxglib_setpixel.c index 46b637575bce9ce059510dcc3c1f38edacf5afb2..2af2c77a14ce7d58bd8769e465af0725b6189d0b 100644 --- a/graphics/nxglib/lcd/nxglib_setpixel.c +++ b/graphics/nxglib/lcd/nxglib_setpixel.c @@ -85,7 +85,7 @@ * ****************************************************************************/ -void NXGL_FUNCNAME(nxgl_setpixel,NXGLIB_SUFFIX) +void NXGL_FUNCNAME(nxgl_setpixel, NXGLIB_SUFFIX) (FAR struct lcd_planeinfo_s *pinfo, FAR const struct nxgl_point_s *pos, NXGL_PIXEL_T color) diff --git a/graphics/nxmu/nxmu_server.c b/graphics/nxmu/nxmu_server.c index eb7fbd75ca59b3f4b0cfbc1cf7cc9e4e6074ea5c..a5dad6ec40bef4a909b85d7d986ef386ae4ebc9a 100644 --- a/graphics/nxmu/nxmu_server.c +++ b/graphics/nxmu/nxmu_server.c @@ -192,7 +192,7 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, return ERROR; } -#if CONFIG_FB_CMAP +#ifdef CONFIG_FB_CMAP ret = nxbe_colormap(dev); if (ret < 0) { @@ -214,7 +214,7 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, attr.mq_msgsize = NX_MXSVRMSGLEN; attr.mq_flags = 0; - fe->conn.crdmq = mq_open(mqname, O_RDONLY|O_CREAT, 0666, &attr); + fe->conn.crdmq = mq_open(mqname, O_RDONLY | O_CREAT, 0666, &attr); if (fe->conn.crdmq == (mqd_t)-1) { gdbg("mq_open(%s) failed: %d\n", mqname, errno); @@ -245,7 +245,7 @@ static inline int nxmu_setup(FAR const char *mqname, FAR NX_DRIVERTYPE *dev, /* Initialize the non-NULL elements of the background window */ fe->be.bkgd.conn = &fe->conn; - fe->be.bkgd.be = (FAR struct nxbe_state_s*)fe; + fe->be.bkgd.be = (FAR struct nxbe_state_s *)fe; fe->be.bkgd.bounds.pt2.x = fe->be.vinfo.xres - 1; fe->be.bkgd.bounds.pt2.y = fe->be.vinfo.yres - 1; @@ -325,7 +325,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) /* Then loop forever processing incoming messages */ - for (;;) + for (; ; ) { /* Receive the next server message */ diff --git a/graphics/nxsu/nx_mousein.c b/graphics/nxsu/nx_mousein.c index 1b3027019cb5f908507140ecbdef70b9e3ec4361..374ba8041177978a018c915a4a28231f919f49f8 100644 --- a/graphics/nxsu/nx_mousein.c +++ b/graphics/nxsu/nx_mousein.c @@ -172,7 +172,7 @@ int nx_mousein(NXHANDLE handle, nxgl_coord_t x, nxgl_coord_t y, uint8_t buttons) y = g_mrange.y - 1; } - /* Look any change in values */ + /* Look any change in values */ if (x != g_mpos.x || y != g_mpos.y || buttons != g_mbutton) { diff --git a/graphics/nxsu/nx_open.c b/graphics/nxsu/nx_open.c index 5132b36e96e57bbde602cc3fe8d07928d46c226f..2c646c8b3e4a0d742ae697f9d03f28d238c3f713 100644 --- a/graphics/nxsu/nx_open.c +++ b/graphics/nxsu/nx_open.c @@ -125,7 +125,7 @@ static inline int nxsu_setup(FAR NX_DRIVERTYPE *dev, return ERROR; } -#if CONFIG_FB_CMAP +#ifdef CONFIG_FB_CMAP ret = nxbe_colormap(dev); if (ret < 0) { @@ -151,7 +151,7 @@ static inline int nxsu_setup(FAR NX_DRIVERTYPE *dev, fe->be.topwnd = &fe->be.bkgd; - /* Initialize the mouse position */ + /* Initialize the mouse position */ #ifdef CONFIG_NX_XYINPUT nxsu_mouseinit(fe->be.vinfo.xres, fe->be.vinfo.yres); diff --git a/graphics/nxterm/nxterm.h b/graphics/nxterm/nxterm.h index f94cd6f093a0e007ab46d62d63d423a17979ed9f..1a082e52837507a3ff44769bdad912a3b95a02e5 100644 --- a/graphics/nxterm/nxterm.h +++ b/graphics/nxterm/nxterm.h @@ -194,7 +194,7 @@ struct nxterm_state_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* This is the common NX driver file operations */ diff --git a/graphics/nxterm/nxterm_font.c b/graphics/nxterm/nxterm_font.c index 013deab581fdb95852cd50e04896f3fc27132540..fec6d5a443b28c30162f1f53e526100002c97f5d 100644 --- a/graphics/nxterm/nxterm_font.c +++ b/graphics/nxterm/nxterm_font.c @@ -311,7 +311,7 @@ nxterm_renderglyph(FAR struct nxterm_state_s *priv, /* Then render the glyph into the allocated memory */ - ret = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap, + ret = RENDERER((FAR nxgl_mxpixel_t *)glyph->bitmap, glyph->height, glyph->width, glyph->stride, fbm, priv->wndo.fcolor[0]); if (ret < 0) diff --git a/graphics/nxterm/nxterm_kbdin.c b/graphics/nxterm/nxterm_kbdin.c index 46c6e200beb03511be7281654aad6ad4bf331c39..395f6f759fbef57dc864deedab1ae069a5176b40 100644 --- a/graphics/nxterm/nxterm_kbdin.c +++ b/graphics/nxterm/nxterm_kbdin.c @@ -1,7 +1,7 @@ /**************************************************************************** * nuttx/graphics/nxterm/nxterm_kbdin.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,22 +46,12 @@ #include #include +#include + #include "nxterm.h" #ifdef CONFIG_NXTERM_NXKBDIN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -81,7 +71,7 @@ static void nxterm_pollnotify(FAR struct nxterm_state_s *priv, pollevent_t event for (i = 0; i < CONFIG_NXTERM_NPOLLWAITERS; i++) { - flags = irqsave(); + flags = enter_critical_section(); fds = priv->fds[i]; if (fds) { @@ -91,7 +81,8 @@ static void nxterm_pollnotify(FAR struct nxterm_state_s *priv, pollevent_t event sem_post(fds->sem); } } - irqrestore(flags); + + leave_critical_section(flags); } } #else @@ -418,14 +409,14 @@ void nxterm_kbdin(NXTERM handle, FAR const uint8_t *buffer, uint8_t buflen) return; } - /* Loop until all of the bytes have been written. This function may be - * called from an interrupt handler! Semaphores cannot be used! - * - * The write logic only needs to modify the head index. Therefore, - * there is a difference in the way that head and tail are protected: - * tail is protected with a semaphore; tail is protected by disabling - * interrupts. - */ + /* Loop until all of the bytes have been written. This function may be + * called from an interrupt handler! Semaphores cannot be used! + * + * The write logic only needs to modify the head index. Therefore, + * there is a difference in the way that head and tail are protected: + * tail is protected with a semaphore; tail is protected by disabling + * interrupts. + */ for (nwritten = 0; nwritten < buflen; nwritten++) { diff --git a/graphics/nxterm/nxterm_register.c b/graphics/nxterm/nxterm_register.c index 6a49e641cf64cedc65d9cc89773cd52bf8df5f1c..a0751773d7a77e1fe65b3263289b523e66f78ec1 100644 --- a/graphics/nxterm/nxterm_register.c +++ b/graphics/nxterm/nxterm_register.c @@ -96,7 +96,7 @@ FAR struct nxterm_state_s * priv->ops = ops; priv->handle = handle; priv->minor = minor; - memcpy(&priv->wndo, wndo, sizeof( struct nxterm_window_s)); + memcpy(&priv->wndo, wndo, sizeof(struct nxterm_window_s)); sem_init(&priv->exclsem, 0, 1); #ifdef CONFIG_DEBUG diff --git a/graphics/nxterm/nxterm_scroll.c b/graphics/nxterm/nxterm_scroll.c index 9d1827606fb2a57055dcc675dfbba2e272381087..38e9f5cb6bfe7cb8619b213f0f740f96a0b2aa98 100644 --- a/graphics/nxterm/nxterm_scroll.c +++ b/graphics/nxterm/nxterm_scroll.c @@ -136,7 +136,7 @@ static inline void nxterm_movedisplay(FAR struct nxterm_state_s *priv, /* Finally, clear the vacated part of the display */ rect.pt1.y = bottom; - rect.pt2.y = priv->wndo.wsize.h- 1; + rect.pt2.y = priv->wndo.wsize.h - 1; ret = priv->ops->fill(priv, &rect, priv->wndo.wcolor); if (ret < 0) diff --git a/include/cxx/cmath b/include/cxx/cmath index b30d5548b7ce4f33c66d034fe606373a3da87766..998406c153439a8577ceab27e8c71aa2e4dbb779 100644 --- a/include/cxx/cmath +++ b/include/cxx/cmath @@ -51,7 +51,7 @@ namespace std { -#if CONFIG_HAVE_FLOAT +#ifdef CONFIG_HAVE_FLOAT using ::acosf; using ::asinf; using ::atanf; @@ -78,7 +78,7 @@ namespace std using ::tanhf; #endif -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE using ::acos; using ::asin; using ::atan; diff --git a/include/cxx/csched b/include/cxx/csched index 262782888cd7c1cc375e2535501e0dd3515ce6e1..f320a82a11cb94524ad2fc6eaa5e88bdbcc6a962 100644 --- a/include/cxx/csched +++ b/include/cxx/csched @@ -64,11 +64,6 @@ namespace std using ::sched_lock; using ::sched_unlock; using ::sched_lockcount; -#ifdef CONFIG_SCHED_INSTRUMENTATION - using ::sched_note_start; - using ::sched_note_stop; - using ::sched_note_switch; -#endif } #endif // __INCLUDE_CXX_CSCHED diff --git a/include/cxx/cstdio b/include/cxx/cstdio index e2de1c23f3353b7e7e817c4e7cca2620a78916d2..0074091a2f7a057fb33146a689161c353801028b 100644 --- a/include/cxx/cstdio +++ b/include/cxx/cstdio @@ -91,7 +91,7 @@ namespace std using ::vprintf; using ::vfprintf; using ::vsprintf; - using ::avsprintf; + using ::vasprintf; using ::vsnprintf; using ::vsscanf; diff --git a/include/cxx/cstdlib b/include/cxx/cstdlib index 790996a8eacfc04c530d24a74ea399164ed39f90..419291c789b2135fbc18f0cc579945471a785435 100644 --- a/include/cxx/cstdlib +++ b/include/cxx/cstdlib @@ -1,7 +1,7 @@ //*************************************************************************** // include/cxx/cstdlib // -// Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. +// Copyright (C) 2009, 2012, 2015 Gregory Nutt. All rights reserved. // Author: Gregory Nutt // // Redistribution and use in source and binary forms, with or without @@ -100,15 +100,29 @@ namespace std using ::calloc; using ::mallinfo; - // Misc. + // Arithmetic using ::abs; using ::labs; #ifdef CONFIG_HAVE_LONG_LONG using ::llabs; #endif + +#ifdef CONFIG_CAN_PASS_STRUCTS + using ::div; + using ::ldiv; +#ifdef CONFIG_HAVE_LONG_LONG + using ::lldiv; +#endif +#endif + + // Temporary files + using ::mktemp; using ::mkstemp; + + // Sorting + using ::qsort; } diff --git a/include/debug.h b/include/debug.h index 10ef6889e916a9d99752a6bec97d479ab398ef90..066ba5a2d6bf9fef285348dbb1818292704629ea 100644 --- a/include/debug.h +++ b/include/debug.h @@ -43,6 +43,10 @@ #include #include +#ifdef CONFIG_ARCH_DEBUG_H +# include +#endif + #include /**************************************************************************** @@ -94,6 +98,15 @@ # define EXTRA_ARG #endif +/* The actual logger function may be overridden in arch/debug.h if needed. */ + +#ifndef __arch_syslog +# define __arch_syslog syslog +#endif +#ifndef __arch_lowsyslog +# define __arch_lowsyslog lowsyslog +#endif + /* Debug macros will differ depending upon if the toolchain supports * macros with a variable number of arguments or not. */ @@ -104,30 +117,30 @@ #ifdef CONFIG_DEBUG # define dbg(format, ...) \ - syslog(LOG_ERR, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) + __arch_syslog(LOG_ERR, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) # ifdef CONFIG_ARCH_LOWPUTC # define lldbg(format, ...) \ - lowsyslog(LOG_ERR, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) + __arch_lowsyslog(LOG_ERR, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) # else # define lldbg(x...) # endif # ifdef CONFIG_DEBUG_VERBOSE # define vdbg(format, ...) \ - syslog(LOG_DEBUG, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) + __arch_syslog(LOG_DEBUG, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) # ifdef CONFIG_ARCH_LOWPUTC # define llvdbg(format, ...) \ - lowsyslog(LOG_DEBUG, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) + __arch_lowsyslog(LOG_DEBUG, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__) # else # define llvdbg(x...) # endif -# else +# else /* CONFIG_DEBUG_VERBOSE */ # define vdbg(x...) # define llvdbg(x...) -# endif +# endif /* CONFIG_DEBUG_VERBOSE */ #else /* CONFIG_DEBUG */ @@ -644,7 +657,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/dirent.h b/include/dirent.h index 82381189c41f61f8d163e319862578d55ec6570d..ea6b18a142acc6197e3fd695ac276b418485403e 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -83,7 +83,7 @@ struct dirent typedef void DIR; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/errno.h b/include/errno.h index f215269c731beb66be29493b6a1c83f876f2d7fe..d6d4ec8e191ab6a12f04838f3f4aef774a18f103 100644 --- a/include/errno.h +++ b/include/errno.h @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * include/errno.h * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. @@ -31,20 +31,20 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ #ifndef __INCLUDE_ERRNO_H #define __INCLUDE_ERRNO_H -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ /* How can we access the errno variable? */ #if !defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_BUILD_KERNEL) @@ -378,13 +378,13 @@ #define ECANCELED 125 #define ECANCELED_STR "Operation cancelled" -/************************************************************************ +/**************************************************************************** * Public Type Definitions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Function Prototypes - ************************************************************************/ + ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) diff --git a/include/fcntl.h b/include/fcntl.h index 6bec04f0acfc8a926d616bb9390745ddd6c00c9e..6145c11fd6becb9f6d0631060a221ae8f33a3b48 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -102,7 +102,7 @@ #define F_GETSIG 6 /* Get the signal sent */ #define F_NOTIFY 7 /* Provide notification when directory referred to by fd changes (linux)*/ #define F_SETFD 8 /* Set the file descriptor flags to value */ -#define F_SETFL 9 /* Set the file status flags to the value */ +#define F_SETFL 9 /* Set the file status flags to the value */ #define F_SETLEASE 10 /* Set or remove file lease (linux) */ #define F_SETLK 11 /* Acquire or release a lock on range of bytes */ #define F_SETLKW 12 /* Like F_SETLK, but wait for lock to become available */ diff --git a/include/fixedmath.h b/include/fixedmath.h index 38a991136bf32abf60a418c73cddcb5c08b71234..665179c4271f5f593be82b9f611d3c774cf1f997 100644 --- a/include/fixedmath.h +++ b/include/fixedmath.h @@ -42,9 +42,9 @@ #include -/************************************************************************** +/**************************************************************************** * Pre-processor Definitions - **************************************************************************/ + ****************************************************************************/ /* Common numbers */ @@ -191,9 +191,9 @@ # define ub16divub16(a,b) (ub16_t)(ub16toub32(a)/(ub32_t)(b)) #endif -/************************************************************************** +/**************************************************************************** * Public Types - **************************************************************************/ + ****************************************************************************/ typedef int16_t b8_t; typedef uint16_t ub8_t; @@ -204,9 +204,9 @@ typedef int64_t b32_t; typedef uint64_t ub32_t; #endif -/************************************************************************** +/**************************************************************************** * Public Functions - **************************************************************************/ + ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/analog/adc.h b/include/nuttx/analog/adc.h index 3d5aa1fb067fac482c1f7f77e83a5ff1db741ecc..04db97626cf078470d4c5092656e63455eda59af 100644 --- a/include/nuttx/analog/adc.h +++ b/include/nuttx/analog/adc.h @@ -139,13 +139,13 @@ struct adc_ops_s struct adc_dev_s { - uint8_t ad_ocount; /* The number of times the device has been opened */ - uint8_t ad_nrxwaiters; /* Number of threads waiting to enqueue a message */ - sem_t ad_closesem; /* Locks out new opens while close is in progress */ - sem_t ad_recvsem; /* Used to wakeup user waiting for space in ad_recv.buffer */ - struct adc_fifo_s ad_recv; /* Describes receive FIFO */ - const struct adc_ops_s *ad_ops; /* Arch-specific operations */ - void *ad_priv; /* Used by the arch-specific logic */ + uint8_t ad_ocount; /* The number of times the device has been opened */ + uint8_t ad_nrxwaiters; /* Number of threads waiting to enqueue a message */ + sem_t ad_closesem; /* Locks out new opens while close is in progress */ + sem_t ad_recvsem; /* Used to wakeup user waiting for space in ad_recv.buffer */ + struct adc_fifo_s ad_recv; /* Describes receive FIFO */ + FAR const struct adc_ops_s *ad_ops; /* Arch-specific operations */ + FAR void *ad_priv; /* Used by the arch-specific logic */ }; /************************************************************************************ diff --git a/include/nuttx/analog/ads1242.h b/include/nuttx/analog/ads1242.h new file mode 100644 index 0000000000000000000000000000000000000000..b74b2a28b264e581e6c9fe48f09342575d9b6fb5 --- /dev/null +++ b/include/nuttx/analog/ads1242.h @@ -0,0 +1,202 @@ +/**************************************************************************** + * include/nuttx/sensors/ads1242.h + * + * Copyright (C) 2016, DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * 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 NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_ +#define NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#if defined(CONFIG_SPI) && defined(CONFIG_ADC_ADS1242) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IOCTL Commands ***********************************************************/ + +#define ANIOC_ADS2142_READ _ANIOC(0x0001) /* Arg: uint32_t *value */ +#define ANIOC_ADS2142_SET_GAIN _ANIOC(0x0002) /* Arg: uint8_t value */ +#define ANIOC_ADS2142_SET_POSITIVE_INPUT _ANIOC(0x0003) /* Arg: uint8_t value */ +#define ANIOC_ADS2142_SET_NEGATIVE_INPUT _ANIOC(0x0004) /* Arg: uint8_t value */ +#define ANIOC_ADS2142_IS_DATA_READY _ANIOC(0x0005) /* Arg: bool *value */ +#define ANIOC_ADS2142_DO_SYSTEM_OFFSET_CALIB _ANIOC(0x0006) /* Arg: None */ + +/* ADS1242 REGISTER *********************************************************/ + +#define ADS1242_REG_SETUP (0x00) /* Setup Register */ +#define ADS1242_REG_MUX (0x01) /* Multiplexer Control Register */ +#define ADS1242_REG_ACR (0x02) /* Analog Control Register */ +#define ADS1242_REG_ODAC (0x03) /* Offset DAC */ +#define ADS1242_REG_DIO (0x04) /* Data I/O */ +#define ADS1242_REG_DIR (0x05) /* Direction Control for Data I/O */ +#define ADS1242_REG_IOCON (0x06) /* I/O Configuration Register */ + +/* ADS1242 REGISTER Bit Definitions *****************************************/ + +/* SETUP */ +#define ADS1242_REG_SETUP_BIT_BOCS (1 << 3) +#define ADS1242_REG_SETUP_BIT_PGA2 (1 << 2) +#define ADS1242_REG_SETUP_BIT_PGA1 (1 << 1) +#define ADS1242_REG_SETUP_BIT_PGA0 (1 << 0) +/* MUX */ +#define ADS1242_REG_MUX_BIT_PSEL3 (1 << 7) +#define ADS1242_REG_MUX_BIT_PSEL2 (1 << 6) +#define ADS1242_REG_MUX_BIT_PSEL1 (1 << 5) +#define ADS1242_REG_MUX_BIT_PSEL0 (1 << 4) +#define ADS1242_REG_MUX_BIT_NSEL3 (1 << 3) +#define ADS1242_REG_MUX_BIT_NSEL2 (1 << 2) +#define ADS1242_REG_MUX_BIT_NSEL1 (1 << 1) +#define ADS1242_REG_MUX_BIT_NSEL0 (1 << 0) +/* ACR */ +#define ADS1242_REG_ACR_BIT_nDRDY (1 << 7) +#define ADS1242_REG_ACR_BIT_UnB (1 << 6) +#define ADS1242_REG_ACR_BIT_SPEED (1 << 5) +#define ADS1242_REG_ACR_BIT_BUFEN (1 << 4) +#define ADS1242_REG_ACR_BIT_BITORDER (1 << 3) +#define ADS1242_REG_ACR_BIT_RANGE (1 << 2) +#define ADS1242_REG_ACR_BIT_DR1 (1 << 1) +#define ADS1242_REG_ACR_BIT_DR0 (1 << 0) + +/* ADS1242 SPI COMMANDS *****************************************************/ + +#define ADS1242_CMD_READ_DATA (0x01) +#define ADS1242_CMD_READ_REGISTER (0x10) +#define ADS1242_CMD_WRITE_REGISTER (0x50) +#define ADS1242_CMD_SELF_OFFSET_CALIB (0xF1) +#define ADS1242_CMD_SELF_GAIN_CALIB (0xf2) +#define ADS1242_CMD_SYSTEM_OFFSET_CALIB (0xf3) +#define ADS1242_CMD_RESET (0xfe) + +/* SPI BUS PARAMETERS *******************************************************/ + +/* 100 kHz, SCLK period has to be at least 4 x tOsc period of ADS1242 + * oscillator circuit. + */ + +#define ADS1242_SPI_FREQUENCY (100000) + +/* Device uses SPI Mode 1: CKPOL = 0, CKPHA = 1 */ + +#define ADS1242_SPI_MODE (SPIDEV_MODE1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef enum +{ + ADS1242_x1 = 0, + ADS1242_x2 = ADS1242_REG_SETUP_BIT_PGA0, + ADS1242_x4 = ADS1242_REG_SETUP_BIT_PGA1, + ADS1242_x8 = ADS1242_REG_SETUP_BIT_PGA1 | ADS1242_REG_SETUP_BIT_PGA0, + ADS1242_x16 = ADS1242_REG_SETUP_BIT_PGA2, + ADS1242_x32 = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA0, + ADS1242_x64 = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA1, + ADS1242_x128 = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA1 | + ADS1242_REG_SETUP_BIT_PGA0 +} ADS1242_GAIN_SELECTION; + +typedef enum +{ + ADS1242_P_AIN0 = 0, + ADS1242_P_AIN1 = ADS1242_REG_MUX_BIT_PSEL0, + ADS1242_P_AIN2 = ADS1242_REG_MUX_BIT_PSEL1, + ADS1242_P_AIN3 = ADS1242_REG_MUX_BIT_PSEL1 | ADS1242_REG_MUX_BIT_PSEL0, + ADS1242_P_AIN4 = ADS1242_REG_MUX_BIT_PSEL2, + ADS1242_P_AIN5 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL0, + ADS1242_P_AIN6 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL1, + ADS1242_P_AIN7 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL1 | + ADS1242_REG_MUX_BIT_PSEL0, +} ADS1242_POSITIVE_INPUT_SELECTION; + +typedef enum +{ + ADS1242_N_AIN0 = 0, + ADS1242_N_AIN1 = ADS1242_REG_MUX_BIT_NSEL0, + ADS1242_N_AIN2 = ADS1242_REG_MUX_BIT_NSEL1, + ADS1242_N_AIN3 = ADS1242_REG_MUX_BIT_NSEL1 | ADS1242_REG_MUX_BIT_NSEL0, + ADS1242_N_AIN4 = ADS1242_REG_MUX_BIT_NSEL2, + ADS1242_N_AIN5 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL0, + ADS1242_N_AIN6 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL1, + ADS1242_N_AIN7 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL1 | + ADS1242_REG_MUX_BIT_NSEL0, +} ADS1242_NEGATIVE_INPUT_SELECTION; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: ads1242_register + * + * Description: + * Register the ADS1242 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/ads1242" + * spi - An instance of the SPI interface to use to communicate with ADS1242 + * osc_freq_hz - The frequency of the ADS1242 oscillator in Hz. Required for + * calculating the minimum delay periods when accessing the device via SPI. + * + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ads1242_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + uint32_t const osc_freq_hz); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_SPI && CONFIG_ADC_ADS1242 */ +#endif /* NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_ */ diff --git a/include/nuttx/analog/pga11x.h b/include/nuttx/analog/pga11x.h index 9a74e09f0eedbf220ef0c5f17cb827cfe733dfbf..7b6cf7881c3457a020b6f7fb4271315401b87541 100644 --- a/include/nuttx/analog/pga11x.h +++ b/include/nuttx/analog/pga11x.h @@ -73,8 +73,6 @@ * When SPI_SELECT is called with devid=SPIDEV_MUX. * * Other settings that effect the driver: - * CONFIG_SPI_OWNBUS -- If the PGA117 is enabled, this must be set to 'y' - * if the PGA117 is the only device on the SPI bus; * CONFIG_DEBUG_SPI -- With CONFIG_DEBUG and CONFIG_DEBUG_VERBOSE, * this will enable debug output from the PGA117 driver. */ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 5f615cd51eea32bda6f7e639852a8c8c8e1d64e9..da9296af2d0953d5713e6a74d76e8f4eecd4203b 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/arch.h * - * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -101,11 +101,14 @@ #include -#include #include #include #include +#if defined(CONFIG_ELF) || defined(CONFIG_MODULE) +# include +#endif + #include /**************************************************************************** @@ -120,7 +123,7 @@ typedef CODE void (*sig_deliver_t)(FAR struct tcb_s *tcb); typedef CODE void (*phy_enable_t)(bool enable); /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -1251,6 +1254,80 @@ int up_shmat(FAR uintptr_t *pages, unsigned int npages, uintptr_t vaddr); int up_shmdt(uintptr_t vaddr, unsigned int npages); #endif +/**************************************************************************** + * Interfaces required for ELF module support + ****************************************************************************/ +/**************************************************************************** + * Name: up_checkarch + * + * Description: + * Given the ELF header in 'hdr', verify that the module is appropriate + * for the current, configured architecture. Every architecture that uses + * the module loader must provide this function. + * + * Input Parameters: + * hdr - The ELF header read from the module file. + * + * Returned Value: + * True if the architecture supports this module file. + * + ****************************************************************************/ + +#if defined(CONFIG_ELF) || defined(CONFIG_MODULE) +bool up_checkarch(FAR const Elf32_Ehdr *hdr); +#endif + +/**************************************************************************** + * Name: up_relocate and up_relocateadd + * + * Description: + * Perform on architecture-specific ELF relocation. Every architecture + * that uses the module loader must provide this function. + * + * Input Parameters: + * rel - The relocation type + * sym - The ELF symbol structure containing the fully resolved value. + * There are a few relocation types for a few architectures that do + * not require symbol information. For those, this value will be + * NULL. Implementations of these functions must be able to handle + * that case. + * addr - The address that requires the relocation. + * + * Returned Value: + * Zero (OK) if the relocation was successful. Otherwise, a negated errno + * value indicating the cause of the relocation failure. + * + ****************************************************************************/ + +#if defined(CONFIG_ELF) || defined(CONFIG_MODULE) +int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, + uintptr_t addr); +int up_relocateadd(FAR const Elf32_Rela *rel, + FAR const Elf32_Sym *sym, uintptr_t addr); +#endif + +/**************************************************************************** + * Name: up_coherent_dcache + * + * Description: + * Ensure that the I and D caches are coherent within specified region + * by cleaning the D cache (i.e., flushing the D cache contents to memory + * and invalidating the I cache. This is typically used when code has been + * written to a memory region, and will be executed. + * + * Input Parameters: + * addr - virtual start address of region + * len - Size of the address region in bytes + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_COHERENT_DCACHE +void up_coherent_dcache(uintptr_t addr, size_t len); +#endif + /**************************************************************************** * Name: up_interrupt_context * @@ -1273,7 +1350,7 @@ bool up_interrupt_context(void); * * This function implements enabling of the device specified by 'irq' * at the interrupt controller level if supported by the architecture - * (irqrestore() supports the global level, the device level is hardware + * (up_irq_restore() supports the global level, the device level is hardware * specific). * * Since this API is not supported on all architectures, it should be @@ -1291,7 +1368,7 @@ void up_enable_irq(int irq); * Description: * This function implements disabling of the device specified by 'irq' * at the interrupt controller level if supported by the architecture - * (irqsave() supports the global level, the device level is hardware + * (up_irq_save() supports the global level, the device level is hardware * specific). * * Since this API is not supported on all architectures, it should be @@ -1558,6 +1635,193 @@ int up_timer_cancel(FAR struct timespec *ts); int up_timer_start(FAR const struct timespec *ts); #endif +/**************************************************************************** + * TLS support + ****************************************************************************/ + +/**************************************************************************** + * Name: up_tls_info + * + * Description: + * Return the TLS information structure for the currently executing thread. + * When TLS is enabled, up_createstack() will align allocated stacks to + * the TLS_STACK_ALIGN value. An instance of the following structure will + * be implicitly positioned at the "lower" end of the stack. Assuming a + * "push down" stack, this is at the "far" end of the stack (and can be + * clobbered if the stack overflows). + * + * If an MCU has a "push up" then that TLS structure will lie at the top + * of the stack and stack allocation and initialization logic must take + * care to preserve this structure content. + * + * The stack memory is fully accessible to user mode threads. + * + * Input Parameters: + * None + * + * Returned Value: + * A pointer to TLS info structure at the beginning of the STACK memory + * allocation. This is essentially an application of the TLS_INFO(sp) + * macro and has a platform dependency only in the manner in which the + * stack pointer (sp) is obtained and interpreted. + * + ****************************************************************************/ + +#ifdef CONFIG_TLS +/* struct tls_info_s; + * FAR struct tls_info_s *up_tls_info(void); + * + * The actual declaration or definition is provided in arch/tls.h. The + * actual implementation may be a MACRO or and inline function. + */ +#endif + +/**************************************************************************** + * Multiple CPU support + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * was previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + +/* See prototype in include/nuttx/spinlock.h */ + +/**************************************************************************** + * Name: up_cpu_index + * + * Description: + * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + * Input Parameters: + * None + * + * Returned Value: + * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that + * corresponds to the currently executing CPU. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_index(void); +#else +# define up_cpu_index() (0) +#endif + +/**************************************************************************** + * Name: up_cpu_start + * + * Description: + * In an SMP configution, only one CPU is initially active (CPU 0). System + * initialization occurs on that single thread. At the completion of the + * initialization of the OS, just before beginning normal multitasking, + * the additional CPUs would be started by calling this function. + * + * Each CPU is provided the entry point to is IDLE task when started. A + * TCB for each CPU's IDLE task has been initialized and placed in the + * CPU's g_assignedtasks[cpu] list. A stack has also been allocateded and + * initialized. + * + * The OS initialization logic calls this function repeatedly until each + * CPU has been started, 1 through (CONFIG_SMP_NCPUS-1). + * + * Input Parameters: + * cpu - The index of the CPU being started. This will be a numeric + * value in the range of from one to (CONFIG_SMP_NCPUS-1). (CPU + * 0 is already active) + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_start(int cpu); +#endif + +/**************************************************************************** + * Name: up_cpu_initialize + * + * Description: + * After the CPU has been started (via up_cpu_start()) the system will + * call back into the architecture-specific code with this function on the + * thread of execution of the newly started CPU. This gives the + * architecture-specific a chance to perform ny initial, CPU-specific + * initialize on that thread. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_initialize(void); +#endif + +/**************************************************************************** + * Name: up_cpu_pause + * + * Description: + * Save the state of the current task at the head of the + * g_assignedtasks[cpu] task list and then pause task execution on the + * CPU. + * + * This function is called by the OS when the logic executing on one CPU + * needs to modify the state of the g_assignedtasks[cpu] list for another + * CPU. + * + * Input Parameters: + * cpu - The index of the CPU to be paused. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_pause(int cpu); +#endif + +/**************************************************************************** + * Name: up_cpu_resume + * + * Description: + * Restart the cpu after it was paused via up_cpu_pause(), restoring the + * state of the task at the head of the g_assignedtasks[cpu] list, and + * resume normal tasking. + * + * This function is called after up_cpu_pause in order resume operation of + * the CPU after modifying its g_assignedtasks[cpu] list. + * + * Input Parameters: + * cpu - The index of the CPU being resumed. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int up_cpu_resume(int cpu); +#endif + /**************************************************************************** * Name: up_romgetc * @@ -1604,7 +1868,7 @@ char up_romgetc(FAR const char *ptr); * Some device drivers may require that the plaform-specific logic * provide these timing loops for short delays. * - ***************************************************************************/ + ****************************************************************************/ void up_mdelay(unsigned int milliseconds); void up_udelay(useconds_t microseconds); @@ -1623,7 +1887,7 @@ void up_udelay(useconds_t microseconds); * definition only provides the 'contract' between application * specific C++ code and platform-specific toolchain support * - ***************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) void up_cxxinitialize(void); @@ -1698,7 +1962,7 @@ void sched_timer_expiration(void); void sched_alarm_expiration(FAR const struct timespec *ts); #endif -/************************************************************************ +/**************************************************************************** * Name: sched_process_cpuload * * Description: @@ -1714,7 +1978,7 @@ void sched_alarm_expiration(FAR const struct timespec *ts); * This function is called from a timer interrupt handler with all * interrupts disabled. * - ************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_SCHED_CPULOAD) && defined(CONFIG_SCHED_CPULOAD_EXTCLK) void weak_function sched_process_cpuload(void); @@ -1728,7 +1992,7 @@ void weak_function sched_process_cpuload(void); * order to dispatch an interrupt to the appropriate, registered handling * logic. * - ***************************************************************************/ + ****************************************************************************/ void irq_dispatch(int irq, FAR void *context); @@ -1765,11 +2029,17 @@ size_t up_check_intstack_remain(void); ****************************************************************************/ /**************************************************************************** - * Name: up_rtcinitialize + * Name: up_rtc_initialize * * Description: - * Initialize the hardware RTC per the selected configuration. This - * function is called once during the OS initialization sequence + * Initialize the builtin, MCU hardware RTC per the selected + * configuration. This function is called once very early in the OS + * initialization sequence. + * + * NOTE that initialization of external RTC hardware that depends on the + * availability of OS resources (such as SPI or I2C) must be deferred + * until the system has fully booted. Other, RTC-specific initialization + * functions are used in that case. * * Input Parameters: * None @@ -1779,8 +2049,8 @@ size_t up_check_intstack_remain(void); * ****************************************************************************/ -#ifdef CONFIG_RTC -int up_rtcinitialize(void); +#if defined(CONFIG_RTC) && !defined(CONFIG_RTC_EXTERNAL) +int up_rtc_initialize(void); #endif /************************************************************************************ @@ -1797,7 +2067,7 @@ int up_rtcinitialize(void); * None * * Returned Value: - * The current time in seconds + * The current time in seconds. * ************************************************************************************/ @@ -1817,7 +2087,7 @@ time_t up_rtc_time(void); * tp - The location to return the high resolution time value. * * Returned Value: - * Zero (OK) on success; a negated errno on failure + * Zero (OK) on success; a negated errno value on failure. * ************************************************************************************/ @@ -1844,7 +2114,7 @@ int up_rtc_gettime(FAR struct timespec *tp); * tp - The location to return the high resolution time value. * * Returned Value: - * Zero (OK) on success; a negated errno on failure + * Zero (OK) on success; a negated errno value on failure. * ************************************************************************************/ @@ -1863,7 +2133,7 @@ int up_rtc_getdatetime(FAR struct tm *tp); * tp - the time to use * * Returned Value: - * Zero (OK) on success; a negated errno on failure + * Zero (OK) on success; a negated errno value on failure. * ************************************************************************************/ diff --git a/include/nuttx/audio/audio.h b/include/nuttx/audio/audio.h index 9799e004e551d04a60a5f21a1d522663c508bda3..323c4dd696f2742464f7674c5073ae70302aa4ba 100644 --- a/include/nuttx/audio/audio.h +++ b/include/nuttx/audio/audio.h @@ -130,7 +130,7 @@ */ #define AUDIO_TYPE_QUERY 0x00 -#define AUDIO_TYPE_INPUT 0x02 +#define AUDIO_TYPE_INPUT 0x01 #define AUDIO_TYPE_OUTPUT 0x02 #define AUDIO_TYPE_MIXER 0x04 #define AUDIO_TYPE_SELECTOR 0x08 diff --git a/include/nuttx/audio/wm8904.h b/include/nuttx/audio/wm8904.h index 6536d778905366cbd77d636896e1800fd16d33e3..5b2bd7e54912d73a7476e2fe9bf2c2af27e09346 100644 --- a/include/nuttx/audio/wm8904.h +++ b/include/nuttx/audio/wm8904.h @@ -84,10 +84,6 @@ # error CONFIG_I2C is required by the WM8904 driver #endif -#ifndef CONFIG_I2C_TRANSFER -# error CONFIG_I2C_TRANSFER is required in the I2C configuration -#endif - #ifndef CONFIG_SCHED_WORKQUEUE # error CONFIG_SCHED_WORKQUEUE is required by the WM8904 driver #endif @@ -214,12 +210,12 @@ extern "C" * ****************************************************************************/ -struct i2c_dev_s; /* Forward reference. Defined in include/nuttx/i2c.h */ +struct i2c_master_s; /* Forward reference. Defined in include/nuttx/i2c/i2c_master.h */ struct i2s_dev_s; /* Forward reference. Defined in include/nuttx/audio/i2s.h */ struct audio_lowerhalf_s; /* Forward reference. Defined in nuttx/audio/audio.h */ FAR struct audio_lowerhalf_s * - wm8904_initialize(FAR struct i2c_dev_s *i2c, FAR struct i2s_dev_s *i2s, + wm8904_initialize(FAR struct i2c_master_s *i2c, FAR struct i2s_dev_s *i2s, FAR const struct wm8904_lower_s *lower); /**************************************************************************** diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h index ed42499356b0b2f5c169f9fcfd5fd773ad5d75ca..f687bbd071a6bba1797846842d6d3865912001d7 100644 --- a/include/nuttx/binfmt/elf.h +++ b/include/nuttx/binfmt/elf.h @@ -48,6 +48,7 @@ #include #include +#include #include /**************************************************************************** @@ -86,7 +87,7 @@ * Public Types ****************************************************************************/ -/* This struct provides a desciption of the currently loaded instantiation +/* This struct provides a description of the currently loaded instantiation * of an ELF binary. */ @@ -271,96 +272,6 @@ int elf_initialize(void); void elf_uninitialize(void); -/**************************************************************************** - * These are APIs must be provided by architecture-specific logic. - * (These really belong in include/nuttx/arch.h): - ****************************************************************************/ -/**************************************************************************** - * Name: up_checkarch - * - * Description: - * Given the ELF header in 'hdr', verify that the ELF file is appropriate - * for the current, configured architecture. Every architecture that uses - * the ELF loader must provide this function. - * - * Input Parameters: - * hdr - The ELF header read from the ELF file. - * - * Returned Value: - * True if the architecture supports this ELF file. - * - ****************************************************************************/ - -bool up_checkarch(FAR const Elf32_Ehdr *hdr); - -/**************************************************************************** - * Name: up_relocate and up_relocateadd - * - * Description: - * Perform on architecture-specific ELF relocation. Every architecture - * that uses the ELF loader must provide this function. - * - * Input Parameters: - * rel - The relocation type - * sym - The ELF symbol structure containing the fully resolved value. - * There are a few relocation types for a few architectures that do - * not require symbol information. For those, this value will be - * NULL. Implementations of these functions must be able to handle - * that case. - * addr - The address that requires the relocation. - * - * Returned Value: - * Zero (OK) if the relocation was successful. Otherwise, a negated errno - * value indicating the cause of the relocation failure. - * - ****************************************************************************/ - -int up_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym, - uintptr_t addr); -int up_relocateadd(FAR const Elf32_Rela *rel, - FAR const Elf32_Sym *sym, uintptr_t addr); - -#ifdef CONFIG_UCLIBCXX_EXCEPTION -/**************************************************************************** - * Name: up_init_exidx - * - * Description: - * Load the boundaries of the Exception Index ELF section in order to - * support exception handling for loaded ELF modules. - * - * Input Parameters: - * address - The ELF section address for the Exception Index - * size - The size of the ELF section. - * - * Returned Value: - * Always returns Zero (OK). - * - ****************************************************************************/ -int up_init_exidx(Elf32_Addr address, Elf32_Word size); -#endif - -/**************************************************************************** - * Name: up_coherent_dcache - * - * Description: - * Ensure that the I and D caches are coherent within specified region - * by cleaning the D cache (i.e., flushing the D cache contents to memory - * and invalidating the I cache. This is typically used when code has been - * written to a memory region, and will be executed. - * - * Input Parameters: - * addr - virtual start address of region - * len - Size of the address region in bytes - * - * Returned Value: - * None - * - ****************************************************************************/ - -#ifdef CONFIG_ARCH_HAVE_COHERENT_DCACHE -void up_coherent_dcache(uintptr_t addr, size_t len); -#endif - #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/binfmt/nxflat.h b/include/nuttx/binfmt/nxflat.h index 8e661115b001a2edf84cf51c4b278a66f12d1e7a..31b173209eb887cc928970fc24f5b783c347453a 100644 --- a/include/nuttx/binfmt/nxflat.h +++ b/include/nuttx/binfmt/nxflat.h @@ -56,7 +56,7 @@ * Public Types ****************************************************************************/ -/* This struct provides a desciption of the currently loaded instantiation +/* This struct provides a description of the currently loaded instantiation * of an nxflat binary. */ @@ -249,7 +249,7 @@ int nxflat_unload(struct nxflat_loadinfo_s *loadinfo); /**************************************************************************** * These are APIs used internally only by NuttX: ****************************************************************************/ -/*********************************************************************** +/**************************************************************************** * Name: nxflat_initialize * * Description: @@ -262,7 +262,7 @@ int nxflat_unload(struct nxflat_loadinfo_s *loadinfo); * 0 (OK) is returned on success and a negated errno is returned on * failure. * - ***********************************************************************/ + ****************************************************************************/ int nxflat_initialize(void); diff --git a/include/nuttx/binfmt/symtab.h b/include/nuttx/binfmt/symtab.h index c6cdeffe44418ccf3c6efb70cca238cb4ea48ff2..9e51ca35398cf0a1f07442442d46236163dfc3a1 100644 --- a/include/nuttx/binfmt/symtab.h +++ b/include/nuttx/binfmt/symtab.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/binfmt/symtab.h * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,34 +41,7 @@ ****************************************************************************/ #include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* struct symbtab_s describes one entry in the symbol table. A symbol table - * is a fixed size array of struct symtab_s. The information is intentionally - * minimal and supports only: - * - * 1. Function pointers as sym_values. Of other kinds of values need to be - * supported, then typing information would also need to be included in - * the structure. - * - * 2. Fixed size arrays. There is no explicit provisional for dyanamically - * adding or removing entries from the symbol table (realloc might be - * used for that purpose if needed). The intention is to support only - * fixed size arrays completely defined at compilation or link time. - */ - -struct symtab_s -{ - FAR const char *sym_name; /* A pointer to the symbol name string */ - FAR const void *sym_value; /* The value associated witht the string */ -}; +#include /**************************************************************************** * Public Functions @@ -87,7 +60,7 @@ extern "C" * Name: exec_getsymtab * * Description: - * Get the current symbol table selection as an atomic operation. + * Get the current application symbol table selection as an atomic operation. * * Input Parameters: * symtab - The location to store the symbol table. @@ -104,7 +77,7 @@ void exec_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols); * Name: exec_setsymtab * * Description: - * Select a new symbol table selection as an atomic operation. + * Select a new application symbol table selection as an atomic operation. * * Input Parameters: * symtab - The new symbol table. @@ -117,82 +90,4 @@ void exec_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols); void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols); -/**************************************************************************** - * Name: symtab_findbyname - * - * Description: - * Find the symbol in the symbol table with the matching name. - * This version assumes that table is not ordered with respect to symbol - * name and, hence, access time will be linear with respect to nsyms. - * - * Returned Value: - * A reference to the symbol table entry if an entry with the matching - * name is found; NULL is returned if the entry is not found. - * - ****************************************************************************/ - -FAR const struct symtab_s * -symtab_findbyname(FAR const struct symtab_s *symtab, - FAR const char *name, int nsyms); - -/**************************************************************************** - * Name: symtab_findorderedbyname - * - * Description: - * Find the symbol in the symbol table with the matching name. - * This version assumes that table ordered with respect to symbol name. - * - * Returned Value: - * A reference to the symbol table entry if an entry with the matching - * name is found; NULL is returned if the entry is not found. - * - ****************************************************************************/ - -FAR const struct symtab_s * -symtab_findorderedbyname(FAR const struct symtab_s *symtab, - FAR const char *name, int nsyms); - -/**************************************************************************** - * Name: symtab_findbyvalue - * - * Description: - * Find the symbol in the symbol table whose value closest (but not greater - * than), the provided value. This version assumes that table is not ordered - * with respect to symbol name and, hence, access time will be linear with - * respect to nsyms. - * - * Returned Value: - * A reference to the symbol table entry if an entry with the matching - * name is found; NULL is returned if the entry is not found. - * - ****************************************************************************/ - -FAR const struct symtab_s * -symtab_findbyvalue(FAR const struct symtab_s *symtab, - FAR void *value, int nsyms); - -/**************************************************************************** - * Name: symtab_findorderedbyvalue - * - * Description: - * Find the symbol in the symbol table whose value closest (but not greater - * than), the provided value. This version assumes that table is ordered - * with respect to symbol name. - * - * Returned Value: - * A reference to the symbol table entry if an entry with the matching - * name is found; NULL is returned if the entry is not found. - * - ****************************************************************************/ - -FAR const struct symtab_s * -symtab_findorderedbyvalue(FAR const struct symtab_s *symtab, - FAR void *value, int nsyms); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - #endif /* __INCLUDE_NUTTX_BINFMT_SYMTAB_H */ - diff --git a/include/nuttx/board.h b/include/nuttx/board.h index f29b68cf10f80ce175ce7d4b499ab0ab689e50ac..6c8578321fdd23d5a918e5f1b0c006c29c4c1e96 100644 --- a/include/nuttx/board.h +++ b/include/nuttx/board.h @@ -101,6 +101,7 @@ #include #include +#include #include @@ -192,6 +193,32 @@ int board_power_off(int status); int board_reset(int status); #endif +/**************************************************************************** + * Name: board_uniqueid + * + * Description: + * Return a unique ID associated with the board. The meaning of this + * unique ID is not specified. It may be a chip identifying number, a + * serial number, a MAC address, etc. It may be in binary or it may be + * ASCII. The only only requirement is that the length of the unique + * ID be exactly CONFIG_BOARDCTL_UNIQUEID_SIZE in length. + * + * Input Parameters: + * uniqueid - A reference to a writable memory location provided by the + * caller to receive the board unique ID. The memory memory referenced + * by this pointer must be at least CONFIG_BOARDCTL_UNIQUEID_SIZE in + * length. + * + * Returned Value: + * Zero (OK) is returned on success. Otherwize a negated errno value is + * returned indicating the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_UNIQUEID +int board_uniqueid(FAR uint8_t *uniqueid); +#endif + /**************************************************************************** * Name: board_tsc_setup * @@ -205,8 +232,8 @@ int board_reset(int status); * application-level touchscreen testing logic (perhaps by * apps/examples/touchscreen). If CONFIG_LIB_BOARDCTL=y and * CONFIG_BOARDCTL_TSCTEST=y, then this functions will be invoked via the - * (non-standard) boardctl() interface using the commands - * BOARDIOC_TSCTEST_SETUP command. + * (non-standard) boardctl() interface using the BOARDIOC_TSCTEST_SETUP + * command. * * Input Parameters: * minor - The input device minor number @@ -231,8 +258,8 @@ int board_tsc_setup(int minor); * application-level touchscreen testing logic (perhaps by * apps/examples/touchscreen). If CONFIG_LIB_BOARDCTL=y and * CONFIG_BOARDCTL_TSCTEST=y, then this functions will be invoked via the - * (non-standard) boardctl() interface using the commands - * BOARDIOC_TSCTEST_TEARDOWN command. + * (non-standard) boardctl() interface using the BOARDIOC_TSCTEST_TEARDOWN + * command. * * Input Parameters: * None @@ -254,8 +281,8 @@ void board_tsc_teardown(void); * This is an internal OS interface but may be invoked indirectly from * application-level graphics logic. If CONFIG_LIB_BOARDCTL=y and * CONFIG_BOARDCTL_ADCTEST=y, then this functions will be invoked via the - * (non-standard) boardctl() interface using the commands - * BOARDIOC_ADCTEST_SETUP command. + * (non-standard) boardctl() interface using the BOARDIOC_ADCTEST_SETUP + * command. * ****************************************************************************/ @@ -288,8 +315,8 @@ int board_pwm_setup(void); * This is an internal OS interface but may be invoked indirectly from * application-level graphics logic. If CONFIG_LIB_BOARDCTL=y and * CONFIG_BOARDCTL_GRAPHICS=y, then this functions will be invoked via the - * (non-standard) boardctl() interface using the commands - * BOARDIOC_GRAPHICS_SETUP command. + * (non-standard) boardctl() interface using the BOARDIOC_GRAPHICS_SETUP + * command. * ****************************************************************************/ @@ -301,6 +328,25 @@ struct fb_vtable_s; FAR struct fb_vtable_s *board_graphics_setup(unsigned int devno); #endif +/**************************************************************************** + * Name: board_can_initialize + * + * Description: + * Perform one-time CAN initialization. This is currently only needed for + * apps/examples/can. + * + * This is an internal OS interface but may be invoked indirectly from + * application-level graphics logic. If CONFIG_LIB_BOARDCTL=y and + * CONFIG_BOARDCTL_CANINIT=y, then this functions will be invoked via the + * (non-standard) boardctl() interface using the BOARDIOC_CAN_INITIALIZE + * command. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_CANINIT +int board_can_initialize(void); +#endif + /**************************************************************************** * Name: board_ioctl * @@ -332,7 +378,7 @@ int board_ioctl(unsigned int cmd, uintptr_t arg); * multiple LCD devices. * board_lcd_uninitialize - Uninitialize the LCD support * - ***************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_LCD struct lcd_dev_s; /* Forward reference */ @@ -343,20 +389,20 @@ void board_lcd_uninitialize(void); #endif /**************************************************************************** - * Name: board_led_initialize + * Name: board_autoled_initialize * * Description: - * This functions is called very early in initialization to perform board- + * This function is called very early in initialization to perform board- * specific initialization of LED-related resources. This includes such * things as, for example, configure GPIO pins to drive the LEDs and also * putting the LEDs in their correct initial state. * - * NOTE: In most architectures, board_led_initialize() is called from + * NOTE: In most architectures, board_autoled_initialize() is called from * board-specific initialization logic. But there are a few architectures * where this initialization function is still called from common chip * architecture logic. This interface is not, however, a common board * interface in any event and, hence, the usage of the name - * board_led_initialize is deprecated. + * board_autoled_initialize is deprecated. * * WARNING: This interface name will eventually be removed; do not use it * in new board ports. New implementations should use the naming @@ -372,13 +418,13 @@ void board_lcd_uninitialize(void); ****************************************************************************/ #ifdef CONFIG_ARCH_LEDS -void board_led_initialize(void); +void board_autoled_initialize(void); #else -# define board_led_initialize() +# define board_autoled_initialize() #endif /**************************************************************************** - * Name: board_led_on + * Name: board_autoled_on * * Description: * Set the LED configuration into the ON condition for the state provided @@ -407,13 +453,13 @@ void board_led_initialize(void); ****************************************************************************/ #ifdef CONFIG_ARCH_LEDS -void board_led_on(int led); +void board_autoled_on(int led); #else -# define board_led_on(led) +# define board_autoled_on(led) #endif /**************************************************************************** - * Name: board_led_off + * Name: board_autoled_off * * Description: * Set the LED configuration into the OFF condition for the state provided @@ -438,9 +484,85 @@ void board_led_on(int led); ****************************************************************************/ #ifdef CONFIG_ARCH_LEDS -void board_led_off(int led); +void board_autoled_off(int led); #else -# define board_led_off(led) +# define board_autoled_off(led) +#endif + +/**************************************************************************** + * Name: board_userled_initialize + * + * Description: + * This function may called from application-specific logic during its + * to perform board-specific initialization of LED resources. This + * includes such things as, for example, configure GPIO pins to drive the + * LEDs and also putting the LEDs in their correct initial state. + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED charater driver). + * + * Most boards have only a few LEDs and in thoses cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_LEDS +void board_userled_initialize(void); +#endif + +/**************************************************************************** + * Name: board_userled + * + * Description: + * This interface may be used by application specific logic to set the + * state of a single LED. Definitions for the led identification are + * provided in the board-specific board.h header file that may be included + * like: + * + * #included + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED charater driver). + * + * Most boards have only a few LEDs and in thoses cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_LEDS +void board_userled(int led, bool ledon); +#endif + +/**************************************************************************** + * Name: board_userled_all + * + * Description: + * This interface may be used by application specific logic to set the + * state of all board LED. Definitions for the led set member + * identification is provided in the board-specific board.h header file + * that may be includedlike: + * + * #included + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED charater driver). + * + * Most boards have only a few LEDs and in thoses cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_LEDS +void board_userled_all(uint8_t ledset); #endif /**************************************************************************** diff --git a/include/nuttx/can.h b/include/nuttx/can.h index 3235b9de544eabb593cd8dc0c21ed11e490bd5fd..6f8b3d72aa904b28f83069f8449413255d4f0479 100644 --- a/include/nuttx/can.h +++ b/include/nuttx/can.h @@ -51,6 +51,10 @@ #include #include +#ifdef CONFIG_CAN_TXREADY +# include +#endif + #ifdef CONFIG_CAN /************************************************************************************ @@ -70,6 +74,12 @@ * CONFIG_CAN_LOOPBACK - A CAN driver may or may not support a loopback * mode for testing. If the driver does support loopback mode, the setting * will enable it. (If the driver does not, this setting will have no effect). + * CONFIG_CAN_TXREADY - Add support for the can_txready() callback. This is needed + * only for CAN hardware the supports an separate H/W TX message FIFO. The call + * back is needed to keep the S/W FIFO and the H/W FIFO in sync. Work queue + * support is needed for this feature. + * CONFIG_CAN_TXREADY_HIPRI or CONFIG_CAN_TXREADY_LOPRI - Selects which work queue + * will be used for the can_txready() processing. */ /* Default configuration settings that may be overridden in the NuttX configuration @@ -106,7 +116,7 @@ * Returned Value: A non-negative filter ID is returned on success. * Otherwise -1 (ERROR) is returned with the errno * variable set to indicate the nature of the error. - * Dependencies: Requires CONFIG_CAN_EXID *not* defined + * Dependencies: None * * CANIOC_ADD_EXTFILTER: * Description: Add an address filter for a extended 29 bit address. @@ -114,7 +124,7 @@ * Returned Value: A non-negative filter ID is returned on success. * Otherwise -1 (ERROR) is returned with the errno * variable set to indicate the nature of the error. - * Dependencies: Requires CONFIG_CAN_EXID=y + * Dependencies: Requires CONFIG_CAN_EXTID=y * * CANIOC_DEL_STDFILTER: * Description: Remove an address filter for a standard 11 bit address. @@ -123,7 +133,7 @@ * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) * is returned with the errno variable set to indicate the * nature of the error. - * Dependencies: Requires CONFIG_CAN_EXID *not* defined + * Dependencies: None * * CANIOC_DEL_EXTFILTER: * Description: Remove an address filter for a standard 29 bit address. @@ -132,20 +142,42 @@ * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) * is returned with the errno variable set to indicate the * nature of the error. - * Dependencies: Requires CONFIG_CAN_EXID=y + * Dependencies: Requires CONFIG_CAN_EXTID=y + * + * CANIOC_GET_BITTIMING: + * Description: Return the current bit timing settings + * Argument: A pointer to a write-able instance of struct + * canioc_bittiming_s in which current bit timing values + * will be returned. + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + * + * CANIOC_SET_BITTIMING: + * Description: Set new current bit timing values + * Argument: A pointer to a read-able instance of struct + * canioc_bittiming_s in which the new bit timing values + * are provided. + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None */ #define CANIOC_RTR _CANIOC(1) -#define CANIOC_ADD_STDFILTER _CANIOC(2) -#define CANIOC_ADD_EXTFILTER _CANIOC(3) -#define CANIOC_DEL_STDFILTER _CANIOC(4) -#define CANIOC_DEL_EXTFILTER _CANIOC(5) +#define CANIOC_GET_BITTIMING _CANIOC(2) +#define CANIOC_SET_BITTIMING _CANIOC(3) +#define CANIOC_ADD_STDFILTER _CANIOC(4) +#define CANIOC_ADD_EXTFILTER _CANIOC(5) +#define CANIOC_DEL_STDFILTER _CANIOC(6) +#define CANIOC_DEL_EXTFILTER _CANIOC(7) /* CANIOC_USER: Device specific ioctl calls can be supported with cmds greater * than this value */ -#define CANIOC_USER _CANIOC(6) +#define CANIOC_USER _CANIOC(8) /* Convenience macros ***************************************************************/ @@ -173,6 +205,98 @@ #define CAN_MSGLEN(nbytes) (sizeof(struct can_msg_s) - CAN_MAXDATALEN + (nbytes)) +/* CAN Error Indications ************************************************************/ + +#ifdef CONFIG_CAN_ERRORS +/* Bit settings in the ch_id field of the CAN error message (when ch_error is set) */ + +# define CAN_ERROR_TXTIMEOUT (1 << 0) /* Bit 0: TX timeout */ +# define CAN_ERROR_LOSTARB (1 << 1) /* Bit 1: Lost arbitration (See CAN_ERROR0_* definitions) */ +# define CAN_ERROR_CONTROLLER (1 << 2) /* Bit 2: Controller error (See CAN_ERROR1_* definitions) */ +# define CAN_ERROR_PROTOCOL (1 << 3) /* Bit 3: Protocol error (see CAN_ERROR1_* and CAN_ERROR3_* definitions) */ +# define CAN_ERROR_TRANSCEIVER (1 << 4) /* Bit 4: Transceiver error (See CAN_ERROR4_* definitions) */ +# define CAN_ERROR_NOACK (1 << 5) /* Bit 5: No ACK received on transmission */ +# define CAN_ERROR_BUSOFF (1 << 6) /* Bit 6: Bus off */ +# define CAN_ERROR_BUSERROR (1 << 7) /* Bit 7: Bus error */ +# define CAN_ERROR_RESTARTED (1 << 8) /* Bit 8: Controller restarted */ + /* Bits 9-10: Available */ + +/* The remaining definitions described the error report payload that follows the + * CAN header. + */ + +# define CAN_ERROR_DLC (8) /* DLC of error report */ + +/* Data[0]: Arbitration lost in ch_error. */ + +# define CAN_ERROR0_UNSPEC 0x00 /* Unspecified error */ +# define CAN_ERROR0_BIT(n) (n) /* Bit number in the bit stream */ + +/* Data[1]: Error status of CAN-controller */ + +# define CAN_ERROR1_UNSPEC 0x00 /* Unspecified error */ +# define CAN_ERROR1_RXOVERFLOW (1 << 0) /* Bit 0: RX buffer overflow */ +# define CAN_ERROR1_TXOVERFLOW (1 << 1) /* Bit 1: TX buffer overflow */ +# define CAN_ERROR1_RXWARNING (1 << 2) /* Bit 2: Reached warning level for RX errors */ +# define CAN_ERROR1_TXWARNING (1 << 3) /* Bit 3: Reached warning level for TX errors */ +# define CAN_ERROR1_RXPASSIVE (1 << 4) /* Bit 4: Reached passive level for RX errors */ +# define CAN_ERROR1_TXPASSIVE (1 << 5) /* Bit 5: Reached passive level for TX errors */ + /* Bits 6-7: Available */ + +/* Data[2]: Error in CAN protocol. This provides the type of the error. */ + +# define CAN_ERROR2_UNSPEC 0x00 /* Unspecified error */ +# define CAN_ERROR2_BIT (1 << 0) /* Bit 0: Single bit error */ +# define CAN_ERROR2_FORM (1 << 1) /* Bit 1: Frame format error */ +# define CAN_ERROR2_STUFF (1 << 2) /* Bit 2: Bit stuffing error */ +# define CAN_ERROR2_BIT0 (1 << 3) /* Bit 3: Unable to send dominant bit */ +# define CAN_ERROR2_BIT1 (1 << 4) /* Bit 4: Unable to send recessive bit */ +# define CAN_ERROR2_OVERLOAD (1 << 5) /* Bit 5: Bus overload */ +# define CAN_ERROR2_ACTIVE (1 << 6) /* Bit 6: Active error announcement */ +# define CAN_ERROR2_TX (1 << 7) /* Bit 7: Error occured on transmission */ + +/* Data[3]: Error in CAN protocol. This provides the loation of the error. */ + +# define CAN_ERROR3_UNSPEC 0x00 /* Unspecified error */ +# define CAN_ERROR3_SOF 0x01 /* start of frame */ +# define CAN_ERROR3_ID0 0x02 /* ID bits 0-4 */ +# define CAN_ERROR3_ID1 0x03 /* ID bits 5-12 */ +# define CAN_ERROR3_ID2 0x04 /* ID bits 13-17 */ +# define CAN_ERROR3_ID3 0x05 /* ID bits 21-28 */ +# define CAN_ERROR3_ID4 0x06 /* ID bits 18-20 */ +# define CAN_ERROR3_IDE 0x07 /* Identifier extension */ +# define CAN_ERROR3_RTR 0x08 /* RTR */ +# define CAN_ERROR3_SRTR 0x09 /* Substitute RTR */ +# define CAN_ERROR3_RES0 0x0a /* Reserved bit 0 */ +# define CAN_ERROR3_RES1 0x0b /* Reserved bit 1 */ +# define CAN_ERROR3_DLC 0x0c /* Data length code */ +# define CAN_ERROR3_DATA 0x0d /* Data section */ +# define CAN_ERROR3_CRCSEQ 0x0e /* CRC sequence */ +# define CAN_ERROR3_CRCDEL 0x0f /* CRC delimiter */ +# define CAN_ERROR3_ACK 0x10 /* ACK slot */ +# define CAN_ERROR3_ACKDEL 0x11 /* ACK delimiter */ +# define CAN_ERROR3_EOF 0x12 /* End of frame */ +# define CAN_ERROR3_INTERM 0x13 /* Intermission */ + +/* Data[4]: Error status of CAN-transceiver */ + +# define CAN_ERROR4_UNSPEC 0x00 + +# define CANH_ERROR4_MASK 0x0f /* Bits 0-3: CANH */ +# define CANH_ERROR4_NOWIRE 0x01 +# define CANH_ERROR4_SHORT2BAT 0x02 +# define CANH_ERROR4_SHORT2VCC 0x03 +# define CANH_ERROR4_SHORT2GND 0x04 + +# define CANL_ERROR4_MASK 0xf0 /* Bits 0-3: CANL */ +# define CANL_ERROR4_NOWIRE 0x10 +# define CANL_ERROR4_SHORT2BAT 0x20 +# define CANL_ERROR4_SHORT2VCC 0x30 +# define CANL_ERROR4_SHORT2GND 0x40 +# define CANL_ERROR4_SHORT2CANH 0x50 + +#endif /* CONFIG_CAN_ERRORS */ + /* CAN filter support ***************************************************************/ /* Some CAN hardware supports a notion of prioritizing messages that match filters. * Only two priority levels are currently supported and are encoded as defined @@ -196,24 +320,36 @@ * One based CAN-message is represented with a maximum of 10 bytes. A message is * composed of at least the first 2 bytes (when there are no data bytes present). * - * Bytes 0-1: Hold a 16-bit value in host byte order - * Bits 0-3: Data Length Code (DLC) - * Bit 4: Remote Transmission Request (RTR) - * Bits 5-15: The 11-bit CAN identifier - * - * Bytes 2-9: CAN data + * Bytes 0-1: Bits 0-3: Data Length Code (DLC) + * Bit 4: Remote Transmission Request (RTR) + * Bit 5: 1=Message ID is a bit-encoded error report (See NOTE) + * Bits 6-7: Unused + * Bytes 1-2: Bits 0-10: The 11-bit CAN identifier This message ID is a bit + * encoded error set if ch_error is set (See NOTE). + * Bits 11-15: Unused + * Bytes 3-10: CAN data * * CAN-message Format (with Extended ID support) * * One CAN-message consists of a maximum of 13 bytes. A message is composed of at * least the first 5 bytes (when there are no data bytes). * - * Bytes 0-3: Hold 11- or 29-bit CAN ID in host byte order - * Byte 4: Bits 0-3: Data Length Code (DLC) - * Bit 4: Remote Transmission Request (RTR) - * Bit 5: Extended ID indication - * Bits 6-7: Unused - * Bytes 5-12: CAN data + * Bytes 0-3: Bits 0-28: Hold 11- or 29-bit CAN ID in host byte order. This + * message ID is a bit encoded error set if ch_error + * is set (See NOTE). + * Bits 29-31: Unused + * Byte 4: Bits 0-3: Data Length Code (DLC) + * Bit 4: Remote Transmission Request (RTR) + * Bit 5: 1=Message ID is a bit-encoded error report (See NOTE) + * Bit 6: Extended ID indication + * Bit 7: Unused + * Bytes 5-12: CAN data Size determined by DLC + * + * NOTE: The error indication if valid only on message reports received from the + * CAN driver; it is ignored on transmission. When the error bit is set, the + * message ID is an encoded set of error indications (see CAN_ERROR_* definitions). + * A more detailed report of certain errors then follows in message payload. + * CONFIG_CAN_ERRORS=y is required in order to receive error reports. * * The struct can_msg_s holds this information in a user-friendly, unpacked form. * This is the form that is used at the read() and write() driver interfaces. The @@ -224,18 +360,25 @@ #ifdef CONFIG_CAN_EXTID struct can_hdr_s { - uint32_t ch_id; /* 11- or 29-bit ID (3-bits unused) */ + uint32_t ch_id; /* 11- or 29-bit ID (20- or 3-bits unused) */ uint8_t ch_dlc : 4; /* 4-bit DLC */ uint8_t ch_rtr : 1; /* RTR indication */ +#ifdef CONFIG_CAN_ERRORS + uint8_t ch_error : 1; /* 1=ch_id is an error report */ +#endif uint8_t ch_extid : 1; /* Extended ID indication */ - uint8_t ch_unused : 2; /* Unused */ + uint8_t ch_unused : 1; /* Unused */ } packed_struct; #else struct can_hdr_s { - uint16_t ch_dlc : 4; /* 4-bit DLC. May be encoded in CAN_FD mode. */ - uint16_t ch_rtr : 1; /* RTR indication */ - uint16_t ch_id : 11; /* 11-bit standard ID */ + uint16_t ch_id; /* 11-bit standard ID (5-bits unused) */ + uint8_t ch_dlc : 4; /* 4-bit DLC. May be encoded in CAN_FD mode. */ + uint8_t ch_rtr : 1; /* RTR indication */ +#ifdef CONFIG_CAN_ERRORS + uint8_t ch_error : 1; /* 1=ch_id is an error report */ +#endif + uint8_t ch_unused : 2; /* Unused */ } packed_struct; #endif @@ -354,6 +497,9 @@ struct can_dev_s sem_t cd_closesem; /* Locks out new opens while close is in progress */ struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */ struct can_rxfifo_s cd_recv; /* Describes receive FIFO */ +#ifdef CONFIG_CAN_TXREADY + struct work_s cd_work; /* Use to manage can_txready() work */ +#endif /* List of pending RTR requests */ struct can_rtrwait_s cd_rtr[CONFIG_CAN_NPENDINGRTR]; FAR const struct can_ops_s *cd_ops; /* Arch-specific operations */ @@ -361,6 +507,7 @@ struct can_dev_s }; /* Structures used with ioctl calls */ +/* CANIOC_RTR: */ struct canioc_rtr_s { @@ -368,7 +515,25 @@ struct canioc_rtr_s FAR struct can_msg_s *ci_msg; /* The location to return the RTR response */ }; +/* CANIOC_GET_BITTIMING/CANIOC_SET_BITTIMING: */ +/* Bit time = Tquanta * (Sync_Seg + Prop_Seq + Phase_Seg1 + Phase_Seg2) + * = Tquanta * (TSEG1 + TSEG2 + 1) + * Where + * TSEG1 = Prop_Seq + Phase_Seg1 + * TSEG2 = Phase_Seg2 + */ + +struct canioc_bittiming_s +{ + uint32_t bt_baud; /* Bit rate = 1 / bit time */ + uint8_t bt_tseg1; /* TSEG1 in time quanta */ + uint8_t bt_tseg2; /* TSEG2 in time quanta */ + uint8_t bt_sjw; /* Synchronization Jump Width in time quanta */ +}; + #ifdef CONFIG_CAN_EXTID +/* CANIOC_ADD_EXTFILTER: */ + struct canioc_extfilter_s { uint32_t xf_id1; /* 29-bit ID. For dual match or for the @@ -378,7 +543,10 @@ struct canioc_extfilter_s uint8_t xf_type; /* See CAN_FILTER_* definitions */ uint8_t xf_prio; /* See CAN_MSGPRIO_* definitions */ }; -#else +#endif + +/* CANIOC_ADD_STDFILTER: */ + struct canioc_stdfilter_s { uint16_t sf_id1; /* 11-bit ID. For dual match or for the @@ -388,7 +556,6 @@ struct canioc_stdfilter_s uint8_t sf_type; /* See CAN_FILTER_* definitions */ uint8_t sf_prio; /* See CAN_MSGPRIO_* definitions */ }; -#endif /************************************************************************************ * Public Data @@ -423,12 +590,12 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev); * Description: * Called from the CAN interrupt handler when new read data is available * - * Parameters: + * Input Parameters: * dev - The specific CAN device * hdr - The 16-bit CAN header * data - An array contain the CAN data. * - * Return: + * Returned Value: * OK on success; a negated errno on failure. * ************************************************************************************/ @@ -440,18 +607,136 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, * Name: can_txdone * * Description: - * Called from the CAN interrupt handler at the completion of a send operation. + * Called when the hardware has processed the outgoing TX message. This + * normally means that the CAN messages was sent out on the wire. But + * if the CAN hardware supports a H/W TX FIFO, then this call may mean + * only that the CAN message has been added to the H/W FIFO. In either + * case, the upper-half CAN driver can remove the outgoing message from + * the S/W FIFO and discard it. + * + * This function may be called in different contexts, depending upon the + * nature of the underlying CAN hardware. * - * Parameters: + * 1. No H/W TX FIFO (CONFIG_CAN_TXREADY not defined) + * + * This function is only called from the CAN interrupt handler at the + * completion of a send operation. + * + * can_write() -> can_xmit() -> dev_send() + * CAN interrupt -> can_txdone() + * + * If the CAN hardware is busy, then the call to dev_send() will + * fail, the S/W TX FIFO will accumulate outgoing messages, and the + * thread calling can_write() may eventually block waiting for space in + * the S/W TX FIFO. + * + * When the CAN hardware completes the transfer and processes the + * CAN interrupt, the call to can_txdone() will make space in the S/W + * TX FIFO and will awaken the waiting can_write() thread. + * + * 2a. H/W TX FIFO (CONFIG_CAN_TXREADY=y) and S/W TX FIFO not full + * + * This function will be called back from dev_send() immediately when a + * new CAN message is added to H/W TX FIFO: + * + * can_write() -> can_xmit() -> dev_send() -> can_txdone() + * + * When the H/W TX FIFO becomes full, dev_send() will fail and + * can_txdone() will not be called. In this case the S/W TX FIFO will + * accumulate outgoing messages, and the thread calling can_write() may + * eventually block waiting for space in the S/W TX FIFO. + * + * 2b. H/W TX FIFO (CONFIG_CAN_TXREADY=y) and S/W TX FIFO full + * + * In this case, the thread calling can_write() is blocked waiting for + * space in the S/W TX FIFO. can_txdone() will be called, indirectly, + * from can_txready_work() running on the thread of the work queue. + * + * CAN interrupt -> can_txready() -> Schedule can_txready_work() + * can_txready_work() -> can_xmit() -> dev_send() -> can_txdone() + * + * The call dev_send() should not fail in this case and the subsequent + * call to can_txdone() will make space in the S/W TX FIFO and will + * awaken the waiting thread. + * + * Input Parameters: * dev - The specific CAN device + * hdr - The 16-bit CAN header + * data - An array contain the CAN data. * - * Return: + * Returned Value: * OK on success; a negated errno on failure. * + * Assumptions: + * Interrupts are disabled. This is required by can_xmit() which is called + * by this function. Interrupts are explicitly disabled when called + * through can_write(). Interrupts are expected be disabled when called + * from the CAN interrupt handler. + * ************************************************************************************/ int can_txdone(FAR struct can_dev_s *dev); +/************************************************************************************ + * Name: can_txready + * + * Description: + * Called from the CAN interrupt handler at the completion of a send + * operation. This interface is needed only for CAN hardware that + * supports queing of outgoing messages in a H/W FIFO. + * + * The CAN upper half driver also supports a queue of output messages in a + * S/W FIFO. Messages are added to that queue when when can_write() is + * called and removed from the queue in can_txdone() when each TX message + * is complete. + * + * After each message is added to the S/W FIFO, the CAN upper half driver + * will attempt to send the message by calling into the lower half driver. + * That send will not be performed if the lower half driver is busy, i.e., + * if dev_txready() returns false. In that case, the number of messages in + * the S/W FIFO can grow. If the S/W FIFO becomes full, then can_write() + * will wait for space in the S/W FIFO. + * + * If the CAN hardware does not support a H/W FIFO then busy means that + * the hardware is actively sending the message and is guaranteed to + * become non-busy (i.e, dev_txready()) when the send transfer completes + * and can_txdone() is called. So the call to can_txdone() means that the + * transfer has completed and also that the hardware is ready to accept + * another transfer. + * + * If the CAN hardware supports a H/W FIFO, can_txdone() is not called + * when the tranfer is complete, but rather when the transfer is queued in + * the H/W FIFO. When the H/W FIFO becomes full, then dev_txready() will + * report false and the number of queued messages in the S/W FIFO will grow. + * + * There is no mechanism in this case to inform the upper half driver when + * the hardware is again available, when there is again space in the H/W + * FIFO. can_txdone() will not be called again. If the S/W FIFO becomes + * full, then the upper half driver will wait for space to become + * available, but there is no event to awaken it and the driver will hang. + * + * Enabling this feature adds support for the can_txready() interface. + * This function is called from the lower half driver's CAN interrupt + * handler each time a TX transfer completes. This is a sure indication + * that the H/W FIFO is no longer full. can_txready() will then awaken + * the can_write() logic and the hang condition is avoided. + * + * Input Parameters: + * dev - The specific CAN device + * + * Returned Value: + * OK on success; a negated errno on failure. + * + * Assumptions: + * Interrupts are disabled. This function may execute in the context of + * and interrupt handler. + * + ************************************************************************************/ + +#ifdef CONFIG_CAN_TXREADY +int can_txready(FAR struct can_dev_s *dev); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h index c091300dbb17bb40a362054651e91e31a3b37616..a844396b30c62f2a422b740cd34229237215924c 100644 --- a/include/nuttx/clock.h +++ b/include/nuttx/clock.h @@ -1,7 +1,8 @@ /**************************************************************************** * include/nuttx/clock.h * - * Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2014, 2016 Gregory Nutt. + All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -98,16 +99,25 @@ /* Timing constants *********************************************************/ -#define NSEC_PER_SEC 1000000000 -#define USEC_PER_SEC 1000000 -#define MSEC_PER_SEC 1000 -#define DSEC_PER_SEC 10 -#define NSEC_PER_DSEC 100000000 -#define USEC_PER_DSEC 100000 -#define MSEC_PER_DSEC 100 -#define NSEC_PER_MSEC 1000000 -#define USEC_PER_MSEC 1000 -#define NSEC_PER_USEC 1000 +#define NSEC_PER_SEC 1000000000L /* Seconds */ +#define USEC_PER_SEC 1000000L +#define MSEC_PER_SEC 1000L +#define DSEC_PER_SEC 10L +#define HSEC_PER_SEC 2L + +#define NSEC_PER_HSEC 500000000L /* Half seconds */ +#define USEC_PER_HSEC 500000L +#define MSEC_PER_HSEC 500L +#define DSEC_PER_HSEC 5L + +#define NSEC_PER_DSEC 100000000L /* Deciseconds */ +#define USEC_PER_DSEC 100000L +#define MSEC_PER_DSEC 100L + +#define NSEC_PER_MSEC 1000000L /* Milliseconds */ +#define USEC_PER_MSEC 1000L + +#define NSEC_PER_USEC 1000L /* Microseconds */ /* If CONFIG_SCHED_TICKLESS is not defined, then the interrupt interval of * the system timer is given by USEC_PER_TICK. This is the expected number @@ -135,6 +145,7 @@ */ #define TICK_PER_DSEC (USEC_PER_DSEC / USEC_PER_TICK) /* Truncates! */ +#define TICK_PER_HSEC (USEC_PER_HSEC / USEC_PER_TICK) /* Truncates! */ #define TICK_PER_SEC (USEC_PER_SEC / USEC_PER_TICK) /* Truncates! */ #define TICK_PER_MSEC (USEC_PER_MSEC / USEC_PER_TICK) /* Truncates! */ #define MSEC_PER_TICK (USEC_PER_TICK / USEC_PER_MSEC) /* Truncates! */ @@ -146,10 +157,11 @@ #if (MSEC_PER_TICK * USEC_PER_MSEC) == USEC_PER_TICK # define MSEC2TICK(msec) (((msec)+(MSEC_PER_TICK/2))/MSEC_PER_TICK) /* Rounds */ #else -# define MSEC2TICK(msec) USEC2TICK(msec * 1000) /* Rounds */ +# define MSEC2TICK(msec) USEC2TICK((msec) * USEC_PER_MSEC) /* Rounds */ #endif #define DSEC2TICK(dsec) MSEC2TICK((dsec) * MSEC_PER_DSEC) /* Rounds */ +#define HSEC2TICK(dsec) MSEC2TICK((dsec) * MSEC_PER_HSEC) /* Rounds */ #define SEC2TICK(sec) MSEC2TICK((sec) * MSEC_PER_SEC) /* Rounds */ #define TICK2NSEC(tick) ((tick) * NSEC_PER_TICK) /* Exact */ @@ -162,6 +174,7 @@ #endif #define TICK2DSEC(tick) (((tick)+(TICK_PER_DSEC/2))/TICK_PER_DSEC) /* Rounds */ +#define TICK2HSEC(tick) (((tick)+(TICK_PER_HSEC/2))/TICK_PER_HSEC) /* Rounds */ #define TICK2SEC(tick) (((tick)+(TICK_PER_SEC/2))/TICK_PER_SEC) /* Rounds */ /**************************************************************************** @@ -177,10 +190,26 @@ struct cpuload_s }; #endif +/* This type is the natural with of the system timer */ + +#ifdef CONFIG_SYSTEM_TIME64 +typedef uint64_t systime_t; +#else +typedef uint32_t systime_t; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + /* Access to raw system clock ***********************************************/ /* Direct access to the system timer/counter is supported only if (1) the * system timer counter is available (i.e., we are not configured to use @@ -189,32 +218,17 @@ struct cpuload_s */ #ifdef __HAVE_KERNEL_GLOBALS -# ifdef CONFIG_SYSTEM_TIME64 - -extern volatile uint64_t g_system_timer; -#define clock_systimer() (uint32_t)(g_system_timer & 0x00000000ffffffff) -#define clock_systimer64() g_system_timer +EXTERN volatile systime_t g_system_timer; -# else - -extern volatile uint32_t g_system_timer; -#define clock_systimer() g_system_timer - -# endif +#ifndef CONFIG_SYSTEM_TIME64 +# define clock_systimer() g_system_timer +#endif #endif /**************************************************************************** * Public Function Prototypes ****************************************************************************/ -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - /**************************************************************************** * Function: clock_synchronize * @@ -251,37 +265,13 @@ void clock_synchronize(void); * Function: clock_systimer * * Description: - * Return the current value of the 32-bit system timer counter. Indirect - * access to the system timer counter is required through this function if - * the execution environment does not have direct access to kernel global - * data + * Return the current value of the 32/64-bit system timer counter. + * Indirect access to the system timer counter is required through this + * function if the execution environment does not have direct access to + * kernel global data. * - * Parameters: - * None - * - * Return Value: - * The current value of the system timer counter - * - * Assumptions: - * - ****************************************************************************/ - -#ifndef __HAVE_KERNEL_GLOBALS -# ifdef CONFIG_SYSTEM_TIME64 -# define clock_systimer() (uint32_t)(clock_systimer64() & 0x00000000ffffffff) -# else -uint32_t clock_systimer(void); -# endif -#endif - -/**************************************************************************** - * Function: clock_systimer64 - * - * Description: - * Return the current value of the 64-bit system timer counter. Indirect - * access to the system timer counter is required through this function if - * the execution environment does not have direct access to kernel global - * data + * Use of this function is also required to assue atomic access to the + * 64-bit system timer. * * Parameters: * None @@ -293,8 +283,8 @@ uint32_t clock_systimer(void); * ****************************************************************************/ -#if !defined(__HAVE_KERNEL_GLOBALS) && defined(CONFIG_SYSTEM_TIME64) -uint64_t clock_systimer64(void); +#if !defined(__HAVE_KERNEL_GLOBALS) || defined(CONFIG_SYSTEM_TIME64) +systime_t clock_systimer(void); #endif /**************************************************************************** diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 9cf1192c57ade43dc1c2c40a41cb2fa695880959..ec93a9a192e84aa68e03fdbec478ba3213f2ccd9 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -40,6 +40,8 @@ * Included Files ****************************************************************************/ +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -127,26 +129,44 @@ */ #if defined(__m32c__) +/* No I-space access qualifiers */ + +# define IOBJ +# define IPTR + /* Select the small, 16-bit addressing model */ -# define CONFIG_SMALL_MEMORY 1 +# define CONFIG_SMALL_MEMORY 1 /* Long and int are not the same size */ -# define CONFIG_LONG_IS_NOT_INT 1 +# define CONFIG_LONG_IS_NOT_INT 1 /* Pointers and int are the same size */ # undef CONFIG_PTR_IS_NOT_INT #elif defined(__AVR__) -/* Select the small, 16-bit addressing model */ +# if defined(CONFIG_AVR_HAS_MEMX_PTR) + /* I-space access qualifiers needed by Harvard architecture */ -# define CONFIG_SMALL_MEMORY 1 +# define IOBJ __flash +# define IPTR __memx + +# else +/* No I-space access qualifiers */ + +# define IOBJ +# define IPTR +# endif + +/* Select the small, 16-bit addressing model (for D-Space) */ + +# define CONFIG_SMALL_MEMORY 1 /* Long and int are not the same size */ -# define CONFIG_LONG_IS_NOT_INT 1 +# define CONFIG_LONG_IS_NOT_INT 1 /* Pointers and int are the same size */ @@ -159,9 +179,14 @@ # define CONFIG_HAVE_FARPOINTER 1 #elif defined(__mc68hc1x__) +/* No I-space access qualifiers */ + +# define IOBJ +# define IPTR + /* Select the small, 16-bit addressing model */ -# define CONFIG_SMALL_MEMORY 1 +# define CONFIG_SMALL_MEMORY 1 /* Normally, mc68hc1x code is compiled with the -mshort option * which results in a 16-bit integer. If -mnoshort is defined @@ -171,22 +196,28 @@ # if __INT__ == 16 /* int is 16-bits, long is 32-bits */ -# define CONFIG_LONG_IS_NOT_INT 1 +# define CONFIG_LONG_IS_NOT_INT 1 -/* Pointers and int are the same size (16-bits) */ +/* Pointers and int are the same size (16-bits) */ # undef CONFIG_PTR_IS_NOT_INT -#else +# else /* int and long are both 32-bits */ # undef CONFIG_LONG_IS_NOT_INT -/* Pointers and int are NOT the same size */ +/* Pointers and int are NOT the same size */ -# define CONFIG_PTR_IS_NOT_INT 1 -#endif +# define CONFIG_PTR_IS_NOT_INT 1 +# endif #else + +/* No I-space access qualifiers */ + +# define IOBJ +# define IPTR + /* Select the large, 32-bit addressing model */ # undef CONFIG_SMALL_MEMORY @@ -347,6 +378,11 @@ # define CONFIG_HAVE_FUNCTIONNAME 1 /* Has __FUNCTION__ */ # define CONFIG_HAVE_FILENAME 1 /* Has __FILE__ */ +/* No I-space access qualifiers */ + +# define IOBJ +# define IPTR + /* Attributes * * The Zilog compiler does not support weak symbols @@ -476,11 +512,11 @@ #endif /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #ifdef __cplusplus @@ -491,7 +527,6 @@ extern "C" #define EXTERN extern #endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/crypto/aes.h b/include/nuttx/crypto/aes.h new file mode 100644 index 0000000000000000000000000000000000000000..5c4d3e805078f942797947abfb9a1560912faeca --- /dev/null +++ b/include/nuttx/crypto/aes.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * include/nuttx/crypto/aes.h + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Extracted from the CC3000 Host Driver Implementation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of Texas Instruments Incorporated 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 __INCLUDE_NUTTX_CRYPTO_AES_H +#define __INCLUDE_NUTTX_CRYPTO_AES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AES128_KEY_SIZE 16 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes +/**************************************************************************** + +/**************************************************************************** + * Name: aes_encrypt + * + * Description: + * AES128 encryption: Given AES128 key and 16 bytes plain text, cipher + * text of 16 bytes is computed. The AES implementation is in mode ECB + * (Electronic Code Book). + * + * Input Parameters: + * key AES128 key of size 16 bytes + * state 16 bytes of plain text and cipher text + * + * Returned Value + * None + * + ****************************************************************************/ + +void aes_encrypt(FAR uint8_t *state, FAR const uint8_t *key); + +/**************************************************************************** + * Name: aes_decrypt + * + * Description: + * AES128 decryption: Given AES128 key and 16 bytes cipher text, plain + * text of 16 bytes is computed The AES implementation is in mode ECB + * (Electronic Code Book). + * + * Input Parameters: + * key AES128 key of size 16 bytes + * state 16 bytes of plain text and cipher text + * + * Returned Value + * None + * + ****************************************************************************/ + +void aes_decrypt(FAR uint8_t *state, FAR const uint8_t *key); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __INCLUDE_NUTTX_CRYPTO_AES_H */ diff --git a/include/nuttx/crypto/tea.h b/include/nuttx/crypto/tea.h new file mode 100644 index 0000000000000000000000000000000000000000..1b568150a050f70b01e4f25adb5618844d4dd959 --- /dev/null +++ b/include/nuttx/crypto/tea.h @@ -0,0 +1,77 @@ +/**************************************************************************** + * include/nuttx/crypto/tea.h + * Tiny Encryption Algorithm + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm: "Following is + * an adaptation of the reference encryption and decryption routines in C, + * released into the public domain by David Wheeler and Roger Needham." + * + * 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 __INCLUDE_NUTTX_CRYPTO_TEA_H +#define __INCLUDE_NUTTX_CRYPTO_TEA_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tea_encrypt + * + * Input Parameters: + * value = 2 x 32-bit value (input/output) + * key = 4 x 32-bit Cache key (input) + * + ****************************************************************************/ + +void tea_encrypt(FAR uint32_t *value, FAR const uint32_t *key); + +/**************************************************************************** + * Name: tea_decrypt + * + * Input Parameters: + * value = 2 x 32-bit value (input/output) + * key = 4 x 32-bit Cache key (input) + * + ****************************************************************************/ + +void tea_decrypt(FAR uint32_t *value, FAR const uint32_t *key); + +#endif /* __INCLUDE_NUTTX_CRYPTO_TEA_H */ + diff --git a/include/nuttx/float.h b/include/nuttx/float.h index a8e4aa28b56091d1d65cb0c7aa46b734b59c1562..a4d8945ee5773b5d045720bee9fdeb7bf0098bb1 100644 --- a/include/nuttx/float.h +++ b/include/nuttx/float.h @@ -61,7 +61,7 @@ #define FLT_MANT_DIG 24 -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MANT_DIG 53 #else # define DBL_MANT_DIG FLT_MANT_DIG @@ -88,7 +88,7 @@ #define FLT_DIG 6 -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_DIG 15 /* 10 */ #else # define DBL_DIG FLT_DIG @@ -106,7 +106,7 @@ #define FLT_MIN_EXP (-125) -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MIN_EXP (-1021) #else # define DBL_MIN_EXP FLT_MIN_EXP @@ -124,7 +124,7 @@ #define FLT_MIN_10_EXP (-37) -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MIN_10_EXP (-307) /* -37 */ #else # define DBL_MIN_10_EXP FLT_MIN_10_EXP @@ -142,7 +142,7 @@ #define FLT_MAX_EXP 128 -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MAX_EXP 1024 #else # define DBL_MAX_EXP FLT_MAX_EXP @@ -160,7 +160,7 @@ #define FLT_MAX_10_EXP 38 /* 37 */ -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MAX_10_EXP 308 /* 37 */ #else # define DBL_MAX_10_EXP FLT_MAX_10_EXP @@ -176,7 +176,7 @@ #define FLT_MAX 3.40282347e+38F /* 1E+37 */ -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_MAX 1.7976931348623157e+308 /* 1E+37 */ #else # define DBL_MAX FLT_MAX @@ -194,7 +194,7 @@ #define FLT_EPSILON 1.1920929e-07F /* 1E-5 */ -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE # define DBL_EPSILON 2.2204460492503131e-16 /* 1E-9 */ #else # define DBL_EPSILON FLT_EPSILON @@ -210,7 +210,7 @@ #define FLT_MIN 1.17549435e-38F /* 1E-37 */ -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE #define DBL_MIN 2.2250738585072014e-308 /* 1E-37 */ #else # define DBL_MIN FLT_MIN diff --git a/include/nuttx/fs/dirent.h b/include/nuttx/fs/dirent.h index 26b3d7bc2685187a469b05d1ad4ffd0241f116f4..efd270fbeecc325bd31857df7bcd3b40855d668c 100644 --- a/include/nuttx/fs/dirent.h +++ b/include/nuttx/fs/dirent.h @@ -102,6 +102,19 @@ struct fs_romfsdir_s }; #endif /* CONFIG_FS_ROMFS */ +#ifdef CONFIG_FS_TMPFS +/* For TMPFS, we need the directory object and an index into the directory + * entries. + */ + +struct tmpfs_directory_s; /* Forward reference */ +struct fs_tmpfsdir_s +{ + FAR struct tmpfs_directory_s *tf_tdo; /* Directory being enumerated */ + unsigned int tf_index; /* Directory index */ +}; +#endif /* CONFIG_FS_TMPFS */ + #ifdef CONFIG_FS_BINFS /* The apps/ pseudo bin/ directory. The state value is simply an index */ @@ -164,6 +177,17 @@ struct fs_unionfsdir_s }; #endif +#ifdef CONFIG_FS_HOSTFS +/* HOSTFS provides mapping to directories on the host machine in the + * sim environment. + */ + +struct fs_hostfsdir_s +{ + FAR void * fs_dir; /* Opaque pointer to host DIR * */ +}; +#endif + #endif /* CONFIG_DISABLE_MOUNTPOINT */ struct fs_dirent_s @@ -209,6 +233,9 @@ struct fs_dirent_s #ifdef CONFIG_FS_ROMFS struct fs_romfsdir_s romfs; #endif +#ifdef CONFIG_FS_TMPFS + struct fs_tmpfsdir_s tmpfs; +#endif #ifdef CONFIG_FS_BINFS struct fs_binfsdir_s binfs; #endif @@ -227,6 +254,9 @@ struct fs_dirent_s #ifdef CONFIG_FS_UNIONFS struct fs_unionfsdir_s unionfs; #endif +#ifdef CONFIG_FS_HOSTFS + struct fs_hostfsdir_s hostfs; +#endif #endif /* !CONFIG_DISABLE_MOUNTPOINT */ } u; @@ -236,7 +266,7 @@ struct fs_dirent_s }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 3d2d6c3c7332484ab21729a9bd713954bc5f2a34..8de9a1b0953e1cf4211ba1698cbd372471fc7dad 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -352,7 +352,7 @@ typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint, #endif /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #undef EXTERN @@ -897,29 +897,6 @@ void devcrypto_register(void); void devzero_register(void); -/* drivers/loop.c ***********************************************************/ -/**************************************************************************** - * Name: losetup - * - * Description: - * Setup the loop device so that it exports the file referenced by 'filename' - * as a block device. - * - ****************************************************************************/ - -int losetup(FAR const char *devname, FAR const char *filename, - uint16_t sectsize, off_t offset, bool readonly); - -/**************************************************************************** - * Name: loteardown - * - * Description: - * Undo the setup performed by losetup - * - ****************************************************************************/ - -int loteardown(FAR const char *devname); - /* drivers/bch/bchdev_register.c ********************************************/ /**************************************************************************** * Name: bchdev_register diff --git a/include/nuttx/fs/hostfs.h b/include/nuttx/fs/hostfs.h new file mode 100644 index 0000000000000000000000000000000000000000..0a57797e57b97b4e8b002a27055c5a2facb54d14 --- /dev/null +++ b/include/nuttx/fs/hostfs.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * include/nuttx/fs/hostfs.h + * + * Copyright (C) 2015 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * 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 __INCLUDE_NUTTX_FS_HOSTFS_H +#define __INCLUDE_NUTTX_FS_HOSTFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define HOST_ST_MODE_REG 0x01000 +#define HOST_ST_MODE_DIR 0x02000 +#define HOST_ST_MODE_CHR 0x04000 +#define HOST_ST_MODE_BLK 0x08000 +#define HOST_ST_MODE_PIPE 0x10000 +#define HOST_ST_MODE_LINK 0x20000 + +#define HOSTFS_FLAG_RDOK 0x0001 +#define HOSTFS_FLAG_WROK 0x0002 +#define HOSTFS_FLAG_CREAT 0x0004 +#define HOSTFS_FLAG_EXCL 0x0008 +#define HOSTFS_FLAG_APPEND 0x0010 +#define HOSTFS_FLAG_TRUNC 0x0020 + +#define HOSTFS_DTYPE_FILE 0x0001 +#define HOSTFS_DTYPE_CHR 0x0002 +#define HOSTFS_DTYPE_BLK 0x0004 +#define HOSTFS_DTYPE_DIRECTORY 0x0008 + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +struct host_dirent_s +{ + size_t d_ino; + size_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; +}; + +struct host_statfs_s +{ + size_t f_type; /* Type of file system */ + size_t f_bsize; /* Optimal transfer block size */ + size_t f_blocks; /* Total data blocks in the file system */ + size_t f_bfree; /* Free blocks */ + size_t f_bavail; /* Free blocks available */ + size_t f_files; /* Total file nodes in file system */ + size_t f_ffree; /* Free file nodes in fs */ + size_t f_fsid; /* File Systme ID */ + size_t f_namelen; /* Max length of filenames */ + size_t f_frsize; /* Fragment size */ +}; + +struct host_stat_s +{ + int st_dev; /* ID of the device containing file */ + size_t st_ino; /* inode number */ + size_t st_mode; /* protection */ + size_t st_nlink; /* number of hard links */ + size_t st_uid; /* user ID of owner */ + size_t st_gid; /* group ID of owner */ + size_t st_rdev; /* device ID */ + size_t st_size; /* total size, in bytes */ + size_t st_blksize; /* blocksize for file system I/O */ + size_t st_blocks; /* number of 512B blocks allocated */ + size_t st_atim; /* time of last access */ + size_t st_mtim; /* time of last modification */ + size_t st_ctim; /* time of last status change */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int host_open(const char *pathname, int flags, int mode); +int host_close(int fd); +ssize_t host_read(int fd, void* buf, size_t count); +ssize_t host_write(int fd, const void *buf, size_t count); +off_t host_lseek(int fd, off_t offset, int whence); +int host_ioctl(int fd, int request, unsigned long arg); +void host_sync(int fd); +int host_dup(int fd); +void *host_opendir(const char *name); +int host_readdir(void* dirp, struct host_dirent_s* entry); +void host_rewinddir(void* dirp); +int host_closedir(void* dirp); +int host_statfs(const char *path, struct host_statfs_s *buf); +int host_unlink(const char *pathname); +int host_mkdir(const char *pathname, mode_t mode); +int host_rmdir(const char *pathname); +int host_rename(const char *oldpath, const char *newpath); +int host_stat(const char *path, struct host_stat_s *buf); + +#endif /* __INCLUDE_NUTTX_FS_HOSTFS_H */ diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index f047d38906867ed2ae7e97f4545969d6fb842477..e404057d7e6729a019242a4ca75aac2e9a716e9c 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -77,7 +77,16 @@ #define _RTCBASE (0x1800) /* RTC ioctl commands */ #define _RELAYBASE (0x1900) /* Relay devices ioctl commands */ #define _CANBASE (0x1a00) /* CAN ioctl commands */ -#define _BOARDBASE (0x1b00) /* boardctl ioctl commands */ +#define _BTNBASE (0x1b00) /* Button ioctl commands */ +#define _ULEDBASE (0x1c00) /* User LED ioctl commands */ +#define _ZCBASE (0x1d00) /* Zero Cross ioctl commands */ +#define _LOOPBASE (0x1e00) /* Loop device commands */ +#define _MODEMBASE (0x1f00) /* Modem ioctl commands */ +#define _I2CBASE (0x2000) /* I2C driver commands */ + +/* boardctl commands share the same number space */ + +#define _BOARDBASE (0xff00) /* boardctl commands */ /* Macros used to manage ioctl commands */ @@ -217,25 +226,6 @@ #define _MTDIOCVALID(c) (_IOC_TYPE(c)==_MTDIOCBASE) #define _MTDIOC(nr) _IOC(_MTDIOCBASE,nr) -#define MTDIOC_GEOMETRY _MTDIOC(0x0001) /* IN: Pointer to write-able struct - * mtd_geometry_s in which to receive - * receive geometry data (see mtd.h) - * OUT: Geometry structure is populated - * with data for the MTD */ -#define MTDIOC_XIPBASE _MTDIOC(0x0002) /* IN: Pointer to pointer to void in - * which to received the XIP base. - * OUT: If media is directly accessible, - * return (void*) base address - * of device memory */ -#define MTDIOC_BULKERASE _MTDIOC(0x0003) /* IN: None - * OUT: None */ -#define MTDIOC_SETSPEED _MTDIOC(0x0004) /* IN: New bus speed in Hz - * OUT: None */ -#define MTDIOC_EXTENDED _MTDIOC(0x0005) /* IN: unsigned long - * 0=Use normal memory region - * 1=Use alternate/extended memory - * OUT: None */ - /* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/ #define _ARPIOCVALID(c) (_IOC_TYPE(c)==_ARPIOCBASE) @@ -286,56 +276,56 @@ /* NuttX Audio driver ioctl definitions *************************************/ /* (see nuttx/audio/audio.h) */ -#define _AUDIOIOCVALID(c) (_IOC_TYPE(c)==_AUDIOIOCBASE) -#define _AUDIOIOC(nr) _IOC(_AUDIOIOCBASE,nr) +#define _AUDIOIOCVALID(c) (_IOC_TYPE(c)==_AUDIOIOCBASE) +#define _AUDIOIOC(nr) _IOC(_AUDIOIOCBASE,nr) /* Segment LCD driver ioctl definitions *************************************/ /* (see nuttx/include/lcd/slcd_codec.h */ -#define _SLCDIOCVALID(c) (_IOC_TYPE(c)==_SLCDIOCBASE) -#define _SLCDIOC(nr) _IOC(_SLCDIOCBASE,nr) +#define _SLCDIOCVALID(c) (_IOC_TYPE(c)==_SLCDIOCBASE) +#define _SLCDIOC(nr) _IOC(_SLCDIOCBASE,nr) /* Wireless driver ioctl definitions ****************************************/ /* (see nuttx/include/wireless/wireless.h */ -#define _WLIOCVALID(c) (_IOC_TYPE(c)==_WLIOCBASE) -#define _WLIOC(nr) _IOC(_WLIOCBASE,nr) +#define _WLIOCVALID(c) (_IOC_TYPE(c)==_WLIOCBASE) +#define _WLIOC(nr) _IOC(_WLIOCBASE,nr) /* Application Config Data driver ioctl definitions *************************/ /* (see nuttx/include/configdata.h */ -#define _CFGDIOCVALID(c) (_IOC_TYPE(c)==_CFGDIOCBASE) -#define _CFGDIOC(nr) _IOC(_CFGDIOCBASE,nr) +#define _CFGDIOCVALID(c) (_IOC_TYPE(c)==_CFGDIOCBASE) +#define _CFGDIOC(nr) _IOC(_CFGDIOCBASE,nr) /* Timer driver ioctl commands **********************************************/ /* (see nuttx/include/timer.h */ -#define _TCIOCVALID(c) (_IOC_TYPE(c)==_TCIOCBASE) -#define _TCIOC(nr) _IOC(_TCIOCBASE,nr) +#define _TCIOCVALID(c) (_IOC_TYPE(c)==_TCIOCBASE) +#define _TCIOC(nr) _IOC(_TCIOCBASE,nr) /* Discrete joystick driver ioctl definitions *******************************/ /* (see nuttx/include/input/djoystick.h */ -#define _DJOYIOCVALID(c) (_IOC_TYPE(c)==_DJOYBASE) -#define _DJOYIOC(nr) _IOC(_DJOYBASE,nr) +#define _DJOYIOCVALID(c) (_IOC_TYPE(c)==_DJOYBASE) +#define _DJOYIOC(nr) _IOC(_DJOYBASE,nr) /* Analog joystick driver ioctl definitions *********************************/ /* (see nuttx/include/input/ajoystick.h */ -#define _AJOYIOCVALID(c) (_IOC_TYPE(c)==_AJOYBASE) -#define _AJOYIOC(nr) _IOC(_AJOYBASE,nr) +#define _AJOYIOCVALID(c) (_IOC_TYPE(c)==_AJOYBASE) +#define _AJOYIOC(nr) _IOC(_AJOYBASE,nr) /* FIFOs and pipe driver ioctl definitions **********************************/ -#define _PIPEIOCVALID(c) (_IOC_TYPE(c)==_PIPEBASE) -#define _PIPEIOC(nr) _IOC(_PIPEBASE,nr) +#define _PIPEIOCVALID(c) (_IOC_TYPE(c)==_PIPEBASE) +#define _PIPEIOC(nr) _IOC(_PIPEBASE,nr) -#define PIPEIOC_POLICY _PIPEIOC(0x0001) /* Set buffer policy - * IN: unsigned long integer - * 0=free on last close - * (default) - * 1=fre when empty - * OUT: None */ +#define PIPEIOC_POLICY _PIPEIOC(0x0001) /* Set buffer policy + * IN: unsigned long integer + * 0=free on last close + * (default) + * 1=fre when empty + * OUT: None */ /* RTC driver ioctl definitions *********************************************/ /* (see nuttx/include/rtc.h */ @@ -346,14 +336,50 @@ /* Relay driver ioctl definitions *******************************************/ /* (see nuttx/power/relay.h */ -#define _RELAYIOCVALID(c) (_IOC_TYPE(c)==_RELAYBASE) -#define _RELAYIOC(nr) _IOC(_RELAYBASE,nr) +#define _RELAYIOCVALID(c) (_IOC_TYPE(c)==_RELAYBASE) +#define _RELAYIOC(nr) _IOC(_RELAYBASE,nr) /* CAN driver ioctl definitions *********************************************/ /* (see nuttx/can.h */ -#define _CANIOCVALID(c) (_IOC_TYPE(c)==_CANBASE) -#define _CANIOC(nr) _IOC(_CANBASE,nr) +#define _CANIOCVALID(c) (_IOC_TYPE(c)==_CANBASE) +#define _CANIOC(nr) _IOC(_CANBASE,nr) + +/* Button driver ioctl definitions ******************************************/ +/* (see nuttx/input/buttons.h */ + +#define _BTNIOCVALID(c) (_IOC_TYPE(c)==_BTNBASE) +#define _BTNIOC(nr) _IOC(_BTNBASE,nr) + +/* User LED driver ioctl definitions ****************************************/ +/* (see nuttx/leds/usersled.h */ + +#define _ULEDIOCVALID(c) (_IOC_TYPE(c)==_ULEDBASE) +#define _ULEDIOC(nr) _IOC(_ULEDBASE,nr) + +/* Zero Cross driver ioctl definitions **************************************/ +/* (see nuttx/include/sensor/zerocross.h */ + +#define _ZCIOCVALID(c) (_IOC_TYPE(c)==_ZCBASE) +#define _ZCIOC(nr) _IOC(_ZCBASE,nr) + +/* Loop driver ioctl definitions ********************************************/ +/* (see nuttx/include/fs/loop.h */ + +#define _LOOPIOCVALID(c) (_IOC_TYPE(c)==_LOOPBASE) +#define _LOOPIOC(nr) _IOC(_LOOPBASE,nr) + +/* Modem driver ioctl definitions ********************************************/ +/* see nuttx/include/modem/*.h */ + +#define _MODEMIOCVALID(c) (_IOC_TYPE(c)==_MODEMBASE) +#define _MODEMIOC(nr) _IOC(_MODEMBASE,nr) + +/* I2C driver ioctl definitions **********************************************/ +/* see nuttx/include/i2c/i2c_master.h */ + +#define _I2CIOCVALID(c) (_IOC_TYPE(c)==_I2CBASE) +#define _I2CIOC(nr) _IOC(_I2CBASE,nr) /* boardctl() command definitions *******************************************/ diff --git a/include/nuttx/fs/loop.h b/include/nuttx/fs/loop.h new file mode 100644 index 0000000000000000000000000000000000000000..ee1efd69f49adcda716ae0ab905b04d7348a7073 --- /dev/null +++ b/include/nuttx/fs/loop.h @@ -0,0 +1,149 @@ +/**************************************************************************** + * include/nuttx/fs/loop.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_FS_LOOP_H +#define __INCLUDE_NUTTX_FS_LOOP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEV_LOOP +/* Loop device IOCTL commands */ + +/* Command: LOOPIOC_SETUP + * Description: Setup the loop device + * Argument: A pointer to a read-only instance of struct losetup_s. + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + +/* Command: LOOPIOC_TEARDOWN + * Description: Teardown a loop device previously setup vis LOOPIOC_SETUP + * Argument: A read-able pointer to the path of the device to be + * torn down + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + +#define LOOPIOC_SETUP _LOOPIOC(0x0001) +#define LOOPIOC_TEARDOWN _LOOPIOC(0x0002) + +#endif + +/**************************************************************************** + * Type Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEV_LOOP +/* This is the structure referred to in the argument to the LOOPIOC_SETUP + * IOCTL command. + */ + +struct losetup_s +{ + FAR const char *devname; /* The loop block device to be created */ + FAR const char *filename; /* The file or character device to use */ + uint16_t sectsize; /* The sector size to use with the block device */ + off_t offset; /* An offset that may be applied to the device */ + bool readonly; /* True: Read access will be supported only */ +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __KERNEL__ +/* These are internal OS interface and are not available to applications */ + +/**************************************************************************** + * Name: loop_register + * + * Description: + * Register /dev/loop + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_LOOP +void loop_register(void); +#endif + +/**************************************************************************** + * Name: losetup + * + * Description: + * Setup the loop device so that it exports the file referenced by 'filename' + * as a block device. + * + ****************************************************************************/ + +int losetup(FAR const char *devname, FAR const char *filename, + uint16_t sectsize, off_t offset, bool readonly); + +/**************************************************************************** + * Name: loteardown + * + * Description: + * Undo the setup performed by losetup + * + ****************************************************************************/ + +int loteardown(FAR const char *devname); +#endif /* __KERNEL __ */ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_FS_LOOP_H */ diff --git a/include/nuttx/fs/mkfatfs.h b/include/nuttx/fs/mkfatfs.h index e7a5a4c904069153b1ad5f14b2b3f4c67e7e4751..03ca6ef956a5e72e9cdecd4128fa2c8bfa460e5e 100644 --- a/include/nuttx/fs/mkfatfs.h +++ b/include/nuttx/fs/mkfatfs.h @@ -95,7 +95,7 @@ struct fat_format_s }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/nuttx/fs/procfs.h b/include/nuttx/fs/procfs.h index 7dfb6da12363f74c47b4d7578821c6d2f865e621..f11046735ed48fa3a6daf5726660a8e3088a20a2 100644 --- a/include/nuttx/fs/procfs.h +++ b/include/nuttx/fs/procfs.h @@ -180,6 +180,28 @@ size_t procfs_memcpy(FAR const char *src, size_t srclen, FAR char *dest, size_t destlen, off_t *offset); +/**************************************************************************** + * Name: procfs_register + * + * Description: + * Add a new entry to the procfs file system. + * + * NOTE: This function should be called *prior* to mounting the procfs + * file system to prevent concurrency problems with the modification of + * the procfs data set while it is in use. + * + * Input Parameters: + * entry - Describes the entry to be registered. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure + * + ****************************************************************************/ + +#ifdef CONFIG_FS_PROCFS_REGISTER +int procfs_register(FAR const struct procfs_entry_s *entry); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/fs/ramdisk.h b/include/nuttx/fs/ramdisk.h index 8721839775f0a2e2e2de2dc3fbf02e16d0a1d0cd..0f425c46aaf00ae852189d0ba7fd6b61ecd94239 100644 --- a/include/nuttx/fs/ramdisk.h +++ b/include/nuttx/fs/ramdisk.h @@ -94,9 +94,9 @@ extern "C" #ifdef CONFIG_FS_WRITABLE int ramdisk_register(int minor, FAR uint8_t *buffer, uint32_t nsectors, uint16_t sectize, uint8_t rdflags); -#define romdisk_register(m,b,n,s) ramdisk_register(m,b,n,s,0) +#define romdisk_register(m,b,n,s) ramdisk_register(m,(FAR uint8_t *)b,n,s,0) #else -int romdisk_register(int minor, FAR uint8_t *buffer, uint32_t nsectors, +int romdisk_register(int minor, FAR const uint8_t *buffer, uint32_t nsectors, uint16_t sectize); #endif diff --git a/include/nuttx/fs/smart.h b/include/nuttx/fs/smart.h index 2621dd77f626d79d077668ff59961aa42a72ad2a..ec217466aad6d81f31c10c78276a538c1d2d8ea5 100644 --- a/include/nuttx/fs/smart.h +++ b/include/nuttx/fs/smart.h @@ -45,6 +45,7 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -55,6 +56,36 @@ #define SMART_FMT_ISFORMATTED 0x01 #define SMART_FMT_HASBYTEWRITE 0x02 +/* The logical sector number of the root directory. */ + +#define SMARTFS_ROOT_DIR_SECTOR 3 + +/* Defines the sector types */ + +#define SMARTFS_SECTOR_TYPE_DIR 1 +#define SMARTFS_SECTOR_TYPE_FILE 2 + +#ifdef CONFIG_SMART_DEV_LOOP +/* Loop device IOCTL commands */ + +/* Command: SMART_LOOPIOC_SETUP + * Description: Setup the loop device + * Argument: A pointer to a read-only instance of struct losetup_s. + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + +/* Command: SMART_LOOPIOC_TEARDOWN + * Description: Teardown a loop device previously setup vis LOOPIOC_SETUP + * Argument: A read-able pointer to the path of the device to be + * torn down + * Dependencies: The loop device must be enabled (CONFIG_DEV_LOOP=y) + */ + +#define SMART_LOOPIOC_SETUP _LOOPIOC(0x0001) +#define SMART_LOOPIOC_TEARDOWN _LOOPIOC(0x0002) + +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -103,6 +134,22 @@ struct smart_procfs_data_s }; #endif +#ifdef CONFIG_SMART_DEV_LOOP +/* This is the structure referred to in the argument to the LOOPIOC_SETUP + * IOCTL command. + */ + +struct smart_losetup_s +{ + FAR const char *filename; /* The file or character device to use */ + int minor; /* The minor number of thedevice */ + int erasesize; /* The erase size to use on the file */ + int sectsize; /* The sector / page size of the file */ + off_t offset; /* An offset that may be applied to the device */ + bool readonly; /* True: Read access will be supported only */ +}; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/include/nuttx/i2c.h b/include/nuttx/i2c/i2c_master.h similarity index 52% rename from include/nuttx/i2c.h rename to include/nuttx/i2c/i2c_master.h index 6395fde925db0a1d47b7320de61251bfd76a5bcb..1938bcbfa10de5db6b2b27899e75748d0cfed618 100644 --- a/include/nuttx/i2c.h +++ b/include/nuttx/i2c/i2c_master.h @@ -1,7 +1,7 @@ /**************************************************************************** - * include/nuttx/i2c.h + * include/nuttx/i2c/i2c_master.h * - * Copyright(C) 2009-2012 Gregory Nutt. All rights reserved. + * Copyright(C) 2009-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __INCLUDE_NUTTX_I2C_H -#define __INCLUDE_NUTTX_I2C_H +#ifndef __INCLUDE_NUTTX_I2C_I2C_MASTER_H +#define __INCLUDE_NUTTX_I2C_I2C_MASTER_H /**************************************************************************** * Included Files @@ -42,22 +42,14 @@ #include +#include #include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* If a dynamic timeout is selected, then a non-negative, non-zero micro- - * seconds per byte value must be provided as well. - */ - -#ifdef CONFIG_STM32_I2C_DYNTIMEO -# if CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE < 1 -# warning "Ignoring CONFIG_STM32_I2C_DYNTIMEO because of CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE" -# undef CONFIG_STM32_I2C_DYNTIMEO -# endif -#endif - /* I2C address calculation. Convert 7- and 10-bit address to 8-bit and * 16-bit read/write address */ @@ -88,155 +80,70 @@ #define I2C_M_NORESTART 0x0080 /* Message should not begin with * (re-)start of transfer */ -/* Access macros ************************************************************/ - -/**************************************************************************** - * Name: I2C_SETFREQUENCY - * - * Description: - * Set the I2C frequency. This frequency will be retained in the struct - * i2c_dev_s instance and will be used with all transfers. Required. - * - * Input Parameters: - * dev - Device-specific state data - * frequency - The I2C frequency requested - * - * Returned Value: - * Returns the actual frequency selected - * - ****************************************************************************/ - -#define I2C_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f)) - -/**************************************************************************** - * Name: I2C_SETADDRESS - * - * Description: - * Set the I2C slave address. This frequency will be retained in the struct - * i2c_dev_s instance and will be used with all transfers. Required. - * - * Input Parameters: - * dev - Device-specific state data - * address - The I2C slave address - * nbits - The number of address bits provided (7 or 10) - * - * Returned Value: - * Returns OK on success; a negated errno on failure. - * - ****************************************************************************/ - -#define I2C_SETADDRESS(d,a,n) ((d)->ops->setaddress(d,a,n)) - -/**************************************************************************** - * Name: I2C_SETOWNADDRESS - * - * Description: - * Set our own I2C address. Calling this function enables Slave mode and - * disables Master mode on given instance (note that I2C is a bus, where - * multiple masters and slave may be handled by one device driver). - * - * One may register a callback to be notified about reception. During the - * slave mode reception, the function READ and WRITE must be used to - * to handle reads and writes from a master. - * - * Input Parameters: - * dev - Device-specific state data - * address - Our own slave address; If it is 0x00, then the device driver - * listens to general call - * nbits - The number of address bits provided (7 or 10) - * - * Returned Value: - * OK on valid address and if the same address has not been assigned - * to another instance sharing the same port. Otherwise ERROR is returned. - * - ****************************************************************************/ +/* I2C Character Driver IOCTL Commands **************************************/ +/* The I2C driver is intended to support application testing of the I2C bus. + * The I2C driver simply wraps an instance of struct i2c_dev_s and then + * provides the following IOCTL commands to access each method of the I2c + * interface. + */ -#define I2C_SETOWNADDRESS(d,a,n) ((d)->ops->setownaddress(d,a,n)) +/* Command: I2CIOC_TRANSFER + * Description: Perform an I2C transfer + * Argument: A reference to an instance of struct i2c_transfer_s. + * Dependencies: CONFIG_I2C_DRIVER + */ -/**************************************************************************** - * Name: I2C_WRITE - * - * Description: - * Send a block of data on I2C using the previously selected I2C - * frequency and slave address. Each write operational will be an 'atomic' - * operation in the sense that any other I2C actions will be serialized - * and pend until this write completes. Required. - * - * Input Parameters: - * dev - Device-specific state data - * buffer - A pointer to the read-only buffer of data to be written to device - * buflen - The number of bytes to send from the buffer - * - * Returned Value: - * 0: success, <0: A negated errno - * - ****************************************************************************/ +#define I2CIOC_TRANSFER _I2CIOC(0x0001) -#define I2C_WRITE(d,b,l) ((d)->ops->write(d,b,l)) +/* Command: I2CIOC_RESET + * Description: Perform an I2C bus reset in an attempt to break loose stuck + * I2C devices. + * Argument: None + * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET + */ -/**************************************************************************** - * Name: I2C_READ - * - * Description: - * Receive a block of data from I2C using the previously selected I2C - * frequency and slave address. Each read operational will be an 'atomic' - * operation in the sense that any other I2C actions will be serialized - * and pend until this read completes. Required. - * - * Input Parameters: - * dev - Device-specific state data - * buffer - A pointer to a buffer of data to receive the data from the device - * buflen - The requested number of bytes to be read - * - * Returned Value: - * 0: success, <0: A negated errno - * - ****************************************************************************/ +#define I2CIOC_RESET _I2CIOC(0x0002) -#define I2C_READ(d,b,l) ((d)->ops->read(d,b,l)) +/* Access macros ************************************************************/ /**************************************************************************** - * Name: I2C_WRITEREAD + * Name: I2C_TRANSFER * * Description: - * Send a block of data on I2C using the previously selected I2C - * frequency and slave address, followed by restarted read access. - * It provides a convenient wrapper to the transfer function. + * Perform a sequence of I2C transfers, each transfer is started with a + * START and the final transfer is completed with a STOP. Each sequence + * will be an 'atomic' operation in the sense that any other I2C actions + * will be serialized and pend until this sequence of transfers completes. * * Input Parameters: - * dev - Device-specific state data - * wbuffer - A pointer to the read-only buffer of data to be written to device - * wbuflen - The number of bytes to send from the buffer - * rbuffer - A pointer to a buffer of data to receive the data from the device - * rbuflen - The requested number of bytes to be read + * dev - Device-specific state data + * msgs - A pointer to a set of message descriptors + * count - The number of transfers to perform * * Returned Value: - * 0: success, <0: A negated errno + * The number of transfers completed * ****************************************************************************/ -#define I2C_WRITEREAD(d,wb,wl,rb,rl) ((d)->ops->writeread(d,wb,wl,rb,rl)) +#define I2C_TRANSFER(d,m,c) ((d)->ops->transfer(d,m,c)) -/**************************************************************************** - * Name: I2C_TRANSFER +/************************************************************************************ + * Name: I2C_RESET * * Description: - * Perform a sequence of I2C transfers, each transfer is started with a - * START and the final transfer is completed with a STOP. Each sequence - * will be an 'atomic' operation in the sense that any other I2C actions - * will be serialized and pend until this read completes. Optional. + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. * * Input Parameters: - * dev - Device-specific state data - * msgs - A pointer to a set of message descriptors - * msgcount - The number of transfers to perform + * dev - Device-specific state data * * Returned Value: - * The number of transfers completed + * Zero (OK) on success; a negated errno value on failure. * - ****************************************************************************/ + ************************************************************************************/ -#define I2C_TRANSFER(d,m,c) ((d)->ops->transfer(d,m,c)) +#ifdef CONFIG_I2C_RESET +# define I2C_RESET(d) ((d)->ops->reset(d)) +#endif /**************************************************************************** * Public Types @@ -244,30 +151,29 @@ /* The I2C vtable */ -struct i2c_dev_s; +struct i2c_master_s; struct i2c_msg_s; struct i2c_ops_s { - uint32_t (*setfrequency)(FAR struct i2c_dev_s *dev, uint32_t frequency); - int (*setaddress)(FAR struct i2c_dev_s *dev, int addr, int nbits); - int (*write)(FAR struct i2c_dev_s *dev, const uint8_t *buffer, - int buflen); - int (*read)(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen); -#ifdef CONFIG_I2C_WRITEREAD - int (*writeread)(FAR struct i2c_dev_s *inst, const uint8_t *wbuffer, - int wbuflen, uint8_t *rbuffer, int rbuflen); -#endif -#ifdef CONFIG_I2C_TRANSFER - int (*transfer)(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, - int count); -#endif -#ifdef CONFIG_I2C_SLAVE - int (*setownaddress)(FAR struct i2c_dev_s *dev, int addr, int nbits); - int (*registercallback)(FAR struct i2c_dev_s *dev, - int (*callback)(FAR void *arg), FAR void *arg); + int (*transfer)(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET + int (*reset)(FAR struct i2c_master_s *dev); #endif }; +/* This structure contains the full state of I2C as needed for a specific + * transfer. It is passed to I2C methods so that I2C transfer may be + * performed in a thread safe manner. + */ + +struct i2c_config_s +{ + uint32_t frequency; /* I2C frequency */ + uint16_t address; /* I2C address (7- or 10-bit) */ + uint8_t addrlen; /* I2C address length (7 or 10 bits) */ +}; + /* I2C transaction segment beginning with a START. A number of these can * be transferred together to form an arbitrary sequence of write/read transfer * to an I2C slave device. @@ -275,10 +181,11 @@ struct i2c_ops_s struct i2c_msg_s { - uint16_t addr; /* Slave address */ - uint16_t flags; /* See I2C_M_* definitions */ - uint8_t *buffer; - int length; + uint32_t frequency; /* I2C frequency */ + uint16_t addr; /* Slave address (7- or 10-bit) */ + uint16_t flags; /* See I2C_M_* definitions */ + FAR uint8_t *buffer; /* Buffer to be transferred */ + ssize_t length; /* Length of the buffer in bytes */ }; /* I2C private data. This structure only defines the initial fields of the @@ -286,9 +193,19 @@ struct i2c_msg_s * add additional, device specific fields after the vtable. */ -struct i2c_dev_s +struct i2c_master_s { - const struct i2c_ops_s *ops; /* I2C vtable */ + FAR const struct i2c_ops_s *ops; /* I2C vtable */ +}; + +/* This structure is used to communicate with the I2C character driver in + * order to perform IOCTL transfers. + */ + +struct i2c_transfer_s +{ + FAR struct i2c_msg_s *msgv; /* Array of I2C messages for the transfer */ + size_t msgc; /* Number of messges in the array. */ }; /**************************************************************************** @@ -305,55 +222,103 @@ extern "C" #endif /**************************************************************************** - * Name: up_i2cinitialize + * Name: i2c_register * * Description: - * Initialize the selected I2C port. And return a unique instance of struct - * struct i2c_dev_s. This function may be called to obtain multiple - * instances of the interface, each of which may be set up with a - * different frequency and slave address. + * Create and register the I2C character driver. + * + * The I2C character driver is a simple character driver that supports I2C + * transfers. The intent of this driver is to support I2C testing. It is + * not suitable for use in any real driver application. * - * Input Parameter: - * Port number (for hardware that has multiple I2C interfaces) + * Input Parameters: + * i2c - An instance of the lower half I2C driver + * bus - The I2C bus number. This will be used as the I2C device minor + * number. The I2C character device will be registered as /dev/i2cN + * where N is the minor number * * Returned Value: - * Valid I2C device structure reference on succcess; a NULL on failure + * OK if the driver was successfully register; A negated errno value is + * returned on any failure. * ****************************************************************************/ -FAR struct i2c_dev_s *up_i2cinitialize(int port); +#ifdef CONFIG_I2C_DRIVER +int i2c_register(FAR struct i2c_master_s *i2c, int bus); +#endif /**************************************************************************** - * Name: up_i2cuninitialize + * Name: i2c_writeread * * Description: - * De-initialize the selected I2C port, and power down the device. + * Send a block of data on I2C followed by restarted read access. This + * provides a convenient wrapper to the transfer function. * - * Input Parameter: - * Device structure as returned by the up_i2cinitialize() + * Input Parameters: + * dev - Device-specific state data + * config - Described the I2C configuration + * wbuffer - A pointer to the read-only buffer of data to be written to device + * wbuflen - The number of bytes to send from the buffer + * rbuffer - A pointer to a buffer of data to receive the data from the device + * rbuflen - The requested number of bytes to be read * * Returned Value: - * OK on success, ERROR when internal reference count mismatch or dev - * points to invalid hardware device. + * 0: success, <0: A negated errno * ****************************************************************************/ -int up_i2cuninitialize(FAR struct i2c_dev_s *dev); +int i2c_writeread(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR const uint8_t *wbuffer, int wbuflen, + FAR uint8_t *rbuffer, int rbuflen); -/************************************************************************************ - * Name: up_i2creset +/**************************************************************************** + * Name: i2c_write * * Description: - * Reset an I2C bus + * Send a block of data on I2C. Each write operation will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this write completes. * - ************************************************************************************/ + * Input Parameters: + * dev - Device-specific state data + * config - Described the I2C configuration + * buffer - A pointer to the read-only buffer of data to be written to device + * buflen - The number of bytes to send from the buffer + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ -#ifdef CONFIG_I2C_RESET -int up_i2creset(FAR struct i2c_dev_s *dev); -#endif +int i2c_write(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR const uint8_t *buffer, int buflen); + +/**************************************************************************** + * Name: i2c_read + * + * Description: + * Receive a block of data from I2C. Each read operation will be an + * 'atomic' operation in the sense that any other I2C actions will be + * serialized and pend until this read completes. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to a buffer of data to receive the data from the device + * buflen - The requested number of bytes to be read + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +int i2c_read(FAR struct i2c_master_s *dev, + FAR const struct i2c_config_s *config, + FAR uint8_t *buffer, int buflen); #undef EXTERN #if defined(__cplusplus) } #endif -#endif /* __INCLUDE_NUTTX_I2C_H */ +#endif /* __INCLUDE_NUTTX_I2C_I2C_MASTER_H */ diff --git a/include/nuttx/i2c/i2c_slave.h b/include/nuttx/i2c/i2c_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..048d88bca14aa711ba8e4529e236993ccbc668ff --- /dev/null +++ b/include/nuttx/i2c/i2c_slave.h @@ -0,0 +1,210 @@ +/**************************************************************************** + * include/nuttx/i2c/i2c_slave.h + * + * Copyright(C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_I2C_I2C_SLAVE_H +#define __INCLUDE_NUTTX_I2C_I2C_SLAVE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_I2C_SLAVE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* I2C address calculation. Convert 7- and 10-bit address to 8-bit and + * 16-bit read/write address + */ + +#define I2CS_READBIT 0x01 + +/* Convert 7- to 8-bit address */ + +#define I2CS_ADDR8(a) ((a) << 1) +#define I2CS_WRITEADDR8(a) I2CS_ADDR8(a) +#define I2CS_READADDR8(a) (I2CS_ADDR8(a) | I2CS_READBIT) + +/* Convert 10- to 16-bit address */ + +#define I2CS_ADDR10H(a) (0xf0 | (((a) >> 7) & 0x06)) +#define I2CS_ADDR10L(a) ((a) & 0xff) + +#define I2CS_WRITEADDR10H(a) I2CS_ADDR10H(a) +#define I2CS_WRITEADDR10L(a) I2CS_ADDR10L(a) + +#define I2CS_READADDR10H(a) (I2CS_ADDR10H(a) | I2CS_READBIT) +#define I2CS_READADDR10L(a) I2CS_ADDR10L(a) + +/* Access macros ************************************************************/ + +/**************************************************************************** + * Name: I2CS_SETOWNADDRESS + * + * Description: + * Set our own I2C address. Calling this function enables Slave mode and + * disables Master mode on the I2C bus (note that I2C is a bus, where + * multiple masters and slave may be handled by one device driver). + * + * One may register a callback to be notified about reception. During the + * slave mode reception, the methods READ and WRITE must be used to + * to handle reads and writes from a master. + * + * Input Parameters: + * dev - Device-specific state data + * address - Our own slave address; If it is 0x00, then the device driver + * listens to general call + * nbits - The number of address bits provided (7 or 10) + * + * Returned Value: + * OK on valid address and if the same address has not been assigned + * to another instance sharing the same port. Otherwise ERROR is returned. + * + ****************************************************************************/ + +#define I2CS_SETOWNADDRESS(d,a,n) ((d)->ops->setownaddress(d,a,n)) + +/**************************************************************************** + * Name: I2CS_WRITE + * + * Description: + * Send a block of data on I2C using the previously selected I2C + * frequency and slave address. Each write operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this write completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to the read-only buffer of data to be written to device + * buflen - The number of bytes to send from the buffer + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +#define I2CS_WRITE(d,b,l) ((d)->ops->write(d,b,l)) + +/**************************************************************************** + * Name: I2CS_READ + * + * Description: + * Receive a block of data from I2C using the previously selected I2C + * frequency and slave address. Each read operational will be an 'atomic' + * operation in the sense that any other I2C actions will be serialized + * and pend until this read completes. Required. + * + * Input Parameters: + * dev - Device-specific state data + * buffer - A pointer to a buffer of data to receive the data from the device + * buflen - The requested number of bytes to be read + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +#define I2CS_READ(d,b,l) ((d)->ops->read(d,b,l)) + +/**************************************************************************** + * Name: I2CS_REGISTERCALLBACK + * + * Description: + * Register to receive a callback when something is received on I2C. + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to be called when something has been received. + * arg - User provided argument to be used with the callback + * + * Returned Value: + * 0: success, <0: A negated errno + * + ****************************************************************************/ + +#define I2CS_REGISTERCALLBACK(d,c,a) ((d)->ops->registercallback(d,c,a)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The I2C vtable */ + +struct i2c_slave_s; +struct i2c_slaveops_s +{ + int (*setownaddress)(FAR struct i2c_slave_s *dev, int addr, int nbits); + int (*write)(FAR struct i2c_slave_s *dev, FAR const uint8_t *buffer, + int buflen); + int (*read)(FAR struct i2c_slave_s *dev, FAR uint8_t *buffer, + int buflen); + int (*registercallback)(FAR struct i2c_slave_s *dev, + int (*callback)(FAR void *arg), FAR void *arg); +}; + +/* I2C private data. This structure only defines the initial fields of the + * structure visible to the I2C client. The specific implementation may + * add additional, device specific fields after the vtable. + */ + +struct i2c_slave_s +{ + const struct i2c_slaveops_s *ops; /* I2C vtable */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* CONFIG_I2C_SLAVE */ +#endif /* __INCLUDE_NUTTX_I2C_I2C_SLAVE_H */ diff --git a/include/nuttx/init.h b/include/nuttx/init.h index 2038427f39abb2a62435a0c685c54f5af8b23012..cc1f4f72a96ca74722e717a65d47cd9016428f4b 100644 --- a/include/nuttx/init.h +++ b/include/nuttx/init.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/init.h * - * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2011, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,12 +43,47 @@ #include #include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Macros for testing which OS services are available at this phase of + * initialization. + */ + +#define OSINIT_MM_READY() (g_os_initstate >= OSINIT_MEMORY) +#define OSINIT_HW_READY() (g_os_initstate >= OSINIT_HARDWARE) +#define OSINIT_OS_READY() (g_os_initstate >= OSINIT_OSREADY) +#define OSINIT_OS_INITIALIZING() (g_os_initstate < OSINIT_OSREADY) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Initialization state. OS bring-up occurs in several phases: */ + +enum os_initstate_e +{ + OSINIT_POWERUP = 0, /* Power-up. No initialization yet performed. + * Depends on .bss initialization logic for this + * value. */ + OSINIT_BOOT = 1, /* Basic boot up initialization is complete. OS + * services and hardware resources are not yet + * available. */ + OSINIT_MEMORY = 2, /* The memory manager has been initialized */ + OSINIT_HARDWARE = 3, /* MCU-specific hardware is initialized. Hardware + * resources such as timers and device drivers are + * now avaiable. Low-level OS services sufficient + * to support the hardware are also available but + * the OS has not yet completed its full + * initialization. */ + OSINIT_OSREADY = 4 /* The OS is fully initialized and multi-tasking is + * active. */ +}; /**************************************************************************** - * Global Data + * Public Data ****************************************************************************/ #ifdef __cplusplus @@ -59,8 +94,15 @@ extern "C" #define EXTERN extern #endif +/* This is the current initialization state. The level of initialization + * is only important early in the start-up sequence when certain OS or + * hardware resources may not yet be available to the OS-internal logic. + */ + +EXTERN uint8_t g_os_initstate; /* See enum os_initstate_e */ + /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /* This entry point must be supplied by the application */ diff --git a/include/nuttx/input/ads7843e.h b/include/nuttx/input/ads7843e.h index 4c4b3b11891b145fe0761f50b86a4c7ba584bd24..3b14507228f17f08314e75de864a83e5fb92dd14 100644 --- a/include/nuttx/input/ads7843e.h +++ b/include/nuttx/input/ads7843e.h @@ -46,7 +46,7 @@ ****************************************************************************/ #include -#include +#include #if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E) diff --git a/include/nuttx/input/ajoystick.h b/include/nuttx/input/ajoystick.h index b2f49c527dfe6b1111830f22017a9d147788ad83..b672ed57edc7a50ab001798eb4a7ffdcdc433660 100644 --- a/include/nuttx/input/ajoystick.h +++ b/include/nuttx/input/ajoystick.h @@ -275,7 +275,7 @@ extern "C" * driver as the specified device. * * Input Parameters: - * devname - The name of the analog joystick device to be registers. + * devname - The name of the analog joystick device to be registered. * This should be a string of the form "/dev/ajoyN" where N is the the * minor device number. * lower - An instance of the platform-specific analog joystick lower diff --git a/include/nuttx/input/buttons.h b/include/nuttx/input/buttons.h new file mode 100644 index 0000000000000000000000000000000000000000..f31a197a1e287a1bc570dcb4f78852c32dcc5346 --- /dev/null +++ b/include/nuttx/input/buttons.h @@ -0,0 +1,185 @@ +/************************************************************************************ + * include/nuttx/input/buttons.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_INPUT_BUTTONS_H +#define __INCLUDE_NUTTX_INPUT_BUTTONS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_BUTTONS_NPOLLWAITERS +# define CONFIG_BUTTONS_NPOLLWAITERS 2 +#endif + +/* ioctl commands */ + +/* Command: BTNIOC_SUPPORTED + * Description: Report the set of button events supported by the hardware; + * Argument: A pointer to writeable btn_buttonset_t value in which to + * return the set of supported buttons. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define BTNIOC_SUPPORTED _BTNIOC(0x0001) + +/* Command: BTNIOC_REGISTER + * Description: Register to receive a signal whenever there is a change in + * the state of button inputs. This feature, of course, depends + * upon interrupt GPIO support from the platform. + * Argument: A read-only pointer to an instance of struct btn_notify_s + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define BTNIOC_REGISTER _BTNIOC(0x0002) + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This type is a bit set that contains the state of all buttons as defined + * in arch/board/board.h. This is the value that is returned when reading + * from the button driver. + */ + +typedef uint8_t btn_buttonset_t; + +/* A reference to this structure is provided with the BTNIOC_REGISTER IOCTL + * command and describes the conditions under which the client would like + * to receive notification. + */ + +struct btn_notify_s +{ + btn_buttonset_t bn_press; /* Set of button depressions to be notified */ + btn_buttonset_t bn_release; /* Set of button releases to be notified */ + uint8_t bn_signo; /* Signal number to use in the notification */ +}; + +/* This is the type of the button interrupt handler used with the struct + * btn_lowerhalf_s enable() method. + */ + +struct btn_lowerhalf_s; +typedef CODE void (*btn_handler_t) + (FAR const struct btn_lowerhalf_s *lower, FAR void *arg); + +/* The button driver is a two-part driver: + * + * 1) A common upper half driver that provides the common user interface to + * the buttons, + * 2) Platform-specific lower half drivers that provide the interface + * between the common upper half and the platform discrete button inputs. + * + * This structure defines the interface between an instance of the lower + * half driver and the common upper half driver. Such an instance is + * passed to the upper half driver when the driver is initialized, binding + * the upper and lower halves into one driver. + */ + +struct btn_lowerhalf_s +{ + /* Return the set of buttons supported by the board */ + + CODE btn_buttonset_t (*bl_supported)(FAR const struct btn_lowerhalf_s *lower); + + /* Return the current state of button data (only) */ + + CODE btn_buttonset_t (*bl_buttons)(FAR const struct btn_lowerhalf_s *lower); + + /* Enable interrupts on the selected set of buttons. An empty set will + * disable all interrupts. + */ + + CODE void (*bl_enable)(FAR const struct btn_lowerhalf_s *lower, + btn_buttonset_t press, btn_buttonset_t release, + btn_handler_t handler, FAR void *arg); +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_register + * + * Description: + * Bind the lower half button driver to an instance of the upper half + * button driver and register the composite character driver as the + * specified device. + * + * Input Parameters: + * devname - The name of the button device to be registered. + * This should be a string of the form "/dev/btnN" where N is the the + * minor device number. + * lower - An instance of the platform-specific button lower half driver. + * + * Returned Values: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int btn_register(FAR const char *devname, + FAR const struct btn_lowerhalf_s *lower); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_INPUT_BUTTONS_H */ + diff --git a/include/nuttx/input/mxt.h b/include/nuttx/input/mxt.h index fb606c1d7895544f7b9690971083b5765afc8169..22ee792769ce4cd75989e364faa5bd82ab5fe767 100644 --- a/include/nuttx/input/mxt.h +++ b/include/nuttx/input/mxt.h @@ -45,7 +45,7 @@ #include #include -#include +#include #if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_MXT) @@ -87,10 +87,6 @@ * in getting the right configuration. */ -#ifndef CONFIG_I2C_TRANSFER -# error "CONFIG_I2C_TRANSFER is required in the I2C configuration" -#endif - #ifdef CONFIG_DISABLE_SIGNALS # error "Signals are required. CONFIG_DISABLE_SIGNALS must not be selected." #endif @@ -199,7 +195,7 @@ extern "C" * ****************************************************************************/ -int mxt_register(FAR struct i2c_dev_s *i2c, +int mxt_register(FAR struct i2c_master_s *i2c, FAR const struct mxt_lower_s *lower, int minor); #undef EXTERN diff --git a/include/nuttx/input/stmpe811.h b/include/nuttx/input/stmpe811.h index 7b11496cc0ab2b65f1fc234a9a9dfc9dcff9189d..0ace9ea3131cb06cecbe1d872fd5ba2d7d3fd7ab 100644 --- a/include/nuttx/input/stmpe811.h +++ b/include/nuttx/input/stmpe811.h @@ -46,7 +46,7 @@ #include -#include +#include #include #include @@ -121,9 +121,6 @@ # ifndef CONFIG_I2C # error "CONFIG_I2C is required in the I2C support" # endif -# ifndef CONFIG_I2C_TRANSFER -# error "CONFIG_I2C_TRANSFER is required in the I2C configuration" -# endif #endif #ifdef CONFIG_DISABLE_SIGNALS @@ -549,7 +546,7 @@ extern "C" STMPE811_HANDLE stmpe811_instantiate(FAR struct spi_dev_s *dev, FAR struct stmpe811_config_s *config); #else -STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_dev_s *dev, +STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_master_s *dev, FAR struct stmpe811_config_s *config); #endif diff --git a/include/nuttx/input/tsc2007.h b/include/nuttx/input/tsc2007.h index 7ca219cd9ae43d2c561b694da8291fd1e5357bcd..20a832f87079623a2be46972c327a3bd9a941b6b 100644 --- a/include/nuttx/input/tsc2007.h +++ b/include/nuttx/input/tsc2007.h @@ -51,7 +51,7 @@ ****************************************************************************/ #include -#include +#include #if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_TSC2007) @@ -69,10 +69,6 @@ * in getting the right configuration. */ -#ifndef CONFIG_I2C_TRANSFER -# error "CONFIG_I2C_TRANSFER is required in the I2C configuration" -#endif - #ifdef CONFIG_DISABLE_SIGNALS # error "Signals are required. CONFIG_DISABLE_SIGNALS must not be selected." #endif @@ -160,7 +156,7 @@ extern "C" * ****************************************************************************/ -int tsc2007_register(FAR struct i2c_dev_s *dev, +int tsc2007_register(FAR struct i2c_master_s *dev, FAR struct tsc2007_config_s *config, int minor); #undef EXTERN diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h index 96d4197a724f8b0b2e08f6ddfd8e380bb411ba9a..ce95d6d4914c1706ea04cc43bddf650c8b0d6a50 100644 --- a/include/nuttx/ioexpander/ioexpander.h +++ b/include/nuttx/ioexpander/ioexpander.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/ioexpander/ioexpander.h * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Sebastien Lorquet * * Redistribution and use in source and binary forms, with or without @@ -41,9 +41,16 @@ ****************************************************************************/ #include +#include #if defined(CONFIG_IOEXPANDER) +#ifndef CONFIG_PCA9555_INT_DISABLE +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Work queue support required. CONFIG_SCHED_WORKQUEUE must be selected." +#endif +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -97,7 +104,7 @@ #define IOEXP_SETOPTION(dev,pin,opt,val) ((dev)->ops->ioe_option(dev,pin,opt,val)) /**************************************************************************** - * Name: IOEXP_WRITE + * Name: IOEXP_WRITEPIN * * Description: * Set the pin level. Required. @@ -157,7 +164,7 @@ #ifdef CONFIG_IOEXPANDER_MULTIPIN /**************************************************************************** - * Name: IOEXP_MULTIWRITE + * Name: IOEXP_MULTIWRITEPIN * * Description: * Set the pin level for multiple pins. This routine may be faster than @@ -216,7 +223,7 @@ #define IOEXP_MULTIREADBUF(dev,pins,vals,count) \ ((dev)->ops->ioe_multireadbuf(dev,pin,vals,count)) -#endif +#endif /* CONFIG_IOEXPANDER_MULTIPIN */ /**************************************************************************** * Public Types @@ -230,15 +237,15 @@ struct ioexpander_ops_s int direction); CODE int (*ioe_option)(FAR struct ioexpander_dev_s *dev, uint8_t pin, int opt, void *val); - CODE int (*ioe_write)(FAR struct ioexpander_dev_s *dev, uint8_t pin, - bool value); + CODE int (*ioe_writepin)(FAR struct ioexpander_dev_s *dev, uint8_t pin, + bool value); CODE int (*ioe_readpin)(FAR struct ioexpander_dev_s *dev, uint8_t pin, bool *value); CODE int (*ioe_readbuf)(FAR struct ioexpander_dev_s *dev, uint8_t pin, bool *value); #ifdef CONFIG_IOEXPANDER_MULTIPIN - CODE int (*ioe_multiwrite)(FAR struct ioexpander_dev_s *dev, - uint8_t *pins, bool *values, int count); + CODE int (*ioe_multiwritepin)(FAR struct ioexpander_dev_s *dev, + uint8_t *pins, bool *values, int count); CODE int (*ioe_multireadpin)(FAR struct ioexpander_dev_s *dev, uint8_t *pins, bool *values, int count); CODE int (*ioe_multireadbuf)(FAR struct ioexpander_dev_s *dev, @@ -249,8 +256,12 @@ struct ioexpander_ops_s struct ioexpander_dev_s { FAR const struct ioexpander_ops_s *ops; +#ifdef CONFIG_IOEXPANDER_INT_ENABLE + struct work_s work; /* Supports the interrupt handling "bottom half" */ + int sigpid; /* PID to be signaled in case of interrupt */ + int sigval; /* Signal to be sent in case of interrupt */ +#endif }; -#endif //CONFIG_IOEXPANDER -#endif //__INCLUDE_NUTTX_IOEXPANDER_IOEXPANDER_H - +#endif /* CONFIG_IOEXPANDER */ +#endif /* __INCLUDE_NUTTX_IOEXPANDER_IOEXPANDER_H */ diff --git a/include/nuttx/ioexpander/pca9555.h b/include/nuttx/ioexpander/pca9555.h index b8c857a3e7e9f9b1174968ad8846033acfc9e8cb..aa0b3c286351242ea2aba1067727a579931fe066 100644 --- a/include/nuttx/ioexpander/pca9555.h +++ b/include/nuttx/ioexpander/pca9555.h @@ -40,7 +40,7 @@ #ifndef __INCLUDE_NUTTX_IOEXPANDER_PCA9555_H #define __INCLUDE_NUTTX_IOEXPANDER_PCA9555_H -#include +#include /* A reference to a structure of this type must be passed to the PCA9555 driver when the * driver is instantiated. This structure provides information about the configuration of @@ -63,7 +63,6 @@ struct pca9555_config_s */ #ifndef CONFIG_PCA9555_INT_DISABLE -/* IRQ support TODO */ #ifdef CONFIG_PCA9555_MULTIPLE int irq; /* IRQ number received by interrupt handler. */ @@ -75,12 +74,10 @@ struct pca9555_config_s * * attach - Attach the PCA9555 interrupt handler to the GPIO interrupt * enable - Enable or disable the GPIO interrupt - * clear - Acknowledge/clear any pending GPIO interrupt */ CODE int (*attach)(FAR struct pca9555_config_s *state, xcpt_t isr); CODE void (*enable)(FAR struct pca9555_config_s *state, bool enable); - CODE void (*clear)(FAR struct pca9555_config_s *state); #endif }; @@ -113,7 +110,7 @@ extern "C" * ********************************************************************************************/ -FAR struct ioexpander_dev_s* pca9555_initialize(FAR struct i2c_dev_s *dev, +FAR struct ioexpander_dev_s* pca9555_initialize(FAR struct i2c_master_s *dev, FAR struct pca9555_config_s *config); #ifdef __cplusplus diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h index 9bdc1cf7d22cfd521aed6f0dbfec266c18180965..2f7dba3764b76d1b211d7eb52544b68d08ac9fb4 100644 --- a/include/nuttx/irq.h +++ b/include/nuttx/irq.h @@ -40,8 +40,11 @@ * Included Files ****************************************************************************/ +#include + #ifndef __ASSEMBLY__ # include +# include #endif /**************************************************************************** @@ -70,7 +73,7 @@ typedef int (*xcpt_t)(int irq, FAR void *context); #include /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifndef __ASSEMBLY__ @@ -97,6 +100,43 @@ extern "C" int irq_attach(int irq, xcpt_t isr); +/**************************************************************************** + * Name: enter_critical_section + * + * Description: + * If SMP is enabled: + * Take the CPU IRQ lock and disable interrupts on all CPUs. A thread- + * specific counter is increment to indicate that the thread has IRQs + * disabled and to support nested calls to enter_critical_section(). + * If SMP is not enabled: + * This function is equivalent to up_irq_save(). + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +irqstate_t enter_critical_section(void); +#else +# define enter_critical_section(f) up_irq_save(f) +#endif + +/**************************************************************************** + * Name: leave_critical_section + * + * Description: + * If SMP is enabled: + * Decrement the IRQ lock count and if it decrements to zero then release + * the spinlock. + * If SMP is not enabled: + * This function is equivalent to up_irq_restore(). + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +void leave_critical_section(irqstate_t flags); +#else +# define leave_critical_section(f) up_irq_restore(f) +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/kmalloc.h b/include/nuttx/kmalloc.h index 162b9356db47e2dae5b9e875012f3f7c75cb58dc..4734a264f61ccce8e9d71d5b99a3fe2ab617e4df 100644 --- a/include/nuttx/kmalloc.h +++ b/include/nuttx/kmalloc.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/kmalloc.h * - * Copyright (C) 2007-2008, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2008, 2011, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -177,7 +177,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem); /* Handles memory freed from an interrupt handler. In that context, kmm_free() * (or kumm_free()) cannot be called. Instead, the allocations are saved in a * list of delayed allocations that will be periodically cleaned up by - * sched_garbagecollection(). + * sched_garbage_collection(). */ void sched_ufree(FAR void *address); @@ -196,7 +196,19 @@ void sched_kfree(FAR void *address); * the system for memory in some context. */ -void sched_garbagecollection(void); +void sched_garbage_collection(void); + +/* Is is not a good idea for the IDLE threads to take the KMM semaphore. + * That can cause the IDLE thread to take processing time from higher + * priority tasks. The IDLE threads will only take the KMM semaphore if + * there is garbage to be collected. + * + * Certainly there is a race condition involved in sampling the garbage + * state. The looping nature of the IDLE loops should catch any missed + * garbage from the test on the next time arround. + */ + +bool sched_have_garbage(void); #undef KMALLOC_EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/lcd/memlcd.h b/include/nuttx/lcd/memlcd.h index 629e79cfa128a636b396a83095b1c1df432ac786..afdc7bf3bdb3b463e7261eb72e33008d0b40f173 100644 --- a/include/nuttx/lcd/memlcd.h +++ b/include/nuttx/lcd/memlcd.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/**************************************************************************** * include/nuttx/lcd/memlcd.h * Common definitions for the Sharp Memory LCD driver * @@ -32,14 +32,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ******************************************************************************/ + ****************************************************************************/ #ifndef __INCLUDE_NUTTX_MEMLCD_H #define __INCLUDE_NUTTX_MEMLCD_H -/******************************************************************************* +/**************************************************************************** * Included Files - ******************************************************************************/ + ****************************************************************************/ #include @@ -51,13 +51,13 @@ extern "C" # define EXTERN extern #endif -/******************************************************************************* +/**************************************************************************** * Pre-processor Definitions - ******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Public Types - ******************************************************************************/ + ****************************************************************************/ /* A reference to a structure of this type must be passed to the initialization * method. It provides some board-specific hooks used by driver to manage the @@ -89,15 +89,15 @@ struct memlcd_priv_s void (*setvcomfreq) (unsigned int freq); }; -/******************************************************************************* +/**************************************************************************** * Public Data - ******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Public Function Prototypes - ******************************************************************************/ + ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: memlcd_initialize * * Description: @@ -114,7 +114,7 @@ struct memlcd_priv_s * On success, this function returns a reference to the LCD object for the * specified LCD. NULL is returned on any failure. * - ******************************************************************************/ + ****************************************************************************/ struct lcd_dev_s; /* see nuttx/lcd.h */ struct spi_dev_s; /* see nuttx/spi/spi.h */ diff --git a/include/nuttx/lcd/ssd1306.h b/include/nuttx/lcd/ssd1306.h index ea80189c461e8e21177a685465e2b2a97b59982f..ed4195e78b81fd98bbea8545d7ad5f9a8a85e7ce 100644 --- a/include/nuttx/lcd/ssd1306.h +++ b/include/nuttx/lcd/ssd1306.h @@ -118,10 +118,6 @@ #ifdef CONFIG_LCD_SSD1306_I2C -#ifndef CONFIG_I2C_TRANSFER -# error "CONFIG_I2C_TRANSFER must be defined in your NuttX configuration" -#endif - #ifndef CONFIG_SSD1306_I2CADDR # define CONFIG_SSD1306_I2CADDR 0x78 /* 120 in decimal */ #endif @@ -243,7 +239,7 @@ struct spi_dev_s; /* See include/nuttx/spi/spi.h */ #ifdef CONFIG_LCD_SSD1306_SPI FAR struct lcd_dev_s *ssd1306_initialize(FAR struct spi_dev_s *dev, unsigned int devno); #else -FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_dev_s *dev, unsigned int devno); +FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_master_s *dev, unsigned int devno); #endif /************************************************************************************************ diff --git a/include/nuttx/lcd/ssd1351.h b/include/nuttx/lcd/ssd1351.h new file mode 100644 index 0000000000000000000000000000000000000000..858ac470e83f6825521b2fbf353a51b6e19786b4 --- /dev/null +++ b/include/nuttx/lcd/ssd1351.h @@ -0,0 +1,157 @@ +/**************************************************************************** + * include/nuttx/lcd/ssd1351.h + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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 __INCLUDE_NUTTX_LCD_SSD1351_H +#define __INCLUDE_NUTTX_LCD_SSD1351_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_LCD_SSD1351 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* SSD1351 configuration settings: + * CONFIG_SSD1351_PARALLEL8BIT - 8-bit parallel interface + * CONFIG_SSD1351_SPI3WIRE - 3-wire SPI interface + * CONFIG_SSD1351_SPI4WIRE - 4-wire SPI interface + * CONFIG_SSD1351_SPIMODE - SPI mode + * CONFIG_SSD1351_SPIFREQ - SPI frequency + * CONFIG_SSD1351_NINTERFACES - number of physical devices supported + * CONFIG_SSD1351_XRES - X resolution + * CONFIG_SSD1351_YRES - Y resolution + * CONFIG_SSD1351_MIRRORX - mirror along the X axis + * CONFIG_SSD1351_MIRRORY - mirror along the Y axis + * CONFIG_SSD1351_INVERT - invert the display + * CONFIG_SSD1351_VDDEXT - external VDD + * CONFIG_SSD1351_TRST - reset period + * CONFIG_SSD1351_TPRECHG1 - first pre-charge period + * CONFIG_SSD1351_PERFENHANCE - enhace display performance + * CONFIG_SSD1351_CLKDIV - clock divider + * CONFIG_SSD1351_OSCFREQ - oscillator frequency + * CONFIG_SSD1351_TPRECHG2 - second pre-charge period + * CONFIG_SSD1351_VPRECHG - pre-charge voltage level + * CONFIG_SSD1351_VCOMH - COM deselect voltage level + * CONFIG_SSD1351_CONTRASTA - color A contrast + * CONFIG_SSD1351_CONTRASTB - color B contrast + * CONFIG_SSD1351_CONTRASTC - color C contrast + * CONFIG_SSD1351_MSTRCONTRAST - master contrast ratio + * + * Required LCD driver settings: + * CONFIG_LCD_SSD1351 - enables SSD1351 support + * CONFIG_LCD_MAXPOWER - maximum power, must be 1 + * + * Additional LCD driver settings: + * CONFIG_LCD_LANDSCAPE - landscape + * CONFIG_LCD_RLANDSCAPE - reverse landscape + * CONFIG_LCD_PORTRAIT - portrait + * CONFIG_LCD_RPORTRAIT - reverse portrait + * + * Required SPI driver settings: + * CONFIG_SPI - enables support for SPI + * CONFIG_SPI_CMDDATA - enables support for cmd/data selection + * (if using 4-wire SPI) + * + * NX settings that must be undefined: + * CONFIG_NX_DISABLE_16BPP - disables 16 bpp support + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT +struct ssd1351_lcd_s +{ + void (*cmd)(FAR struct ssd1351_lcd_s *lcd, uint8_t cmd); +#ifndef CONFIG_LCD_NOGETRUN + uint8_t (*read)(FAR struct ssd1351_lcd_s *lcd); +#endif + void (*write)(FAR struct ssd1351_lcd_s *lcd, uint8_t data); +}; +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +struct spi_dev_s; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: ssd1351_initialize + * + * Description: + * Initialize the video hardware. The initial state of the device + * is fully initialized, display memory cleared, and ready to use, + * but with the power setting at 0 (full off == sleep mode). + * + * Input Parameters: + * lcd - A reference to the platform-specific interface. + * spi - A reference to the SPI driver instance. + * devno - A value in the range of 0 through CONFIG_SSD1351_NINTERFACES-1. + * This allows support for multiple devices. + * + * Returned Value: + * On success, this function returns a reference to the LCD object for the + * specified device. NULL is returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SSD1351_PARALLEL8BIT +FAR struct lcd_dev_s *ssd1351_initialize(FAR struct ssd1351_lcd_s *lcd, + unsigned int devno); +#elif defined(CONFIG_SSD1351_SPI3WIRE) || defined(CONFIG_SSD1351_SPI4WIRE) +FAR struct lcd_dev_s *ssd1351_initialize(FAR struct spi_dev_s *spi, + unsigned int devno); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_LCD_SSD1351 */ +#endif /* __INCLUDE_NUTTX_LCD_SSD1351_H */ diff --git a/include/nuttx/leds/pca9635pw.h b/include/nuttx/leds/pca9635pw.h new file mode 100644 index 0000000000000000000000000000000000000000..9872cb1b8b5029522628c265074eef4c23a753ad --- /dev/null +++ b/include/nuttx/leds/pca9635pw.h @@ -0,0 +1,201 @@ +/**************************************************************************** + * include/nuttx/leds/pca9635pw.h + * + * Copyright (C) 2015 DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * 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 __INCLUDE_NUTTX_LEDS_PCA9635PW_H +#define __INCLUDE_NUTTX_LEDS_PCA9635PW_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/* Configuration + * CONFIG_I2C - Enables support for I2C drivers + * CONFIG_PCA9635PW - Enables support for the PCA9635PW driver + */ + +#if defined(CONFIG_I2C) && defined(CONFIG_PCA9635PW) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* I2C definitions */ + +#define I2C_BUS_FREQ_HZ (1000000) + +/* PCA9635PW register addresses */ + +#define PCA9635PW_MODE_1 (0x00) /* Mode register 1 */ +#define PCA9635PW_MODE_2 (0x01) /* Mode register 2 */ +#define PCA9635PW_LED_0 (0x02) /* LED 0 brightness control */ +#define PCA9635PW_LED_1 (PCA9635PW_LED_0 + 1) /* LED 1 brightness control */ +#define PCA9635PW_LED_2 (PCA9635PW_LED_0 + 2) /* LED 2 brightness control */ +#define PCA9635PW_LED_3 (PCA9635PW_LED_0 + 3) /* LED 3 brightness control */ +#define PCA9635PW_LED_4 (PCA9635PW_LED_0 + 4) /* LED 4 brightness control */ +#define PCA9635PW_LED_5 (PCA9635PW_LED_0 + 5) /* LED 5 brightness control */ +#define PCA9635PW_LED_6 (PCA9635PW_LED_0 + 6) /* LED 6 brightness control */ +#define PCA9635PW_LED_7 (PCA9635PW_LED_0 + 7) /* LED 7 brightness control */ +#define PCA9635PW_LED_8 (PCA9635PW_LED_0 + 8) /* LED 8 brightness control */ +#define PCA9635PW_LED_9 (PCA9635PW_LED_0 + 9) /* LED 9 brightness control */ +#define PCA9635PW_LED_10 (PCA9635PW_LED_0 + 10) /* LED 10 brightness control */ +#define PCA9635PW_LED_11 (PCA9635PW_LED_0 + 11) /* LED 11 brightness control */ +#define PCA9635PW_LED_12 (PCA9635PW_LED_0 + 12) /* LED 12 brightness control */ +#define PCA9635PW_LED_13 (PCA9635PW_LED_0 + 13) /* LED 13 brightness control */ +#define PCA9635PW_LED_14 (PCA9635PW_LED_0 + 14) /* LED 14 brightness control */ +#define PCA9635PW_LED_15 (PCA9635PW_LED_0 + 15) /* LED 15 brightness control */ +#define PCA9635PW_GRPPWM (0x12) /* Group duty cycle control */ +#define PCA9635PW_GRPFREQ (0x13) /* group frequency */ +#define PCA9635PW_LED_OUT_0 (0x14) /* LED output state 0 */ +#define PCA9635PW_LED_OUT_1 (PCA9635PW_LED_OUT_0 + 1) /* LED output state 1 */ +#define PCA9635PW_LED_OUT_2 (PCA9635PW_LED_OUT_0 + 2) /* LED output state 2 */ +#define PCA9635PW_LED_OUT_3 (PCA9635PW_LED_OUT_0 + 3) /* LED output state 3 */ + +/* PCA9635PW_MODE_1 bit definitions */ + +#define PCA9635PW_MODE_1_AI2 (1<<7) /* auto increment enable/disable */ +#define PCA9635PW_MODE_1_AI1 (1<<6) /* auto increment bit 1 */ +#define PCA9635PW_MODE_1_AI0 (1<<5) /* auto increment bit 0 */ +#define PCA9635PW_MODE_1_SLEEP (1<<4) /* low power mode/sleep enable/disable */ +#define PCA9635PW_MODE_1_SUB1 (1<<3) /* PCA9635PW reponds to I2C subaddress 1 enable/disable */ +#define PCA9635PW_MODE_1_SUB2 (1<<2) /* PCA9635PW reponds to I2C subaddress 2 enable/disable */ +#define PCA9635PW_MODE_1_SUB3 (1<<1) /* PCA9635PW reponds to I2C subaddress 3 enable/disable */ +#define PCA9635PW_MODE_1_ALLCALL (1<<0) /* PCA9635PW reponds to led all call I2C address enable/disable */ + +/* PCA9635PW_MODE_2 bit definitions */ + +#define PCA9635PW_MODE_2_DMBLNK (1<<5) /* group control dimming/blinking */ +#define PCA9635PW_MODE_2_INVRT (1<<4) /* output logic state inverted/not inverted */ +#define PCA9635PW_MODE_2_OCH (1<<3) /* output change on stop command/on ACK */ +#define PCA9635PW_MODE_2_OUTDRV (1<<2) /* outputs are configured with an open-drain-structure/totem-pole-structure */ +#define PCA9635PW_MODE_2_OUTNE1 (1<<1) /* handling of outputs in dependency of !OE pin */ +#define PCA9635PW_MODE_2_OUTNE0 (1<<0) /* handling of outputs in dependency of !OE pin */ + +/* PCA9635PW_LED_OUT_x register value definitions */ + +#define PCA9635PW_LED_OUT_x_MODE_0 (0x00) /* all led drivers are turned off */ +#define PCA9635PW_LED_OUT_x_MODE_1 (0x55) /* all led drivers are fully turned on */ +#define PCA9635PW_LED_OUT_x_MODE_2 (0xAA) /* all led drivers individual brightness can be controlled by their individual pwm registers */ +#define PCA9635PW_LED_OUT_x_MODE_3 (0xFF) /* all led drivers individual brightness and group dimming/blinking can be controlled by their individual pwm registers and the GRPPWM register */ + +/* IOCTL commands */ + +#define PWMIOC_SETLED_BRIGHTNESS _PWMIOC(1) /* Arg: pca9635pw_setled_brightness_arg_s * pointer */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum led_select_e +{ + LED_0 = PCA9635PW_LED_0, + LED_1 = PCA9635PW_LED_1, + LED_2 = PCA9635PW_LED_2, + LED_3 = PCA9635PW_LED_3, + LED_4 = PCA9635PW_LED_4, + LED_5 = PCA9635PW_LED_5, + LED_6 = PCA9635PW_LED_6, + LED_7 = PCA9635PW_LED_7, + LED_8 = PCA9635PW_LED_8, + LED_9 = PCA9635PW_LED_9, + LED_10 = PCA9635PW_LED_10, + LED_11 = PCA9635PW_LED_11, + LED_12 = PCA9635PW_LED_12, + LED_13 = PCA9635PW_LED_13, + LED_14 = PCA9635PW_LED_14, + LED_15 = PCA9635PW_LED_15 +}; + +/* This structure is used in an IOCTL command for setting the PWM of an individual + * LED. The desired LED is selected by setting the 'led' parameter accordingly + * whereas the 'led_pwm' field governs the brightness of the selected LED. A value + * of 0 (0x00) leads to a duty cycle of 0 % = LED off while a value of 255 (0xFF) + * leads to a duty cycle of 99.6 % = Maximum brightness. + */ + +struct pca9635pw_setled_brightness_arg_s +{ + enum led_select_e led; + uint8_t brightness; +}; + +/**************************************************************************** + * Forward declarations + ****************************************************************************/ + +struct i2c_master_s; + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: pca9635pw_register + * + * Description: + * Register the PCA9635PW device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/leddrv0". + * i2c - An instance of the I2C interface to use to communicate + * with the LM92. + * pca9635pw_i2c_addr + * - The I2C address of the PCA9635PW. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pca9635pw_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t const pca9635pw_i2c_addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_I2C_PCA9635PW */ +#endif /* __INCLUDE_NUTTX_LEDS_PCA9635PW_H */ diff --git a/include/nuttx/leds/rgbled.h b/include/nuttx/leds/rgbled.h new file mode 100644 index 0000000000000000000000000000000000000000..07560d6a6eb044d09647bc5f51e804872ab33c47 --- /dev/null +++ b/include/nuttx/leds/rgbled.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * include/nuttx/rgbled.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 __INCLUDE_NUTTX_LEDS_RGBLED_H +#define __INCLUDE_NUTTX_LEDS_RGBLED_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include + +#ifdef CONFIG_RGBLED + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rgbled_register + * + * Description: + * This function binds three instances of a "lower half" PWM driver with + * the "upper half" RGB LED device and registers that device so that can + * be used by application code. + * + * + * Input parameters: + * path - The full path to the driver to be registers in the NuttX pseudo- + * filesystem. The recommended convention is to name all PWM drivers + * as "/dev/rgdbled0", "/dev/rgbled1", etc. where the driver path + * differs only in the "minor" number at the end of the device name. + * ledr, ledg, and ledb - A pointer to an instance of lower half PWM + * drivers for the red, green, and blue LEDs, respectively. These + * instances will be bound to the RGB LED driver and must persists as + * long as that driver persists. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +int rgbled_register(FAR const char *path, FAR struct pwm_lowerhalf_s *ledr, + FAR struct pwm_lowerhalf_s *ledg, + FAR struct pwm_lowerhalf_s *ledb); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_RGBLED */ +#endif /* __INCLUDE_NUTTX_LEDS_RGBLED_H */ diff --git a/include/nuttx/leds/userled.h b/include/nuttx/leds/userled.h new file mode 100644 index 0000000000000000000000000000000000000000..093c3b5b9a2adf4ce1d8fc6fcd9ea96bde235d5b --- /dev/null +++ b/include/nuttx/leds/userled.h @@ -0,0 +1,201 @@ +/************************************************************************************ + * include/nuttx/leds/userled.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_LEDS_USERLED_H +#define __INCLUDE_NUTTX_LEDS_USERLED_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_ARCH_HAVE_LEDS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* ioctl commands */ + +/* Command: ULEDIOC_SUPPORTED + * Description: Report the set of LEDs supported by the hardware; + * Argument: A pointer to writeable userled_set_t value in which to + * return the set of supported LEDs. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define ULEDIOC_SUPPORTED _ULEDIOC(0x0001) + +/* Command: ULEDIOC_SETLED + * Description: Set the state of one LED. + * Argument: A read-only pointer to an instance of struct userled_s + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define ULEDIOC_SETLED _ULEDIOC(0x0002) + +/* Command: ULEDIOC_SETALL + * Description: Set the state of all LEDs. + * Argument: A value of type userled_set_t cast to unsigned long + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define ULEDIOC_SETALL _ULEDIOC(0x0003) + +/* Command: ULEDIOC_GETALL + * Description: Get the state of one LED. + * Argument: A write-able pointer to a userled_set_t memory location in + * which to return the LED state. + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define ULEDIOC_GETALL _ULEDIOC(0x0004) + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This type is a bit set that contains the state of all LEDs as defined + * in arch/board/board.h. This is the value that is returned when reading + * from or writing to the LED driver. + */ + +typedef uint8_t userled_set_t; + +/* A reference to this structure is provided with the ULEDIOC_SETLED IOCTL + * command and describes the LED to be set and the new value of the LED. + * The encoding of LEDs is provided in the board-specific board.h header + * file. + */ + +struct userled_s +{ + uint8_t ul_led; /* Identifies the LED */ + bool ul_on; /* The LED state. true: ON; false: OFF */ +}; + +/* The user LED driver is a two-part driver: + * + * 1) A common upper half driver that provides the common user interface to + * the LEDs, + * 2) Platform-specific lower half drivers that provide the interface + * between the common upper half and the platform discrete LED outputs. + * + * This structure defines the interface between an instance of the lower + * half driver and the common upper half driver. Such an instance is + * passed to the upper half driver when the driver is initialized, binding + * the upper and lower halves into one driver. + */ + +struct userled_lowerhalf_s +{ + /* Return the set of LEDs supported by the board */ + + CODE userled_set_t (*ll_supported)(FAR const struct userled_lowerhalf_s *lower); + + /* Set the current state of one LED */ + + CODE void (*ll_led)(FAR const struct userled_lowerhalf_s *lower, + int led, bool ledon); + + /* Set the state of all LEDs */ + + CODE void (*ll_ledset)(FAR const struct userled_lowerhalf_s *lower, + userled_set_t ledset); +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: userled_register + * + * Description: + * Bind the lower half LED driver to an instance of the upper half + * LED driver and register the composite character driver as the + * specified device. + * + * Input Parameters: + * devname - The name of the LED device to be registered. + * This should be a string of the form "/dev/ledN" where N is the the + * minor device number. + * lower - An instance of the platform-specific LED lower half driver. + * + * Returned Values: + * Zero (OK) is returned on success. Otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int userled_register(FAR const char *devname, + FAR const struct userled_lowerhalf_s *lower); + +/**************************************************************************** + * Name: userled_lower_initialize + * + * Description: + * Initialize the generic LED lower half driver, bind it and register + * it with the upper half LED driver as devname. + * + ****************************************************************************/ + +#ifdef CONFIG_USERLED_LOWER +int userled_lower_initialize(FAR const char *devname); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_ARCH_HAVE_LEDS */ +#endif /* __INCLUDE_NUTTX_LEDS_USERLED_H */ diff --git a/include/nuttx/math.h b/include/nuttx/math.h index 40990352af7b7f1e96a4d278aeeaa02625ac658f..6ee91eab7e66d052539532a1a6ba0cec818503e8 100644 --- a/include/nuttx/math.h +++ b/include/nuttx/math.h @@ -128,7 +128,7 @@ extern "C" /* General Functions ********************************************************/ float ceilf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double ceil (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -136,7 +136,7 @@ long double ceill (long double x); #endif float floorf(float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double floor (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -144,7 +144,7 @@ long double floorl(long double x); #endif float roundf(float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double round (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -152,7 +152,7 @@ long double roundl(long double x); #endif float rintf(float x); /* Not implemented */ -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double rint(double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -160,7 +160,7 @@ long double rintl(long double x); /* Not implemented */ #endif float fabsf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double fabs (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -168,7 +168,7 @@ long double fabsl (long double x); #endif float modff (float x, float *iptr); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double modf (double x, double *iptr); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -176,7 +176,7 @@ long double modfl (long double x, long double *iptr); #endif float fmodf (float x, float div); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double fmod (double x, double div); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -186,7 +186,7 @@ long double fmodl (long double x, long double div); /* Exponential and Logarithmic Functions ************************************/ float powf (float b, float e); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double pow (double b, double e); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -195,7 +195,7 @@ long double powl (long double b, long double e); float expf (float x); #define expm1f(x) (expf(x) - 1.0) -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double exp (double x); #define expm1(x) (exp(x) - 1.0) #endif @@ -205,7 +205,7 @@ long double expl (long double x); #endif float logf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double log (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -213,7 +213,7 @@ long double logl (long double x); #endif float log10f(float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double log10 (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -221,7 +221,7 @@ long double log10l(long double x); #endif float log2f (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double log2 (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -229,7 +229,7 @@ long double log2l (long double x); #endif float sqrtf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double sqrt (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -237,7 +237,7 @@ long double sqrtl (long double x); #endif float ldexpf(float x, int n); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double ldexp (double x, int n); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -245,7 +245,7 @@ long double ldexpl(long double x, int n); #endif float frexpf(float x, int *exp); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double frexp (double x, int *exp); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -255,7 +255,7 @@ long double frexpl(long double x, int *exp); /* Trigonometric Functions **************************************************/ float sinf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double sin (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -263,7 +263,7 @@ long double sinl (long double x); #endif float cosf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double cos (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -271,7 +271,7 @@ long double cosl (long double x); #endif float tanf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double tan (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -279,7 +279,7 @@ long double tanl (long double x); #endif float asinf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double asin (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -287,7 +287,7 @@ long double asinl (long double x); #endif float acosf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double acos (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -295,7 +295,7 @@ long double acosl (long double x); #endif float atanf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double atan (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -303,7 +303,7 @@ long double atanl (long double x); #endif float atan2f(float y, float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double atan2 (double y, double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -311,7 +311,7 @@ long double atan2l(long double y, long double x); #endif float sinhf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double sinh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -319,7 +319,7 @@ long double sinhl (long double x); #endif float coshf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double cosh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -327,7 +327,7 @@ long double coshl (long double x); #endif float tanhf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double tanh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -335,7 +335,7 @@ long double tanhl (long double x); #endif float asinhf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double asinh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -343,7 +343,7 @@ long double asinhl (long double x); #endif float acoshf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double acosh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -351,7 +351,7 @@ long double acoshl (long double x); #endif float atanhf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double atanh (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -360,7 +360,7 @@ long double atanhl (long double x); float erff (float x); #define erfcf(x) (1 - erff(x)) -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double erf (double x); #define erfc(x) (1 - erf(x)) #endif @@ -370,7 +370,7 @@ long double erfl (long double x); #endif float copysignf (float x, float y); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double copysign (double x, double y); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE @@ -378,7 +378,7 @@ long double copysignl (long double x, long double y); #endif float truncf (float x); -#if CONFIG_HAVE_DOUBLE +#ifdef CONFIG_HAVE_DOUBLE double trunc (double x); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE diff --git a/include/nuttx/math32.h b/include/nuttx/math32.h new file mode 100644 index 0000000000000000000000000000000000000000..64e993d7905bacd029ffc9807c0601b81187651c --- /dev/null +++ b/include/nuttx/math32.h @@ -0,0 +1,241 @@ +/**************************************************************************** + * include/nuttx/math32.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_MATH32_H +#define __INCLUDE_NUTTX_MATH32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* These types are useful on platforms that do not support 64-bit types. */ + +struct int64_s +{ +#ifdef CONFIG_ENDIAN_BIG + int32_t ms; + uint32_t ls; +#else + uint32_t ls; + int32_t ms; +#endif +}; + +struct uint64_s +{ +#ifdef CONFIG_ENDIAN_BIG + uint32_t ms; + uint32_t ls; +#else + uint32_t ls; + uint32_t ms; +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: uneg64 + * + * Description: + * Negate a 64-bit unsigned value. + * + * Input Parameters: + * value - The value to be negated. + * + ****************************************************************************/ + +/* void uneg64(FAR const uint64_s *value); */ + +#define uneg64(value) \ + do \ + { \ + value->ms = ~value->ms; \ + value->ls = -value->ls; \ + if (value->ls == 0) \ + { \ + value->ms++; \ + } \ + } \ + while (0) + +/**************************************************************************** + * Name: uadd32x64 + * + * Description: + * Add a 32-bit value to a 64-bit values and return the truncated 64-bit + * sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd32x64(uint32_t term1, FAR const struct uint64_s *term2, + FAR struct uint64_s *sum); + +/**************************************************************************** + * Name: uadd64 + * + * Description: + * Add two 64-bit values and return a 64-bit sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd64(FAR const struct uint64_s *term1, + FAR const struct uint64_s *term2, + FAR struct uint64_s *sum); + +/**************************************************************************** + * Name: usub64x32 + * + * Description: + * Subtract a 32-bit value from a 64-bit value and return the 64-bit + * difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64x32(FAR const struct uint64_s *minuend, uint32_t subtrahend, + FAR struct uint64_s *difference); + +/**************************************************************************** + * Name: usub64 + * + * Description: + * Subtract two 64-bit values and return the 64-bit difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64(FAR const struct uint64_s *minuend, + FAR const struct uint64_s *subtrahend, + FAR struct uint64_s *difference); + +/**************************************************************************** + * Name: umul32 + * + * Description: + * Multiply two 32-bit values, factor1 and factor2, and return the + * full 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul32(uint32_t factor1, uint32_t factor2, FAR struct uint64_s *product); + +/**************************************************************************** + * Name: umul32x64 + * + * Description: + * Multiply one 32-bit and one 64-bit values, factor1 and factor2, + * respectively, and return the truncated 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul32x64(uint32_t factor1, FAR const struct uint64_s *factor2, + FAR struct uint64_s *product); + +/**************************************************************************** + * Name: umul64 + * + * Description: + * Multiply two 64-bit values, factor1 and factor2, and return the + * truncated 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul64(FAR const struct uint64_s *factor1, + FAR const struct uint64_s *factor2, + FAR struct uint64_s *product); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_MATH32_H */ diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h index 6a8c27ba468ca46ed9934ea6df7b84423f878ca0..7d2e102f318bd1fb8500cde56716ce26880c29b2 100644 --- a/include/nuttx/mm/mm.h +++ b/include/nuttx/mm/mm.h @@ -184,10 +184,10 @@ #ifdef CONFIG_MM_SMALL typedef uint16_t mmsize_t; -# define MMSIZE_MAX 0xffff +# define MMSIZE_MAX UINT16_MAX #else - typedef size_t mmsize_t; -# define MMSIZE_MAX SIZE_MAX + typedef uint32_t mmsize_t; +# define MMSIZE_MAX UINT32_MAX #endif /* This describes an allocated chunk. An allocated chunk is @@ -287,7 +287,7 @@ extern "C" * no global user heap structure. */ - #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) +#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) /* In the kernel build, there a multiple user heaps; one for each task * group. In this build configuration, the user heap structure lies * in a reserved region at the beginning of the .bss/.data address @@ -491,8 +491,8 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info); struct mallinfo kmm_mallinfo(void); #else int kmm_mallinfo(struct mallinfo *info); -#endif #endif /* CONFIG_CAN_PASS_STRUCTS */ +#endif /* CONFIG_MM_KERNEL_HEAP */ /* Functions contained in mm_shrinkchunk.c **********************************/ diff --git a/include/nuttx/mmcsd.h b/include/nuttx/mmcsd.h index 29f256d82d2d8ee78ad0ad229482de324e1d4d0f..8d9c54b47191b782245743d7e73efa57fac82f2d 100644 --- a/include/nuttx/mmcsd.h +++ b/include/nuttx/mmcsd.h @@ -92,8 +92,9 @@ int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev); * slotno - The slot number to use. This is only meaningful for architectures * that support multiple MMC/SD slots. This value must be in the range * {0, ..., CONFIG_MMCSD_NSLOTS}. - * spi - And instance of an SPI interface obtained by called - * up_spiinitialize() with the appropriate port number (see spi.h) + * spi - And instance of an SPI interface obtained by called the + * approprite xyz_spibus_initialize() function for the MCU "xyz" with + * the appropriate port number. * ****************************************************************************/ diff --git a/include/nuttx/modem/u-blox.h b/include/nuttx/modem/u-blox.h new file mode 100644 index 0000000000000000000000000000000000000000..3b08ac422d781cf30b18803793882fa4c03d46e6 --- /dev/null +++ b/include/nuttx/modem/u-blox.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * include/nuttx/modem/u-blox.h + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * 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 __INCLUDE_NUTTX_MODEM_U_BLOX_H +#define __INCLUDE_NUTTX_MODEM_U_BLOX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MODEM_IOC_POWERON _MODEMIOC(1) +#define MODEM_IOC_POWEROFF _MODEMIOC(2) +#define MODEM_IOC_RESET _MODEMIOC(3) +#define MODEM_IOC_GETSTATUS _MODEMIOC(4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ubxmdm_regval +{ + FAR char name[3]; + bool val; +}; + +struct ubxmdm_status +{ + bool on; + int register_values_size; + FAR struct ubxmdm_regval* register_values; +}; + +struct ubxmdm_lower; + +struct ubxmdm_ops +{ + CODE int (*poweron) (FAR struct ubxmdm_lower* lower); + CODE int (*poweroff) (FAR struct ubxmdm_lower* lower); + CODE int (*reset) (FAR struct ubxmdm_lower* lower); + CODE int (*getstatus)(FAR struct ubxmdm_lower* lower, + FAR struct ubxmdm_status* status); + CODE int (*ioctl) (FAR struct ubxmdm_lower* lower, + int cmd, + unsigned long arg); +}; + +struct ubxmdm_lower +{ + FAR const struct ubxmdm_ops *ops; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * "Upper-Half" Timer Driver Interfaces + ****************************************************************************/ + +FAR void *ubxmdm_register(FAR const char *path, + FAR struct ubxmdm_lower *lower); + +void ubxmdm_unregister(FAR void *handle); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_MODEM_U_BLOX_H */ diff --git a/include/nuttx/module.h b/include/nuttx/module.h new file mode 100644 index 0000000000000000000000000000000000000000..7ce8b80447292358a2df43b4dbd4490539befa38 --- /dev/null +++ b/include/nuttx/module.h @@ -0,0 +1,250 @@ +/**************************************************************************** + * include/nuttx/module.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_MODULE_H +#define __INCLUDE_NUTTX_MODULE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_MODULE_ALIGN_LOG2 +# define CONFIG_MODULE_ALIGN_LOG2 2 +#endif + +#ifndef CONFIG_MODULE_BUFFERSIZE +# define CONFIG_MODULE_BUFFERSIZE 128 +#endif + +#ifndef CONFIG_MODULE_BUFFERINCR +# define CONFIG_MODULE_BUFFERINCR 32 +#endif + +#define MODULENAME_MAX 16 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This is the type of the function that is called to uninitialize the + * the loaded module. This may mean, for example, un-registering a device + * driver. If the module is successfully initialized, its memory will be + * deallocated. + * + * Input Parameters: + * arg - An opaque argument that was previously returned by the initializer + * function. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure to + * initialize the module. If zero is returned, then the module memory + * will be deallocated. If the module is still in use (for example with + * open driver instances), the uninitialization function should fail with + * -EBUSY + */ + +typedef CODE int (*mod_uninitializer_t)(FAR void *arg); + +/* A NuttX module is expected to export a function called module_initialize() + * that has the following function prototype. This function should appear as + * the entry point in the ELF module file and will be called bythe binfmt + * logic after the module has been loaded into kernel memory. + * + * Input Parameters: + * uninitializer - The pointer to the uninitialization function. NULL may + * be returned if no uninitialization is needed (i.e, the the module + * memory can be deallocated at any time). + * arg - An argument that will be passed to the uninitialization function. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure to + * initialize the module. + */ + +typedef CODE int (*mod_initializer_t)(mod_uninitializer_t *uninitializer, + FAR void **arg); + +#ifdef __KERNEL__ +/* This is the type of the callback function used by mod_registry_foreach() */ + +struct module_s; +typedef CODE int (*mod_callback_t)(FAR struct module_s *modp, FAR void *arg); +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mod_getsymtab + * + * Description: + * Get the current kernel symbol table selection as an atomic operation. + * + * Input Parameters: + * symtab - The location to store the symbol table. + * nsymbols - The location to store the number of symbols in the symbol table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef __KERNEL__ +void mod_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols); +#endif + +/**************************************************************************** + * Name: mod_setsymtab + * + * Description: + * Select a new kernel symbol table selection as an atomic operation. + * + * Input Parameters: + * symtab - The new symbol table. + * nsymbols - The number of symbols in the symbol table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef __KERNEL__ +void mod_setsymtab(FAR const struct symtab_s *symtab, int nsymbols); +#endif + +/**************************************************************************** + * Name: insmod + * + * Description: + * Verify that the file is an ELF module binary and, if so, load the + * module into kernel memory and initialize it for use. + * + * NOTE: mod_setsymtab had to have been called in board-specific OS logic + * prior to calling this function from application logic (perhaps via + * boardctl(BOARDIOC_OS_SYMTAB). Otherwise, insmod will be unable to + * resolve symbols in the OS module. + * + * Input Parameters: + * + * filename - Full path to the module binary to be loaded + * modulename - The name that can be used to refer to the module after + * it has been loaded. + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int insmod(FAR const char *filename, FAR const char *modulename); + +/**************************************************************************** + * Name: rmmod + * + * Description: + * Remove a previously installed module from memory. + * + * Input Parameters: + * + * modulename - The module name. This is the name module name that was + * provided to insmod when the module was loaded. + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int rmmod(FAR const char *modulename); + +/**************************************************************************** + * Name: mod_registry_foreach + * + * Description: + * Visit each module in the registry. This is an internal OS interface and + * not available for use by applications. + * + * Input Parameters: + * callback - This callback function was be called for each entry in the + * registry. + * arg - This opaque argument will be passed to the callback function. + * + * Returned Value: + * This function normally returns zero (OK). If, however, any callback + * function returns a non-zero value, the traversal will be terminated and + * that non-zero value will be returned. + * + * Assumptions: + * The caller does NOT hold the lock on the module registry. + * + ****************************************************************************/ + +#ifdef __KERNEL__ +int mod_registry_foreach(mod_callback_t callback, FAR void *arg); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_MODULE_H */ diff --git a/include/nuttx/mqueue.h b/include/nuttx/mqueue.h index 857bbfa0ea39e9bdd4d876d75d1b3ce616d7099e..53fa3af9f8e18dab0b705201db7b393d8c64c8ee 100644 --- a/include/nuttx/mqueue.h +++ b/include/nuttx/mqueue.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/mqueue.h * - * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -57,7 +57,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Type Declarations + * Public Type Declarations ****************************************************************************/ /* This structure defines a message queue */ @@ -80,8 +80,7 @@ struct mqueue_inode_s #ifndef CONFIG_DISABLE_SIGNALS FAR struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */ pid_t ntpid; /* Notification: Receiving Task's PID */ - int ntsigno; /* Notification: Signal number */ - union sigval ntvalue; /* Notification: Signal value */ + struct sigevent ntevent; /* Notification description */ #endif }; @@ -97,11 +96,11 @@ struct mq_des }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #ifdef __cplusplus @@ -112,7 +111,7 @@ extern "C" #define EXTERN extern #endif -/************************************************************************ +/**************************************************************************** * Name: mq_msgqfree * * Description: @@ -128,7 +127,7 @@ extern "C" * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_msgqfree(FAR struct mqueue_inode_s *msgq); diff --git a/include/nuttx/mtd/mtd.h b/include/nuttx/mtd/mtd.h index 4162cde6f9f1bfc4ac472d974f5892e0b05ec2bb..c8a34052c8acd67e8d075f43eea9e967ba1b0938 100644 --- a/include/nuttx/mtd/mtd.h +++ b/include/nuttx/mtd/mtd.h @@ -45,10 +45,41 @@ #include #include +#include + +#include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Ioctl commands */ + +#define MTDIOC_GEOMETRY _MTDIOC(0x0001) /* IN: Pointer to write-able struct + * mtd_geometry_s in which to receive + * receive geometry data (see mtd.h) + * OUT: Geometry structure is populated + * with data for the MTD */ +#define MTDIOC_XIPBASE _MTDIOC(0x0002) /* IN: Pointer to pointer to void in + * which to received the XIP base. + * OUT: If media is directly accessible, + * return (void*) base address + * of device memory */ +#define MTDIOC_BULKERASE _MTDIOC(0x0003) /* IN: None + * OUT: None */ +#define MTDIOC_PROTECT _MTDIOC(0x0004) /* IN: Pointer to read-able struct + * mtd_protects_s that provides + * the region to protect. + * OUT: None */ +#define MTDIOC_UNPROTECT _MTDIOC(0x0005) /* IN: Pointer to read-able struct + * mtd_protects_s that provides + * the region to un-protect. + * OUT: None */ +#define MTDIOC_SETSPEED _MTDIOC(0x0006) /* IN: New bus speed in Hz + * OUT: None */ +#define MTDIOC_EXTENDED _MTDIOC(0x0007) /* IN: unsigned long + * 0=Use normal memory region + * 1=Use alternate/extended memory + * OUT: None */ /* Macros to hide implementation */ @@ -83,13 +114,22 @@ struct mtd_geometry_s { - uint16_t blocksize; /* Size of one read/write block. */ - /* Probably 16-bits wasted here for alignment */ + uint32_t blocksize; /* Size of one read/write block. */ uint32_t erasesize; /* Size of one erase blocks -- must be a multiple * of blocksize.*/ uint32_t neraseblocks; /* Number of erase blocks */ }; +/* This structure describes a range of sectors to be protected or + * unprotected. + */ + +struct mtd_protect_s +{ + off_t startblock; /* First block to be [un-]protected */ + size_t nblocks; /* Number of blocks to [un-]protect */ +}; + /* The following defines the information for writing bytes to a sector * that are not a full page write (bytewrite). */ @@ -295,24 +335,31 @@ int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, * functions (such as a block or character driver front end). */ -/************************************************************************************ +/**************************************************************************** * Name: s512_initialize * * Description: - * Create an initialized MTD device instance. This MTD driver contains another - * MTD driver and converts a larger sector size to a standard 512 byte sector - * size. - * - * MTD devices are not registered in the file system, but are created as instances - * that can be bound to other functions (such as a block or character driver front - * end). + * Create an initialized MTD device instance. This MTD driver contains + * another MTD driver and converts a larger sector size to a standard 512 + * byte sector size. * - ************************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_MTD_SECT512 FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd); #endif +/**************************************************************************** + * Name: progmem_initialize + * + * Description: + * Create and initialize an MTD device instance that can be used to access + * on-chip program memory. + * + ****************************************************************************/ + +FAR struct mtd_dev_s *progmem_initialize(void); + /**************************************************************************** * Name: at45db_initialize * @@ -333,8 +380,27 @@ FAR struct mtd_dev_s *at45db_initialize(FAR struct spi_dev_s *dev); * ****************************************************************************/ -struct i2c_dev_s; /* Forward reference */ -FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev); +struct i2c_master_s; /* Forward reference */ + +#ifdef CONFIG_AT24XX_MULTI +FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev, + uint8_t address); +#else +FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev); +#endif + +/************************************************************************************ + * Name: at24c_uninitialize + * + * Description: + * Release resources held by an allocated MTD device instance. Resources are only + * allocated for the case where multiple AT24xx devices are support. + * + ************************************************************************************/ + +#ifdef CONFIG_AT24XX_MULTI +void at24c_uninitialize(FAR struct mtd_dev_s *mtd); +#endif /**************************************************************************** * Name: at25_initialize @@ -434,6 +500,19 @@ FAR struct mtd_dev_s *sst39vf_initialize(void); FAR struct mtd_dev_s *w25_initialize(FAR struct spi_dev_s *dev); +/**************************************************************************** + * Name: s25fl1_initialize + * + * Description: + * Create an initialize MTD device instance for the QuadSPI-based ST24FL1 + * FLASH part. + * + ****************************************************************************/ + +struct qspi_dev_s; /* Forward reference */ +FAR struct mtd_dev_s *s25fl1_initialize(FAR struct qspi_dev_s *qspi, + bool unprotect); + /**************************************************************************** * Name: up_flashinitialize * @@ -444,6 +523,37 @@ FAR struct mtd_dev_s *w25_initialize(FAR struct spi_dev_s *dev); FAR struct mtd_dev_s *up_flashinitialize(void); +/**************************************************************************** + * Name: filemtd_initialize + * + * Description: + * Create a file backed MTD device. + * + ****************************************************************************/ + +FAR struct mtd_dev_s *filemtd_initialize(FAR const char *path, size_t offset, + int16_t sectsize, int32_t erasesize); + +/**************************************************************************** + * Name: filemtd_teardown + * + * Description: + * Tear down a filemtd device. + * + ****************************************************************************/ + +void filemtd_teardown(FAR struct mtd_dev_s* mtd); + +/**************************************************************************** + * Name: filemtd_isfilemtd + * + * Description: + * Test if MTD is a filemtd device. + * + ****************************************************************************/ + +bool filemtd_isfilemtd(FAR struct mtd_dev_s* mtd); + /**************************************************************************** * Name: mtd_register * @@ -461,6 +571,21 @@ FAR struct mtd_dev_s *up_flashinitialize(void); int mtd_register(FAR struct mtd_dev_s *mtd, FAR const char *name); #endif +/**************************************************************************** + * Name: mtd_unregister + * + * Description: + * Un-registers an MTD device with the procfs file system. + * + * In an embedded system, this all is really unnecessary, but is provided + * in the procfs system simply for information purposes (if desired). + * + ****************************************************************************/ + +#ifdef CONFIG_MTD_REGISTRATION +int mtd_unregister(FAR struct mtd_dev_s *mtd); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/6lowpan.h b/include/nuttx/net/6lowpan.h new file mode 100644 index 0000000000000000000000000000000000000000..cbd7e071bf3829c226ae0fe4c5e86af80e5e43c2 --- /dev/null +++ b/include/nuttx/net/6lowpan.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * include/nuttx/net/6lowpan.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Includes some definitions that a compatible with the LGPL GNU C Library + * header file of the same name. + * + * 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 __INCLUDE_NUTTX_NET_6LOWPAN_H +#define __INCLUDE_NUTTX_NET_6LOWPAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __INCLUDE_NUTTX_NET_6LOWPAN_H */ diff --git a/include/nuttx/net/arp.h b/include/nuttx/net/arp.h index 502d89b0e63d282e46072ac110c972be88ac695d..236053ce70393d6fc7d4f5fb77a7a5560e152e0c 100644 --- a/include/nuttx/net/arp.h +++ b/include/nuttx/net/arp.h @@ -2,7 +2,7 @@ * include/nuttx/net/arp.h * Macros and definitions for the ARP module. * - * Copyright (C) 2007, 2009-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009-2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Derived from uIP with has a similar BSD-styple license: @@ -48,6 +48,7 @@ #include #include +#include #include #include @@ -60,6 +61,16 @@ * Pre-processor Definitions ****************************************************************************/ +/* ARP protocol HARDWARE identifiers. Provided as the sa_family member of a + * struct sockaddr. + * + * When sa_family is ARPHRD_ETHER, the 6 byte Ethernet address is provided + * in the first 6-bytes of the sockaddr sa_data array. + */ + +#define ARPHRD_ETHER 1 /* Ethernet */ +#define ARPHRD_IEEE802154 804 /* IEEE 802.15.4 */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -70,9 +81,29 @@ struct arp_entry { in_addr_t at_ipaddr; /* IP address */ struct ether_addr at_ethaddr; /* Hardware address */ - uint8_t at_time; + uint8_t at_time; /* Time of last usage */ }; +/* Used with the SIOCSARP, SIOCDARP, and SIOCGARP IOCTL commands to set, + * delete, or get an ARP table entry. + * + * SIOCSARP - Both values are inputs a define the new ARP table entry + * SIOCDARP - Only the protcol address is required as an input. The ARP + * table entry with that matching address will be deleted, + * regardless of the hardware address. + * SIOCGARP - The protocol address is an input an identifies the table + * entry to locate; The hardware address is an output and + * on a successful lookup, provides the matching hardware + * address. + */ + +struct arpreq +{ + struct sockaddr arp_pa; /* Protocol address */ + struct sockaddr arp_ha; /* Hardware address */ +}; + + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/include/nuttx/net/cs89x0.h b/include/nuttx/net/cs89x0.h index 493a552a18233558974401eca6f9422cb162a964..9d92a193117d21c0accbb95eb0b522ed9f3c6201 100644 --- a/include/nuttx/net/cs89x0.h +++ b/include/nuttx/net/cs89x0.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/cs89x0.h * - * Copyright (C) 2009, 2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2012, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,29 +49,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_C89x0_STATISTICS -struct cs89x0_statistics_s -{ - uint32_t tx_packets; - uint32_t tx_errors; - uint32_t tx_carriererrors; - uint32_t tx_heartbeaterrors; - uint32_t tx_windowerrors; - uint32_t tx_abortederrors; - uint32_t rx_missederrors; - uint32_t rx_packets; - uint32_t rx_errors; - uint32_t rx_lengtherrors; - uint32_t rx_crcerrors; - uint32_t rx_frameerrors; - uint32_t rx_dropped; - uint32_t rx_missederrors; - uint32_t collisions; -}; -#endif - /* This structure encapsulates all state information for a single hardware * interface. It includes values that must be provided by the user to in * to describe details of the CS89x00 implementation on a particular board. @@ -112,12 +89,6 @@ struct cs89x0_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s cs_dev; /* Interface understood by uIP */ - - /* Driver statistics */ - -#ifdef CONFIG_C89x0_STATISTICS - struct cs89x0_statistics_s cs_stats; -#endif }; /**************************************************************************** diff --git a/include/nuttx/net/dns.h b/include/nuttx/net/dns.h index 94da6abbec6b836d891fd04781df0052b3f4cbd3..8c11147e7ed0f36dd12beac4f2ad89a0ec41014c 100644 --- a/include/nuttx/net/dns.h +++ b/include/nuttx/net/dns.h @@ -164,6 +164,12 @@ struct dns_answer_s } u; }; +/* The type of the callback from dns_foreach_nameserver() */ + +typedef CODE int (*dns_callback_t)(FAR void *arg, + FAR struct sockaddr *addr, + FAR socklen_t addrlen); + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -178,25 +184,35 @@ extern "C" #endif /**************************************************************************** - * Name: dns_setserver + * Name: dns_add_nameserver * * Description: - * Configure which DNS server to use for queries. Set the port number - * to zero to use the default DNS server port. + * Configure a DNS server to use for queries. Set the port number to zero + * to use the default DNS server port. * ****************************************************************************/ -int dns_setserver(FAR const struct sockaddr *addr, socklen_t addrlen); +int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen); + +/**************************************************************************** + * Name: dns_del_nameserver + * + * Description: + * Remove a DNS server so it is no longer available for further use. + * + ****************************************************************************/ +/* REVISIT: Not implemented */ /**************************************************************************** - * Name: dns_getserver + * Name: dns_foreach_nameserver * * Description: - * Obtain the currently configured DNS server. + * Traverse each nameserver entry in the resolv.conf file and perform the + * the provided callback. * ****************************************************************************/ -int dns_getserver(FAR struct sockaddr *addr, FAR socklen_t *addrlen); +int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg); #undef EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/net/enc28j60.h b/include/nuttx/net/enc28j60.h index aeb8e5166219e75269dff0ecd879291def8a4c65..b5d31e4654272163ff5efffc6c4e95ae74866b2f 100644 --- a/include/nuttx/net/enc28j60.h +++ b/include/nuttx/net/enc28j60.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/enc28j60.h * - * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,6 @@ * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 * devices that will be supported. - * CONFIG_ENC28J60_STATS - Collect network statistics * CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex */ @@ -64,24 +63,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_ENC28J60_STATS -struct enc_stats_s -{ - uint8_t maxpktcnt; /* Max. number of buffered RX packets */ - uint32_t txrequests; /* Number of TX packets queued */ - uint32_t txifs; /* TXIF completion events */ - uint32_t txabrts; /* TXIF completions with ESTAT.TXABRT */ - uint32_t txerifs; /* TXERIF error events */ - uint32_t txtimeouts; /* S/W detected TX timeouts */ - uint32_t pktifs; /* PKTIF RX completion events */ - uint32_t rxnotok; /* PKTIF without RXSTAT_OK */ - uint32_t rxpktlen; /* PKTIF with bad pktlen */ - uint32_t rxerifs; /* RXERIF error evernts */ -}; -#endif - /* The ENC28J60 normal provides interrupts to the MCU via a GPIO pin. The * following structure provides an MCU-independent mechanixm for controlling * the ENC28J60 GPIO interrupt. @@ -151,29 +132,6 @@ struct spi_dev_s; /* see nuttx/spi/spi.h */ int enc_initialize(FAR struct spi_dev_s *spi, FAR const struct enc_lower_s *lower, unsigned int devno); -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENC28J60 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENC28J60 is supported, then this is the - * zero based number that identifies the ENC28J60; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENC28J60_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/encx24j600.h b/include/nuttx/net/encx24j600.h index 0a39373a822fa297a4210fbcb68e71fc8b56cbcd..39ce6c8664e8f67a988a9d098f0a0601097a4531 100644 --- a/include/nuttx/net/encx24j600.h +++ b/include/nuttx/net/encx24j600.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/encx24j600.h * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,6 @@ * CONFIG_ENCX24J600_FREQUENCY - Define to use a different bus frequency * CONFIG_ENCX24J600_NINTERFACES - Specifies the number of physical ENCX24J600 * devices that will be supported. - * CONFIG_ENCX24J600_STATS - Collect network statistics * CONFIG_ENCX24J600_HALFDUPPLEX - Default is full duplex */ @@ -64,24 +63,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_ENCX24J600_STATS -struct enc_stats_s -{ - uint8_t maxpktcnt; /* Max. number of buffered RX packets */ - uint32_t txrequests; /* Number of TX packets queued */ - uint32_t txifs; /* TXIF completion events */ - uint32_t txabrts; /* TXIF completions with ESTAT.TXABRT */ - uint32_t txerifs; /* TXERIF error events */ - uint32_t txtimeouts; /* S/W detected TX timeouts */ - uint32_t pktifs; /* PKTIF RX completion events */ - uint32_t rxnotok; /* PKTIF without RXSTAT_OK */ - uint32_t rxpktlen; /* PKTIF with bad pktlen */ - uint32_t rxerifs; /* RXERIF error evernts */ -}; -#endif - /* The ENCX24J600 normal provides interrupts to the MCU via a GPIO pin. The * following structure provides an MCU-independent mechanixm for controlling * the ENCX24J600 GPIO interrupt. @@ -150,30 +131,6 @@ extern "C" struct spi_dev_s; /* see nuttx/spi/spi.h */ int enc_initialize(FAR struct spi_dev_s *spi, FAR const struct enc_lower_s *lower, unsigned int devno); - -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENCX24J600 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENCX24J600 is supported, then this is the - * zero based number that identifies the ENCX24J600; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENCX24J600_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/iob.h b/include/nuttx/net/iob.h index 121d82ae1f1f85813fe29d5f52a31fea7a929286..b9ff53d78c9d5d83bb4f89ff0283b2555e602cba 100644 --- a/include/nuttx/net/iob.h +++ b/include/nuttx/net/iob.h @@ -157,7 +157,7 @@ struct iob_queue_s #endif /* CONFIG_IOB_NCHAINS > 0 */ /**************************************************************************** - * Global Data + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/nuttx/net/ioctl.h b/include/nuttx/net/ioctl.h index 5b617314d7ef7812ab1b2d5ff2af23693d551df2..a20d5e231b2c395a00cd2261c015cd3076727bd1 100644 --- a/include/nuttx/net/ioctl.h +++ b/include/nuttx/net/ioctl.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/ioctl.h * - * Copyright (C) 2007-2008, 2010-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2008, 2010-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -94,92 +94,106 @@ #define SIOCGIPMSFILTER _SIOC(0x001a) /* Retrieve source filter addresses */ #define SIOCSIPMSFILTER _SIOC(0x001b) /* Set source filter content */ +/* ARP Table. Argument is a reference to sruct arpreq as defined + * include/nuttx/net/arp.h + */ + +#define SIOCSARP _SIOC(0x001c) /* Set an ARP mapping */ +#define SIOCDARP _SIOC(0x001d) /* Delete an ARP mapping */ +#define SIOCGARP _SIOC(0x001e) /* Get an ARP mapping */ + /* Routing table. Argument is a reference to struct rtentry as defined in * include/net/route.h */ -#define SIOCADDRT _SIOC(0x001c) /* Add an entry to the routing table */ -#define SIOCDELRT _SIOC(0x001d) /* Delete an entry from the routing table */ +#define SIOCADDRT _SIOC(0x001f) /* Add an entry to the routing table */ +#define SIOCDELRT _SIOC(0x0020) /* Delete an entry from the routing table */ /* Wireless ioctl commands **************************************************/ - -#define SIOCSIWCOMMIT _SIOC(0x001e) /* Commit pending changes to driver */ -#define SIOCGIWNAME _SIOC(0x001f) /* Get name of wireless protocol */ - -#define SIOCSIWNWID _SIOC(0x0020) /* Set network ID (pre-802.11) */ -#define SIOCGIWNWID _SIOC(0x0021) /* Get network ID (the cell) */ -#define SIOCSIWFREQ _SIOC(0x0022) /* Set channel/frequency (Hz) */ -#define SIOCGIWFREQ _SIOC(0x0023) /* Get channel/frequency (Hz) */ -#define SIOCSIWMODE _SIOC(0x0024) /* Set operation mode */ -#define SIOCGIWMODE _SIOC(0x0025) /* Get operation mode */ -#define SIOCSIWSENS _SIOC(0x0026) /* Set sensitivity (dBm) */ -#define SIOCGIWSENS _SIOC(0x0027) /* Get sensitivity (dBm) */ - -#define SIOCGIWRANGE _SIOC(0x0028) /* Get range of parameters */ -#define SIOCGIWPRIV _SIOC(0x0029) /* Get private ioctl interface info */ -#define SIOCGIWSTATS _SIOC(0x002a) /* Get wireless stats */ - -#define SIOCSIWSPY _SIOC(0x002b) /* Set spy addresses */ -#define SIOCGIWSPY _SIOC(0x002c) /* Get spy info (quality of link) */ -#define SIOCSIWTHRSPY _SIOC(0x002d) /* Set spy threshold (spy event) */ -#define SIOCGIWTHRSPY _SIOC(0x002e) /* Get spy threshold */ - -#define SIOCSIWAP _SIOC(0x002f) /* Set access point MAC addresses */ -#define SIOCGIWAP _SIOC(0x0030) /* Get access point MAC addresses */ -#define SIOCGIWAPLIST _SIOC(0x0031) /* Deprecated in favor of scanning */ -#define SIOCSIWSCAN _SIOC(0x0032) /* Trigger scanning (list cells) */ -#define SIOCGIWSCAN _SIOC(0x0033) /* Get scanning results */ - -#define SIOCSIWESSID _SIOC(0x0034) /* Set ESSID (network name) */ -#define SIOCGIWESSID _SIOC(0x0035) /* Get ESSID */ -#define SIOCSIWNICKN _SIOC(0x0036) /* Set node name/nickname */ -#define SIOCGIWNICKN _SIOC(0x0037) /* Get node name/nickname */ - -#define SIOCSIWRATE _SIOC(0x0038) /* Set default bit rate (bps) */ -#define SIOCGIWRATE _SIOC(0x0039) /* Get default bit rate (bps) */ -#define SIOCSIWRTS _SIOC(0x003a) /* Set RTS/CTS threshold (bytes) */ -#define SIOCGIWRTS _SIOC(0x003b) /* Get RTS/CTS threshold (bytes) */ -#define SIOCSIWFRAG _SIOC(0x003c) /* Set fragmentation thr (bytes) */ -#define SIOCGIWFRAG _SIOC(0x003d) /* Get fragmentation thr (bytes) */ -#define SIOCSIWTXPOW _SIOC(0x003e) /* Set transmit power (dBm) */ -#define SIOCGIWTXPOW _SIOC(0x003f) /* Get transmit power (dBm) */ -#define SIOCSIWRETRY _SIOC(0x0040) /* Set retry limits and lifetime */ -#define SIOCGIWRETRY _SIOC(0x0041) /* Get retry limits and lifetime */ - -#define SIOCSIWPOWER _SIOC(0x0042) /* Set Power Management settings */ -#define SIOCGIWPOWER _SIOC(0x0043) /* Get Power Management settings */ - -#define SIOCSIWGENIE _SIOC(0x0044) /* Set generic IE */ -#define SIOCGIWGENIE _SIOC(0x0045) /* Get generic IE */ - -#define SIOCSIWMLME _SIOC(0x0046) /* Request MLME operation */ - -#define SIOCSIWAUTH _SIOC(0x0047) /* Set authentication mode params */ -#define SIOCGIWAUTH _SIOC(0x0048) /* Get authentication mode params */ - -#define SIOCSIWENCODEEXT _SIOC(0x0049) /* Set encoding token & mode */ -#define SIOCGIWENCODEEXT _SIOC(0x004a) /* Get encoding token & mode */ - -#define SIOCSIWPMKSA _SIOC(0x004b) /* PMKSA cache operation */ +/* Not currently used */ + +#define SIOCSIWCOMMIT _SIOC(0x0021) /* Commit pending changes to driver */ +#define SIOCGIWNAME _SIOC(0x0022) /* Get name of wireless protocol */ + +#define SIOCSIWNWID _SIOC(0x0023) /* Set network ID (pre-802.11) */ +#define SIOCGIWNWID _SIOC(0x0024) /* Get network ID (the cell) */ +#define SIOCSIWFREQ _SIOC(0x0025) /* Set channel/frequency (Hz) */ +#define SIOCGIWFREQ _SIOC(0x0026) /* Get channel/frequency (Hz) */ +#define SIOCSIWMODE _SIOC(0x0027) /* Set operation mode */ +#define SIOCGIWMODE _SIOC(0x0028) /* Get operation mode */ +#define SIOCSIWSENS _SIOC(0x0029) /* Set sensitivity (dBm) */ +#define SIOCGIWSENS _SIOC(0x002a) /* Get sensitivity (dBm) */ + +#define SIOCGIWRANGE _SIOC(0x002b) /* Get range of parameters */ +#define SIOCGIWPRIV _SIOC(0x002c) /* Get private ioctl interface info */ +#define SIOCGIWSTATS _SIOC(0x002d) /* Get wireless stats */ + +#define SIOCSIWSPY _SIOC(0x002e) /* Set spy addresses */ +#define SIOCGIWSPY _SIOC(0x002f) /* Get spy info (quality of link) */ +#define SIOCSIWTHRSPY _SIOC(0x0030) /* Set spy threshold (spy event) */ +#define SIOCGIWTHRSPY _SIOC(0x0031) /* Get spy threshold */ + +#define SIOCSIWAP _SIOC(0x0032) /* Set access point MAC addresses */ +#define SIOCGIWAP _SIOC(0x0033) /* Get access point MAC addresses */ +#define SIOCGIWAPLIST _SIOC(0x0034) /* Deprecated in favor of scanning */ +#define SIOCSIWSCAN _SIOC(0x0035) /* Trigger scanning (list cells) */ +#define SIOCGIWSCAN _SIOC(0x0036) /* Get scanning results */ + +#define SIOCSIWESSID _SIOC(0x0037) /* Set ESSID (network name) */ +#define SIOCGIWESSID _SIOC(0x0038) /* Get ESSID */ +#define SIOCSIWNICKN _SIOC(0x0039) /* Set node name/nickname */ +#define SIOCGIWNICKN _SIOC(0x003a) /* Get node name/nickname */ + +#define SIOCSIWRATE _SIOC(0x003b) /* Set default bit rate (bps) */ +#define SIOCGIWRATE _SIOC(0x003c) /* Get default bit rate (bps) */ +#define SIOCSIWRTS _SIOC(0x003d) /* Set RTS/CTS threshold (bytes) */ +#define SIOCGIWRTS _SIOC(0x003e) /* Get RTS/CTS threshold (bytes) */ +#define SIOCSIWFRAG _SIOC(0x003f) /* Set fragmentation thr (bytes) */ +#define SIOCGIWFRAG _SIOC(0x0040) /* Get fragmentation thr (bytes) */ +#define SIOCSIWTXPOW _SIOC(0x0041) /* Set transmit power (dBm) */ +#define SIOCGIWTXPOW _SIOC(0x0042) /* Get transmit power (dBm) */ +#define SIOCSIWRETRY _SIOC(0x0043) /* Set retry limits and lifetime */ +#define SIOCGIWRETRY _SIOC(0x0044) /* Get retry limits and lifetime */ + +#define SIOCSIWPOWER _SIOC(0x0045) /* Set Power Management settings */ +#define SIOCGIWPOWER _SIOC(0x0046) /* Get Power Management settings */ + +#define SIOCSIWGENIE _SIOC(0x0047) /* Set generic IE */ +#define SIOCGIWGENIE _SIOC(0x0048) /* Get generic IE */ + +#define SIOCSIWMLME _SIOC(0x0049) /* Request MLME operation */ + +#define SIOCSIWAUTH _SIOC(0x004a) /* Set authentication mode params */ +#define SIOCGIWAUTH _SIOC(0x004b) /* Get authentication mode params */ + +#define SIOCSIWENCODEEXT _SIOC(0x004c) /* Set encoding token & mode */ +#define SIOCGIWENCODEEXT _SIOC(0x004d) /* Get encoding token & mode */ + +#define SIOCSIWPMKSA _SIOC(0x004e) /* PMKSA cache operation */ /* MDIO/MCD *****************************************************************/ -#define SIOCMIINOTIFY _SIOC(0x004b) /* Receive notificaion via signal on - * PHY state change */ -#define SIOCGMIIPHY _SIOC(0x004c) /* Get address of MII PHY in use */ -#define SIOCGMIIREG _SIOC(0x004d) /* Get a MII register via MDIO */ -#define SIOCSMIIREG _SIOC(0x004e) /* Set a MII register via MDIO */ +#define SIOCMIINOTIFY _SIOC(0x004f) /* Receive notificaion via signal on + * PHY state change */ +#define SIOCGMIIPHY _SIOC(0x0050) /* Get address of MII PHY in use */ +#define SIOCGMIIREG _SIOC(0x0051) /* Get a MII register via MDIO */ +#define SIOCSMIIREG _SIOC(0x0052) /* Set a MII register via MDIO */ /* Unix domain sockets ******************************************************/ -#define SIOCINQ _SIOC(0x004f) /* Returns the amount of queued unread - * data in the receive */ +#define SIOCINQ _SIOC(0x0053) /* Returns the amount of queued unread + * data in the receive */ + +/* Telnet driver ************************************************************/ + +#define SIOCTELNET _SIOC(0x0054) /* Create a Telnet sessions. + * See include/nuttx/net/telnet.h */ /**************************************************************************** - * Type Definitions + * Pulbic Type Definitions ****************************************************************************/ -/* See include/net/if.h */ +/* See include/net/if.h, include/net/route.h, and include/net/arp.h */ /**************************************************************************** * Public Function Prototypes diff --git a/include/nuttx/net/ip.h b/include/nuttx/net/ip.h index 59088d90591fc9e9edcc910c01ea865b8386e08d..c707b91bda494ba7df4925f219c211bc0960fce2 100644 --- a/include/nuttx/net/ip.h +++ b/include/nuttx/net/ip.h @@ -62,6 +62,12 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* IP Version Mask (bits 0-3 of first byte) */ + +#define IP_VERSION_MASK 0x70 +#define IPv4_VERSION 0x40 +#define IPv6_VERSION 0x60 + /* Values for the IP protocol field */ #define IP_PROTO_ICMP 1 diff --git a/include/nuttx/fs/mksmartfs.h b/include/nuttx/net/loopback.h similarity index 65% rename from include/nuttx/fs/mksmartfs.h rename to include/nuttx/net/loopback.h index e0a841ca0f4b5f57de29cc9617c1f4b2b3e3835d..76e8312c39a9e80622eb1c4cd138af1ff98da915 100644 --- a/include/nuttx/fs/mksmartfs.h +++ b/include/nuttx/net/loopback.h @@ -1,8 +1,12 @@ /**************************************************************************** - * include/nuttx/fs/mksmartfs.h + * include/nuttx/net/loopback.h + * Definitions for use with local loopback device * - * Copyright (C) 2013, 2015 Ken Pettit. All rights reserved. - * Author: Ken Pettit + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory nutt + * + * Includes some definitions that a compatible with the LGPL GNU C Library + * header file of the same name. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,34 +37,36 @@ * ****************************************************************************/ -#ifndef __INCLUDE_NUTTX_SMART_MKSMARTFS_H -#define __INCLUDE_NUTTX_SMART_MKSMARTFS_H +#ifndef __INCLUDE_NUTTX_NET_LOOPBACK_H +#define __INCLUDE_NUTTX_NET_LOOPBACK_H /**************************************************************************** * Included Files ****************************************************************************/ #include -#include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ +#include +#include + +#ifdef CONFIG_NET_LOOPBACK /**************************************************************************** - * Public Types + * Public Type Definitions ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -#undef EXTERN -#if defined(__cplusplus) +#ifdef __cplusplus #define EXTERN extern "C" extern "C" { @@ -68,43 +74,47 @@ extern "C" #define EXTERN extern #endif +#ifdef CONFIG_LIBC_NETDB +/* Local loopback hostname */ + +EXTERN const char g_lo_hostname[]; +#endif + +/* Local loopback addresses */ + +EXTERN const in_addr_t g_lo_ipv4addr; +EXTERN const in_addr_t g_lo_ipv4mask; +EXTERN const net_ipv6addr_t g_lo_ipv6addr; + /**************************************************************************** - * Name: mksmartfs + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Function: localhost_initialize * * Description: - * Make a SMART (Sector Mapped Allocation for Really Tiny) Flash file - * system image on the specified block device (must be a SMART device). - * - * Inputs: - * pathname - the full path to a registered block driver - * nrootdirs - the number of Root Directory entries to support - * on this device (supports multiple mount points). + * Initialize the Ethernet controller and driver * - * Return: - * Zero (OK) on success; -1 (ERROR) on failure with errno set appropriately: + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. * - * EINVAL - NULL block driver string - * ENOENT - 'pathname' does not refer to anything in the filesystem. - * ENOTBLK - 'pathname' does not refer to a block driver - * EACCESS - block driver does not support write or geometry methods or - * is not a SMART device + * Returned Value: + * OK on success; Negated errno on failure. * * Assumptions: - * - The caller must assure that the block driver is not mounted and not in - * use when this function is called. The result of formatting a mounted - * device is indeterminate (but likely not good). * ****************************************************************************/ -#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS -int mksmartfs(FAR const char *pathname, uint8_t nrootdirs); -#else -int mksmartfs(FAR const char *pathname); -#endif +#ifdef CONFIG_NETDEV_LOOPBACK +int localhost_initialize(void); +#endif /* CONFIG_NETDEV_LOOPBACK */ #undef EXTERN -#if defined(__cplusplus) +#ifdef __cplusplus } #endif -#endif /* __INCLUDE_NUTTX_SMART_MKSMARTFS_H */ +#endif /* CONFIG_NET_LOOPBACK */ +#endif /* __INCLUDE_NUTTX_NET_LOOPBACK_H */ diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 77c7fd807ab1f72afb7bd059f78f0133af6fa053..a11c8bcd2e4c7244fc28bf6076977298fc465e98 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/net.h * - * Copyright (C) 2007, 2009-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ #include #ifndef CONFIG_NET_NOINTS -# include +# include #endif /**************************************************************************** @@ -76,9 +76,10 @@ enum net_lltype_e { NET_LL_ETHERNET = 0, /* Ethernet */ + NET_LL_LOOPBACK, /* Local loopback */ NET_LL_SLIP, /* Serial Line Internet Protocol (SLIP) */ - NET_LL_PPP, /* Point-to-Point Protocol (PPP) */ NET_LL_TUN, /* TUN Virtual Network Device */ + NET_LL_6LOWPAN /* IEEE 802.15.4 6LoWPAN*/ }; /* This defines a bitmap big enough for one bit for each socket option */ @@ -139,7 +140,7 @@ struct socketlist /* Callback from netdev_foreach() */ struct net_driver_s; /* Forward reference. Defined in nuttx/net/netdev.h */ -typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, void *arg); +typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, FAR void *arg); #ifdef CONFIG_NET_NOINTS /* Semaphore based locking for non-interrupt based logic. @@ -253,7 +254,7 @@ void net_initialize(void); #ifdef CONFIG_NET_NOINTS net_lock_t net_lock(void); #else -# define net_lock() irqsave() +# define net_lock() enter_critical_section() #endif /**************************************************************************** @@ -267,7 +268,7 @@ net_lock_t net_lock(void); #ifdef CONFIG_NET_NOINTS void net_unlock(net_lock_t flags); #else -# define net_unlock(f) irqrestore(f) +# define net_unlock(f) leave_critical_section(f) #endif /**************************************************************************** @@ -1078,7 +1079,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap); * * Parameters: * dev - The device driver structure to be registered. - * lltype - Link level protocol used by the driver (Ethernet, SLIP, PPP, ... + * lltype - Link level protocol used by the driver (Ethernet, SLIP, TUN, ... * * Returned Value: * 0:Success; negated errno on failure @@ -1130,7 +1131,7 @@ int netdev_unregister(FAR struct net_driver_s *dev); * ****************************************************************************/ -int netdev_foreach(netdev_callback_t callback, void *arg); +int netdev_foreach(netdev_callback_t callback, FAR void *arg); #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/net/netconfig.h b/include/nuttx/net/netconfig.h index aeea16b4e174bc7ffc6a2b9c65d1997789c66a5c..f65b1c478d30fa1fabe7ee7355e8a990cf13a0f9 100644 --- a/include/nuttx/net/netconfig.h +++ b/include/nuttx/net/netconfig.h @@ -62,6 +62,14 @@ * Public Type Definitions ****************************************************************************/ +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + /* Layer 2 Configuration Options ********************************************/ /* The default data link layer for uIP is Ethernet. If CONFIG_NET_SLIP is @@ -125,17 +133,29 @@ # define _MAX_ETH_MTU 0 # endif +# ifdef CONFIG_NET_LOOPBACK +# define _MIN_LO_MTU MIN(_MIN_ETH_MTU,1518) +# define _MAX_LO_MTU MAX(_MAX_ETH_MTU,574) +# else +# define _MIN_LO_MTU _MIN_ETH_MTU +# define _MAX_LO_MTU _MAX_ETH_MTU +# endif + # ifdef CONFIG_NET_SLIP -# define _MIN_SLIP_MTU MIN(_MIN_ETH_MTU,CONFIG_NET_SLIP_MTU) -# define _MAX_SLIP_MTU MAX(_MAX_ETH_MTU,CONFIG_NET_SLIP_MTU) +# define _MIN_SLIP_MTU MIN(_MIN_LO_MTU,CONFIG_NET_SLIP_MTU) +# define _MAX_SLIP_MTU MAX(_MAX_LO_MTU,CONFIG_NET_SLIP_MTU) # else -# define _MIN_SLIP_MTU _MIN_ETH_MTU -# define _MAX_SLIP_MTU _MAX_ETH_MTU +# define _MIN_SLIP_MTU _MIN_LO_MTU +# define _MAX_SLIP_MTU _MAX_LO_MTU # endif # define MIN_NET_DEV_MTU _MIN_SLIP_MTU # define MAX_NET_DEV_MTU _MAX_SLIP_MTU +/* For the loopback device, we will use the largest MTU */ + +# define NET_LO_MTU MAX_NET_DEV_MTU + #elif defined(CONFIG_NET_SLIP) /* There is no link layer header with SLIP */ @@ -156,8 +176,22 @@ # define MIN_NET_DEV_MTU CONFIG_NET_ETH_MTU # define MAX_NET_DEV_MTU CONFIG_NET_ETH_MTU +#elif defined(CONFIG_NET_LOOPBACK) + /* Force the loopback MTU to some reasonable size. We could do something smarter, but + * The case where the local loopback device is the only device is very unusal. + */ + +# define NET_LO_MTU 1518 + + /* Assume standard Ethernet link layer header */ + +# define NET_LL_HDRLEN(d) 0 +# define NET_DEV_MTU(d) NET_LO_MTU +# define MIN_NET_DEV_MTU NET_LO_MTU +# define MAX_NET_DEV_MTU NET_LO_MTU + #else - /* Perhaps only Unix domain sockets */ + /* Perhaps only Unix domain sockets of the loopback device */ # define NET_LL_HDRLEN(d) 0 # define NET_DEV_MTU(d) 0 @@ -226,9 +260,12 @@ /* If Ethernet is supported, then it will have the smaller MSS */ -#ifdef CONFIG_NET_SLIP +#if defined(CONFIG_NET_SLIP) # define SLIP_UDP_MSS(h) (CONFIG_NET_SLIP_MTU - (h)) # define __MIN_UDP_MSS(h) SLIP_UDP_MSS(h) +#elif defined(CONFIG_NET_LOOPBACK) +# define LO_UDP_MSS(h) (NET_LO_MTU - (h)) +# define __MIN_UDP_MSS(h) LO_UDP_MSS(h) #endif #ifdef CONFIG_NET_ETHERNET @@ -346,12 +383,16 @@ */ #define TCP_MSS(d,h) (NET_DEV_MTU(d) - NET_LL_HDRLEN(d) - TCP_HDRLEN - (h)) +#define LO_TCP_MSS(h) (NET_LO_MTU - (h)) /* If Ethernet is supported, then it will have the smaller MSS */ -#ifdef CONFIG_NET_SLIP +#if defined(CONFIG_NET_SLIP) # define SLIP_TCP_MSS(h) (CONFIG_NET_SLIP_MTU - (h)) # define __MIN_TCP_MSS(h) SLIP_TCP_MSS(h) +#elif defined(CONFIG_NET_LOOPBACK) +# define LO_TCP_MSS(h) (NET_LO_MTU - (h)) +# define __MIN_TCP_MSS(h) LO_TCP_MSS(h) #endif #ifdef CONFIG_NET_ETHERNET @@ -402,15 +443,17 @@ * See the note above regarding the TCP MSS and CONFIG_NET_MULTILINK. */ +#define NET_LO_TCP_RECVWNDO LO_TCP_MSS(0) + #ifdef CONFIG_NET_SLIP # ifndef CONFIG_NET_SLIP_TCP_RECVWNDO -# define CONFIG_NET_SLIP_TCP_RECVWNDO SLIP_TCP_MSS +# define CONFIG_NET_SLIP_TCP_RECVWNDO SLIP_TCP_MSS(0) # endif #endif #ifdef CONFIG_NET_ETHERNET # ifndef CONFIG_NET_ETH_TCP_RECVWNDO -# define CONFIG_NET_ETH_TCP_RECVWNDO ETH_TCP_MSS +# define CONFIG_NET_ETH_TCP_RECVWNDO ETH_TCP_MSS(0) # endif #endif @@ -426,11 +469,16 @@ # define NET_DEV_RCVWNDO(d) CONFIG_NET_SLIP_TCP_RECVWNDO -#else /* if defined(CONFIG_NET_ETHERNET) */ +#elif defined(CONFIG_NET_ETHERNET) /* Only Ethernet.. use the configured SLIP receive window size */ # define NET_DEV_RCVWNDO(d) CONFIG_NET_ETH_TCP_RECVWNDO +#else /* if defined(CONFIG_NET_LOOPBACK) */ + /* Only loal loopback.. use the fixed loopback receive window size */ + +# define NET_DEV_RCVWNDO(d) NET_LO_TCP_RECVWNDO + #endif /* MULTILINK or SLIP or ETHERNET */ /* How long a connection should stay in the TIME_WAIT state. diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 49a90723bef9358b444d1520007d52f6dadfcf6f..de6e997faf142874cb5fe986ebcb26d3d2fb9dd4 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -2,7 +2,7 @@ * include/nuttx/net/netdev.h * Defines architecture-specific device driver interfaces to the uIP network. * - * Copyright (C) 2007, 2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Derived largely from portions of uIP with has a similar BSD-styple license: @@ -66,17 +66,114 @@ * Pre-processor Definitions ****************************************************************************/ +/* Helper macros for network device statistics */ + +#ifdef CONFIG_NETDEV_STATISTICS +# define NETDEV_RESET_STATISTICS(dev) \ + memset(&(dev)->d_statistics, 0, sizeof(struct netdev_statistics_s)) + +# define _NETDEV_STATISTIC(dev,name) ((dev)->d_statistics.name++) +# define _NETDEV_ERROR(dev,name) \ + do \ + { \ + (dev)->d_statistics.name++; \ + (dev)->d_statistics.errors++; \ + } \ + while (0) + +# define NETDEV_RXPACKETS(dev) _NETDEV_STATISTIC(dev,rx_packets) +# define NETDEV_RXFRAGMENTS(dev) _NETDEV_STATISTIC(dev,rx_fragments) +# define NETDEV_RXERRORS(dev) _NETDEV_ERROR(dev,rx_errors) +# ifdef CONFIG_NET_IPv4 +# define NETDEV_RXIPV4(dev) _NETDEV_STATISTIC(dev,rx_ipv4) +# else +# define NETDEV_RXIPV4(dev) +# endif +# ifdef CONFIG_NET_IPv6 +# define NETDEV_RXIPV6(dev) _NETDEV_STATISTIC(dev,rx_ipv6) +# else +# define NETDEV_RXIPV6(dev) +# endif +# ifdef CONFIG_NET_ARP +# define NETDEV_RXARP(dev) _NETDEV_STATISTIC(dev,rx_arp) +# else +# define NETDEV_RXARP(dev) +# endif +# define NETDEV_RXDROPPED(dev) _NETDEV_STATISTIC(dev,rx_dropped) + +# define NETDEV_TXPACKETS(dev) _NETDEV_STATISTIC(dev,tx_packets) +# define NETDEV_TXDONE(dev) _NETDEV_STATISTIC(dev,tx_done) +# define NETDEV_TXERRORS(dev) _NETDEV_ERROR(dev,tx_errors) +# define NETDEV_TXTIMEOUTS(dev) _NETDEV_ERROR(dev,tx_timeouts) + +# define NETDEV_ERRORS(dev) _NETDEV_STATISTIC(dev,errors) + +#else +# define NETDEV_RESET_STATISTICS(dev) +# define NETDEV_RXPACKETS(dev) +# define NETDEV_RXFRAGMENTS(dev) +# define NETDEV_RXERRORS(dev) +# define NETDEV_RXIPV4(dev) +# define NETDEV_RXIPV6(dev) +# define NETDEV_RXARP(dev) +# define NETDEV_RXDROPPED(dev) + +# define NETDEV_TXPACKETS(dev) +# define NETDEV_TXDONE(dev) +# define NETDEV_TXERRORS(dev) +# define NETDEV_TXTIMEOUTS(dev) + +# define NETDEV_ERRORS(dev) +#endif + /**************************************************************************** * Public Types ****************************************************************************/ -struct devif_callback_s; /* Forward reference */ +#ifdef CONFIG_NETDEV_STATISTICS +/* If CONFIG_NETDEV_STATISTICS is enabled and if the driver supports + * statistics, then this structure holds the counts of network driver + * events. + */ + +struct netdev_statistics_s +{ + /* Rx Status */ + + uint32_t rx_packets; /* Number of packets received */ + uint32_t rx_fragments; /* Number of fragments received */ + uint32_t rx_errors; /* Number of receive errors */ +#ifdef CONFIG_NET_IPv4 + uint32_t rx_ipv4; /* Number of Rx IPv4 packets received */ +#endif +#ifdef CONFIG_NET_IPv6 + uint32_t rx_ipv6; /* Number of Rx IPv6 packets received */ +#endif +#ifdef CONFIG_NET_ARP + uint32_t rx_arp; /* Number of Rx ARP packets received */ +#endif + uint32_t rx_dropped; /* Unsupported Rx packets received */ + + /* Tx Status */ + + uint32_t tx_packets; /* Number of Tx packets queued */ + uint32_t tx_done; /* Number of packets completed */ + uint32_t tx_errors; /* Number of receive errors (incl timeouts) */ + uint32_t tx_timeouts; /* Number of Tx timeout errors */ + + /* Other status */ + + uint32_t errors; /* Total umber of errors */ +}; +#endif /* This structure collects information that is specific to a specific network * interface driver. If the hardware platform supports only a single instance * of this structure. */ +struct devif_callback_s; /* Forward reference */ + struct net_driver_s { /* This link is used to maintain a single-linked list of ethernet drivers. @@ -192,6 +289,15 @@ struct net_driver_s sq_queue_t grplist; #endif +#ifdef CONFIG_NETDEV_STATISTICS + /* If CONFIG_NETDEV_STATISTICS is enabled and if the driver supports + * statistics, then this structure holds the counts of network driver + * events. + */ + + struct netdev_statistics_s d_statistics; +#endif + /* Application callbacks: * * Network device event handlers are retained in a 'list' and are called @@ -239,7 +345,7 @@ struct net_driver_s typedef int (*devif_poll_callback_t)(FAR struct net_driver_s *dev); /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -369,8 +475,7 @@ int ipv6_input(FAR struct net_driver_s *dev); ****************************************************************************/ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback); -int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback, - int hsec); +int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback); /**************************************************************************** * Name: neighbor_out diff --git a/include/nuttx/net/telnet.h b/include/nuttx/net/telnet.h new file mode 100644 index 0000000000000000000000000000000000000000..c7184c6d6bba53259e66180033af2c11fc502ed9 --- /dev/null +++ b/include/nuttx/net/telnet.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * include/nuttx/net/telnet.h + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 Gregory Nutt 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 __INCLUDE_NUTTX_NET_TELNET_H +#define __INCLUDE_NUTTX_NET_TELNET_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_NETDEV_TELNET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The minimum size of a device name. Big enough to hold /dev/telnet65535. */ + +#define TELNET_DEVPATH_MAX 18 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* NETDEV ioctl command: + * + * Command: SIOCTELNET + * Description: Create a Telnet sessions. + * Argument: A pointer to a write-able instance of struct telnet_session_s. + * Dependencies: CONFIG_NETDEV_TELNET + */ + +struct telnet_session_s +{ + int ts_sd; /* Socket descriptor for session. */ + char ts_devpath[TELNET_DEVPATH_MAX]; /* Path to new session driver */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: telnet_initialize + * + * Description: + * Create the Telnet factory at /dev/telnet. + * + * Parameters: + * None + * + * Return: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef __KERNEL__ +int telnet_initialize(void); +#endif + +#endif /* CONFIG_NETDEV_TELNET */ +#endif /* __INCLUDE_NUTTX_NET_TELNET_H */ diff --git a/include/nuttx/net/tun.h b/include/nuttx/net/tun.h index 0ed8f3940eb4a5bcb5140e555623d0a3c76368eb..c61c3c84f42cc4355d1fc409b4369bf09a374097 100644 --- a/include/nuttx/net/tun.h +++ b/include/nuttx/net/tun.h @@ -56,7 +56,10 @@ /* TUNSETIFF ifr flags */ -#define IFF_TUN 0x0001 +#define IFF_TUN 0x01 +#define IFF_TAP 0x02 +#define IFF_MASK 0x7f +#define IFF_NO_PI 0x80 /**************************************************************************** * Public Type Definitions diff --git a/include/nuttx/poff.h b/include/nuttx/poff.h index 05349e53a87f7351e28c1e7a660d55fae7f2a648..cda48805e4d41f19879593c34f65bb6d4d28c8e1 100644 --- a/include/nuttx/poff.h +++ b/include/nuttx/poff.h @@ -1,4 +1,4 @@ -/*************************************************************************** +/**************************************************************************** * include/nuttx/poff.h * Definitions for the P-Code Object File Format (POFF) * @@ -32,21 +32,21 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ***************************************************************************/ + ****************************************************************************/ #ifndef __INCLUDE_NUXX_POFF_H #define __INCLUDE_NUXX_POFF_H -/*************************************************************************** +/**************************************************************************** * Included Files - ***************************************************************************/ + ****************************************************************************/ #include #include -/*************************************************************************** +/**************************************************************************** * Pre-processor Definitions - ***************************************************************************/ + ****************************************************************************/ /* Definitions for the fh_ident field of the poffHdr_t */ @@ -157,9 +157,9 @@ #define RLI_TYPE(x) ((x) & 0xff) /* Reloc type */ #define RLI_MAKE(s,t) (((uint32_t)(s) << 8) | ((t) & 0xff)) -/*************************************************************************** +/**************************************************************************** * Public Types - ***************************************************************************/ + ****************************************************************************/ /* POFF file header */ diff --git a/include/nuttx/power/battery_charger.h b/include/nuttx/power/battery_charger.h new file mode 100644 index 0000000000000000000000000000000000000000..d90db10154b39951ebac7f95f0eb26e64b390913 --- /dev/null +++ b/include/nuttx/power/battery_charger.h @@ -0,0 +1,234 @@ +/**************************************************************************** + * include/nuttx/power/battery_charger.h + * NuttX Battery Charger Interfaces + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_POWER_BATTERY_CHARGER_H +#define __INCLUDE_NUTTX_POWER_BATTERY_CHARGER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BATTERY_CHARGER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* CONFIG_BATTERY_CHARGER - Upper half battery charger driver support + * + * Specific, lower-half drivers will have other configuration requirements + * such as: + * + * CONFIG_I2C - I2C support *may* be needed + * CONFIG_I2C_BQ2425X - The BQ2425x driver must be explicitly selected. + */ + +/* IOCTL Commands ***********************************************************/ +/* The upper-half battery charger driver provides a character driver "wrapper" + * around the lower-half battery charger driver that does all of the real work. + * Since there is no real data transfer to/or from a battery, all of the + * driver interaction is through IOCTL commands. The IOCTL commands + * supported by the upper-half driver simply provide calls into the the + * lower half as summarized below: + * + * BATIOC_STATE - Return the current state of the battery (see + * enum battery_charger_status_e). + * Input value: A pointer to type int. + * BATIOC_HEALTH - Return the current health of the battery (see + * enum battery_charger_health_e). + * Input value: A pointer to type int. + * BATIOC_ONLINE - Return 1 if the battery is online; 0 if offline. + * Input value: A pointer to type bool. + * BATIOC_VOLTAGE - Define the wished charger voltage to charge the battery. + * Input value: An int defining the voltage value. + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* Battery status */ + +enum battery_charger_status_e +{ + BATTERY_UNKNOWN = 0, /* Battery state is not known */ + BATTERY_FAULT, /* Charger reported a fault, get health for more info */ + BATTERY_IDLE, /* Not full, not charging, not discharging */ + BATTERY_FULL, /* Full, not discharging */ + BATTERY_CHARGING, /* Not full, charging */ + BATTERY_DISCHARGING /* Probably not full, discharging */ +}; + +/* Battery Health status */ + +enum battery_charger_health_e +{ + BATTERY_HEALTH_UNKNOWN = 0, /* Battery health state is not known */ + BATTERY_HEALTH_GOOD, /* Battery is in good condiction */ + BATTERY_HEALTH_DEAD, /* Battery is dead, nothing we can do */ + BATTERY_HEALTH_OVERHEAT, /* Battery is over recommended temperature */ + BATTERY_HEALTH_OVERVOLTAGE, /* Battery voltage is over recommended level */ + BATTERY_HEALTH_UNSPEC_FAIL, /* Battery charger reported an unspected failure */ + BATTERY_HEALTH_COLD, /* Battery is under recommended temperature */ + BATTERY_HEALTH_WD_TMR_EXP, /* Battery WatchDog Timer Expired */ + BATTERY_HEALTH_SAFE_TMR_EXP, /* Battery Safety Timer Expired */ + BATTERY_HEALTH_DISCONNECTED /* Battery is not connected */ +}; + + /* This structure defines the lower half battery interface */ + +struct battery_charger_dev_s; +struct battery_charger_operations_s +{ + /* Return the current battery state (see enum battery_charger_status_e) */ + + int (*state)(struct battery_charger_dev_s *dev, int *status); + + /* Return the current battery health (see enum battery_charger_health_e) */ + + int (*health)(struct battery_charger_dev_s *dev, int *health); + + /* Return true if the batter is online */ + + int (*online)(struct battery_charger_dev_s *dev, bool *status); + + /* Set the wished battery voltage for charging */ + + int (*voltage)(struct battery_charger_dev_s *dev, int value); + + /* Set the wished current rate used for charging */ + + int (*current)(struct battery_charger_dev_s *dev, int value); +}; + +/* This structure defines the battery driver state structure */ + +struct battery_charger_dev_s +{ + /* Fields required by the upper-half driver */ + + FAR const struct battery_charger_operations_s *ops; /* Battery operations */ + sem_t batsem; /* Enforce mutually exclusive access */ + + /* Data fields specific to the lower-half driver may follow */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: battery_charger_register + * + * Description: + * Register a lower half battery driver with the common, upper-half + * battery driver. + * + * Input parameters: + * devpath - The location in the pseudo-filesystem to create the driver. + * Recommended standard is "/dev/bat0", "/dev/bat1", etc. + * dev - An instance of the battery state structure . + * + * Returned value: + * Zero on success or a negated errno value on failure. + * + ****************************************************************************/ + +int battery_charger_register(FAR const char *devpath, + FAR struct battery_charger_dev_s *dev); + +/**************************************************************************** + * Name: bq2425x_initialize + * + * Description: + * Initialize the BQ2425X battery driver and return an instance of the + * lower_half interface that may be used with battery_charger_register(); + * + * This driver requires: + * + * CONFIG_BATTERY_CHARGER - Upper half battery fuel gauge driver support + * CONFIG_I2C - I2C support + * CONFIG_I2C_BQ2425X - And the driver must be explictly selected. + * CONFIG_I2C_BQ24250 or CONFIG_I2C_BQ24251 - The driver must know which + * chip is on the board in order to scale the voltage correctly. + * + * Input Parameters: + * i2c - An instance of the I2C interface to use to communicate with + * the BQ2425X + * addr - The I2C address of the BQ2425X (Better be 0x6A). + * frequency - The I2C frequency + * + * Returned Value: + * A pointer to the initializeed battery driver instance. A NULL pointer + * is returned on a failure to initialize the BQ2425X lower half. + * + ****************************************************************************/ + +#if defined(CONFIG_I2C) && defined(CONFIG_I2C_BQ2425X) +struct i2c_master_s; /* Forward reference */ + +FAR struct battery_charger_dev_s *bq2425x_initialize(FAR struct i2c_master_s *i2c, + uint8_t addr, + uint32_t frequency); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_BATTERY_CHARGER */ +#endif /* __INCLUDE_NUTTX_POWER_BATTERY_H */ diff --git a/include/nuttx/power/battery.h b/include/nuttx/power/battery_gauge.h similarity index 79% rename from include/nuttx/power/battery.h rename to include/nuttx/power/battery_gauge.h index 9fa44fe5948f9d76231becc5f6d3272d29300606..8351faee8ce161e7027f7e00cf152aff92ac61e3 100644 --- a/include/nuttx/power/battery.h +++ b/include/nuttx/power/battery_gauge.h @@ -1,6 +1,6 @@ /**************************************************************************** - * include/nuttx/power/battery.h - * NuttX Battery Interfaces + * include/nuttx/power/battery_gauge.h + * NuttX Battery Fuel Gauge Interfaces * * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -34,8 +34,8 @@ * ****************************************************************************/ -#ifndef __INCLUDE_NUTTX_POWER_BATTERY_H -#define __INCLUDE_NUTTX_POWER_BATTERY_H +#ifndef __INCLUDE_NUTTX_POWER_BATTERY_GAUGE_H +#define __INCLUDE_NUTTX_POWER_BATTERY_GAUGE_H /**************************************************************************** * Included Files @@ -48,13 +48,13 @@ #include #include -#ifdef CONFIG_BATTERY +#ifdef CONFIG_BATTERY_GAUGE /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /* Configuration ************************************************************/ -/* CONFIG_BATTERY - Upper half battery driver support +/* CONFIG_BATTERY_GAUGE - Upper half battery fuel gauge driver support * * Specific, lower-half drivers will have other configuration requirements * such as: @@ -64,15 +64,16 @@ */ /* IOCTL Commands ***********************************************************/ -/* The upper-half battery driver provides a character driver "wrapper" - * around the lower-half battery driver that does all of the real work. +/* The upper-half battery fuel gauge driver provides a character driver + * "wrapper" * around the lower-half battery driver that does all of the + * real work. * Since there is no real data transfer to/or from a battery, all of the * driver interaction is through IOCTIL commands. The IOCTL commands * supported by the upper-half driver simply provide calls into the the * lower half as summarized below: * * BATIOC_STATE - Return the current state of the battery (see - * enum battery_status_e). + * enum battery_gauge_status_e). * Input value: A pointer to type int. * BATIOC_ONLINE - Return 1 if the battery is online; 0 if offline. * Input value: A pointer to type bool. @@ -85,17 +86,12 @@ * Input value: A pointer to type b16_t. */ -#define BATIOC_STATE _BATIOC(0x0001) -#define BATIOC_ONLINE _BATIOC(0x0002) -#define BATIOC_VOLTAGE _BATIOC(0x0003) -#define BATIOC_CAPACITY _BATIOC(0x0004) - /**************************************************************************** * Public Types ****************************************************************************/ /* Battery status */ -enum battery_status_e +enum battery_gauge_status_e { BATTERY_UNKNOWN = 0, /* Battery state is not known */ BATTERY_IDLE, /* Not full, not charging, not discharging */ @@ -106,33 +102,33 @@ enum battery_status_e /* This structure defines the lower half battery interface */ -struct battery_dev_s; -struct battery_operations_s +struct battery_gauge_dev_s; +struct battery_gauge_operations_s { - /* Return the current battery state (see enum battery_status_e) */ + /* Return the current battery state (see enum battery_gauge_status_e) */ - int (*state)(struct battery_dev_s *dev, int *status); + int (*state)(struct battery_gauge_dev_s *dev, int *status); /* Return true if the batter is online */ - int (*online)(struct battery_dev_s *dev, bool *status); + int (*online)(struct battery_gauge_dev_s *dev, bool *status); /* Current battery voltage */ - int (*voltage)(struct battery_dev_s *dev, b16_t *value); + int (*voltage)(struct battery_gauge_dev_s *dev, b16_t *value); /* Battery capacity */ - int (*capacity)(struct battery_dev_s *dev, b16_t *value); + int (*capacity)(struct battery_gauge_dev_s *dev, b16_t *value); }; /* This structure defines the battery driver state structure */ -struct battery_dev_s +struct battery_gauge_dev_s { /* Fields required by the upper-half driver */ - FAR const struct battery_operations_s *ops; /* Battery operations */ + FAR const struct battery_gauge_operations_s *ops; /* Battery operations */ sem_t batsem; /* Enforce mutually exclusive access */ /* Data fields specific to the lower-half driver may follow */ @@ -156,7 +152,7 @@ extern "C" * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Name: battery_register + * Name: battery_gauge_register * * Description: * Register a lower half battery driver with the common, upper-half @@ -172,18 +168,19 @@ extern "C" * ****************************************************************************/ -int battery_register(FAR const char *devpath, FAR struct battery_dev_s *dev); +int battery_gauge_register(FAR const char *devpath, + FAR struct battery_gauge_dev_s *dev); /**************************************************************************** * Name: max1704x_initialize * * Description: * Initialize the MAX1704x battery driver and return an instance of the - * lower_half interface that may be used with battery_register(); + * lower_half interface that may be used with battery_gauge_register(); * * This driver requires: * - * CONFIG_BATTERY - Upper half battery driver support + * CONFIG_BATTERY_GAUGE - Upper half battery fuel gauge driver support * CONFIG_I2C - I2C support * CONFIG_I2C_MAX1704X - And the driver must be explictly selected. * CONFIG_I2C_MAX17040 or CONFIG_I2C_MAX17041 - The driver must know which @@ -201,10 +198,11 @@ int battery_register(FAR const char *devpath, FAR struct battery_dev_s *dev); ****************************************************************************/ #if defined(CONFIG_I2C) && defined(CONFIG_I2C_MAX1704X) -struct i2c_dev_s; /* Forward reference */ +struct i2c_master_s; /* Forward reference */ -FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c - uint8_t addr, uint32_t frequency); +FAR struct battery_gauge_dev_s *max1704x_initialize(FAR struct i2c_master_s *i2c + uint8_t addr, + uint32_t frequency); #endif #undef EXTERN @@ -213,5 +211,5 @@ FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c #endif #endif /* __ASSEMBLY__ */ -#endif /* CONFIG_BATTERY */ -#endif /* __INCLUDE_NUTTX_POWER_BATTERY_H */ +#endif /* CONFIG_BATTERY_GAUGE */ +#endif /* __INCLUDE_NUTTX_POWER_BATTERY_GAUGE_H */ diff --git a/include/nuttx/power/battery_ioctl.h b/include/nuttx/power/battery_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..4bbd46e21bc83e2f2d3bb0312fc6a07c4bfd001e --- /dev/null +++ b/include/nuttx/power/battery_ioctl.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * include/nuttx/power/battery_ioctl.h + * NuttX Battery IOCTLs definition + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_POWER_BATTERY_IOCTL_H +#define __INCLUDE_NUTTX_POWER_BATTERY_IOCTL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BATIOC_STATE _BATIOC(0x0001) +#define BATIOC_HEALTH _BATIOC(0x0002) +#define BATIOC_ONLINE _BATIOC(0x0003) +#define BATIOC_VOLTAGE _BATIOC(0x0004) +#define BATIOC_CURRENT _BATIOC(0x0005) +#define BATIOC_CAPACITY _BATIOC(0x0006) + +#endif /* __INCLUDE_NUTTX_POWER_BATTERY_IOCTL_H */ diff --git a/include/nuttx/progmem.h b/include/nuttx/progmem.h index 779755505254efccadc65f3deef5c57c1294f272..a5ed707a6134065eb296520e4d63cf7855ca828f 100644 --- a/include/nuttx/progmem.h +++ b/include/nuttx/progmem.h @@ -99,13 +99,13 @@ size_t up_progmem_pagesize(size_t page); * Address to page conversion * * Input Parameters: - * addr - Address with of without flash offset (absolute or aligned to page0) + * addr - Address with or without flash offset (absolute or aligned to page0) * * Returned Value: * Page or negative value on error. The following errors are reported * (errno is not set!): * - * EFAULT: On invalid address + * -EFAULT: On invalid address * ****************************************************************************/ @@ -134,18 +134,18 @@ size_t up_progmem_getaddress(size_t page); * Erase selected page. * * Input Parameters: - * page - + * page - The page index to be erased. * * Returned Value: * Page size or negative value on error. The following errors are reported * (errno is not set!): * - * EFAULT: On invalid page - * EIO: On unsuccessful erase - * EROFS: On access to write protected area - * EACCES: Insufficient permissions (read/write protected) - * EPERM: If operation is not permitted due to some other constraints - * (i.e. some internal block is not running etc.) + * -EFAULT: On invalid page + * -EIO: On unsuccessful erase + * -EROFS: On access to write protected area + * -EACCES: Insufficient permissions (read/write protected) + * -EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) * ****************************************************************************/ @@ -158,14 +158,14 @@ ssize_t up_progmem_erasepage(size_t page); * Checks whether page is erased * * Input Parameters: - * page - + * page - The page index to be checked. * * Returned Value: - * Returns number of bytes written or negative value on error. If it - * returns zero then complete page is empty (erased). + * Returns number of bytes NOT erased or negative value on error. If it + * returns zero then complete page is erased. * - * The following errors are reported (errno is not set!) - * EFAULT: On invalid page + * The following errors are reported: + * -EFAULT: On invalid page * ****************************************************************************/ @@ -183,29 +183,24 @@ ssize_t up_progmem_ispageerased(size_t page); * Input Parameters: * addr - Address with or without flash offset (absolute or aligned to page0) * buf - Pointer to buffer - * count - Number of bytes to write * + * count - Number of bytes to write * * Returned Value: * Bytes written or negative value on error. The following errors are * reported (errno is not set!) * - * EINVAL: if count is not aligned with the flash boundaries (i.e. - * some MCU's require per half-word or even word access) + * EINVAL: If count is not aligned with the flash boundaries (i.e. + * some MCU's require per half-word or even word access) * EFAULT: On invalid address - * EIO: On unsuccessful write - * EROFS: On access to write protected area + * EIO: On unsuccessful write + * EROFS: On access to write protected area * EACCES: Insufficient permissions (read/write protected) - * EPERM: If operation is not permitted due to some other constraints - * (i.e. some internal block is not running etc.) + * EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) * ****************************************************************************/ -ssize_t up_progmem_write(size_t addr, const void *buf, size_t count); - -/* TODO: Define the following functions and their options: - * - up_progmem_protect() - * - up_progmem_unprotect() - */ +ssize_t up_progmem_write(size_t addr, FAR const void *buf, size_t count); #undef EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index 7528bbda8534dc3f3d8c9b09ebf2cec2928b8129..54d5dc659bddf656d1912d9534e4b96fe79ace63 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -2,7 +2,7 @@ * include/nuttx/pthread.h * Non-standard, NuttX-specific pthread-related declarations. * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,11 +51,34 @@ /* Default pthread attribute initializer */ -#ifdef CONFIG_SCHED_SPORADIC +#if CONFIG_RR_INTERVAL == 0 +# define PTHREAD_DEFAULT_POLICY SCHED_FIFO +#else +# define PTHREAD_DEFAULT_POLICY SCHED_RR +#endif + +/* A lot of hassle to use the old-fashioned struct initializers. But this + * gives us backward compatibility with some very old compilers. + */ + +#if defined(CONFIG_SCHED_SPORADIC) && defined(CONFIG_SMP) +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + 0, /* low_priority */ \ + 0, /* max_repl */ \ + 0, /* affinity */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + {0, 0}, /* repl_period */ \ + {0, 0} /* budget */ \ + } +#elif defined(CONFIG_SCHED_SPORADIC) # define PTHREAD_ATTR_INITIALIZER \ { \ PTHREAD_DEFAULT_PRIORITY, /* priority */ \ - SCHED_RR, /* policy */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ 0, /* low_priority */ \ 0, /* max_repl */ \ @@ -63,11 +86,20 @@ {0, 0}, /* repl_period */ \ {0, 0}, /* budget */ \ } +#elif defined(CONFIG_SMP) +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + 0, /* affinity */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + } #else # define PTHREAD_ATTR_INITIALIZER \ { \ PTHREAD_DEFAULT_PRIORITY, /* priority */ \ - SCHED_RR, /* policy */ \ + PTHREAD_DEFAULT_POLICY, /* policy */ \ PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ PTHREAD_STACK_DEFAULT, /* stacksize */ \ } diff --git a/include/nuttx/pwm.h b/include/nuttx/pwm.h index 8abb51e7134bc282e57a30649c500156da3f1e6e..f77cbee23ae2f1a816306ebba64a78fd8843ee08 100644 --- a/include/nuttx/pwm.h +++ b/include/nuttx/pwm.h @@ -122,17 +122,30 @@ /**************************************************************************** * Public Types ****************************************************************************/ + +#ifdef CONFIG_PWM_MULTICHAN +struct pwm_chan_s +{ + ub16_t duty; + uint8_t channel; +}; +#endif + /* This structure describes the characteristics of the pulsed output */ struct pwm_info_s { - uint32_t frequency; /* Frequency of the pulse train */ - ub16_t duty; /* Duty of the pulse train, "1"-to-"0" duration. - * Maximum: 65535/65536 (0x0000ffff) - * Minimum: 1/65536 (0x00000001) */ -#ifdef CONFIG_PWM_PULSECOUNT - uint32_t count; /* The number of pulse to generate. 0 means to - * generate an indefinite number of pulses */ + uint32_t frequency; /* Frequency of the pulse train */ +#ifdef CONFIG_PWM_MULTICHAN + struct pwm_chan_s channels[CONFIG_PWM_NCHANNELS]; +#else + ub16_t duty; /* Duty of the pulse train, "1"-to-"0" duration. + * Maximum: 65535/65536 (0x0000ffff) + * Minimum: 1/65536 (0x00000001) */ +# ifdef CONFIG_PWM_PULSECOUNT + uint32_t count; /* The number of pulse to generate. 0 means to + * generate an indefinite number of pulses */ +# endif #endif }; diff --git a/include/nuttx/rwbuffer.h b/include/nuttx/rwbuffer.h index 7a97ff65c681641265b0aa07292f3e6d969f5d0f..c658117b68683b5192abf6d0c0b1029a0866c39b 100644 --- a/include/nuttx/rwbuffer.h +++ b/include/nuttx/rwbuffer.h @@ -36,9 +36,9 @@ #ifndef __INCLUDE_NUTTX_RWBUFFER_H #define __INCLUDE_NUTTX_RWBUFFER_H -/********************************************************************** +/**************************************************************************** * Included Files - **********************************************************************/ + ****************************************************************************/ #include @@ -49,13 +49,13 @@ #if defined(CONFIG_DRVR_WRITEBUFFER) || defined(CONFIG_DRVR_READAHEAD) -/********************************************************************** +/**************************************************************************** * Pre-processor Definitions - **********************************************************************/ + ****************************************************************************/ -/********************************************************************** +/**************************************************************************** * Public Types - **********************************************************************/ + ****************************************************************************/ /* Data transfer callouts. These must be provided by the block driver * logic in order to flush the write buffer when appropriate or to @@ -154,9 +154,9 @@ struct rwbuffer_s #endif }; -/********************************************************************** - * Global Variables - **********************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) @@ -167,9 +167,9 @@ extern "C" #define EXTERN extern #endif -/********************************************************************** - * Global Function Prototypes - **********************************************************************/ +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ /* Buffer initialization */ diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 4eaacbd229fded73695702845e19727a8f3b36f7..b4f3d055fa4bf4e683a1d2015a29bb509df5f079 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -1,7 +1,7 @@ /******************************************************************************** * include/nuttx/sched.h * - * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -125,8 +126,8 @@ /* Task Management Definitions **************************************************/ /* Special task IDS. Any negative PID is invalid. */ -#define NULL_TASK_PROCESS_ID (pid_t)0 -#define INVALID_PROCESS_ID (pid_t)-1 +#define NULL_TASK_PROCESS_ID (pid_t)0 +#define INVALID_PROCESS_ID (pid_t)-1 /* This is the maximum number of times that a lock can be set */ @@ -136,9 +137,9 @@ #define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */ #define TCB_FLAG_TTYPE_MASK (3 << TCB_FLAG_TTYPE_SHIFT) -# define TCB_FLAG_TTYPE_TASK (0 << TCB_FLAG_TTYPE_SHIFT) /* Normal user task */ -# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */ -# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */ +# define TCB_FLAG_TTYPE_TASK (0 << TCB_FLAG_TTYPE_SHIFT) /* Normal user task */ +# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */ +# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */ #define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */ #define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */ #define TCB_FLAG_POLICY_SHIFT (4) /* Bit 4-5: Scheduling policy */ @@ -147,13 +148,17 @@ # define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */ # define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */ # define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */ -#define TCB_FLAG_EXIT_PROCESSING (1 << 6) /* Bit 6: Exitting */ +#define TCB_FLAG_CPU_LOCKED (1 << 6) /* Bit 6: Locked to this CPU */ +#define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */ + /* Bits 8-15: Available */ /* Values for struct task_group tg_flags */ #define GROUP_FLAG_NOCLDWAIT (1 << 0) /* Bit 0: Do not retain child exit status */ #define GROUP_FLAG_ADDRENV (1 << 1) /* Bit 1: Group has an address environment */ #define GROUP_FLAG_PRIVILEGED (1 << 2) /* Bit 2: Group is privileged */ +#define GROUP_FLAG_DELETED (1 << 3) /* Bit 3: Group has been deleted but not yet freed */ + /* Bits 4-7: Available */ /* Values for struct child_status_s ch_flags */ @@ -163,12 +168,14 @@ # define CHILD_FLAG_TTYPE_PTHREAD (1 << CHILD_FLAG_TTYPE_SHIFT) /* User pthread */ # define CHILD_FLAG_TTYPE_KERNEL (2 << CHILD_FLAG_TTYPE_SHIFT) /* Kernel thread */ #define CHILD_FLAG_EXITED (1 << 0) /* Bit 2: The child thread has exit'ed */ + /* Bits 3-7: Available */ /* Sporadic scheduler flags */ -#define SPORADIC_FLAG_ALLOCED (1 << 0) /* Bit 0: Timer is allocated */ -#define SPORADIC_FLAG_MAIN (1 << 1) /* Bit 1: The main timer */ -#define SPORADIC_FLAG_REPLENISH (1 << 2) /* Bit 2: Replenishment cycle */ +#define SPORADIC_FLAG_ALLOCED (1 << 0) /* Bit 0: Timer is allocated */ +#define SPORADIC_FLAG_MAIN (1 << 1) /* Bit 1: The main timer */ +#define SPORADIC_FLAG_REPLENISH (1 << 2) /* Bit 2: Replenishment cycle */ + /* Bits 3-7: Available */ /******************************************************************************** * Public Type Definitions @@ -188,6 +195,9 @@ enum tstate_e TSTATE_TASK_INVALID = 0, /* INVALID - The TCB is uninitialized */ TSTATE_TASK_PENDING, /* READY_TO_RUN - Pending preemption unlock */ TSTATE_TASK_READYTORUN, /* READY-TO-RUN - But not running */ +#ifdef CONFIG_SMP + TSTATE_TASK_ASSIGNED, /* READY-TO-RUN - Not running, but assigned to a CPU */ +#endif TSTATE_TASK_RUNNING, /* READY_TO_RUN - And running */ TSTATE_TASK_INACTIVE, /* BLOCKED - Initialized but not yet activated */ @@ -206,12 +216,16 @@ enum tstate_e }; typedef enum tstate_e tstate_t; -/* The following definitions are determined by tstate_t */ +/* The following definitions are determined by tstate_t. Ordering of values + * in the enumeration is important! + */ -#define FIRST_READY_TO_RUN_STATE TSTATE_TASK_READYTORUN -#define LAST_READY_TO_RUN_STATE TSTATE_TASK_RUNNING -#define FIRST_BLOCKED_STATE TSTATE_TASK_INACTIVE -#define LAST_BLOCKED_STATE (NUM_TASK_STATES-1) +#define FIRST_READY_TO_RUN_STATE TSTATE_TASK_READYTORUN +#define LAST_READY_TO_RUN_STATE TSTATE_TASK_RUNNING +#define FIRST_ASSIGNED_STATE TSTATE_TASK_ASSIGNED +#define LAST_ASSIGNED_STATE TSTATE_TASK_RUNNING +#define FIRST_BLOCKED_STATE TSTATE_TASK_INACTIVE +#define LAST_BLOCKED_STATE (NUM_TASK_STATES-1) /* The following is the form of a thread start-up function */ @@ -272,14 +286,14 @@ struct replenishment_s struct sporadic_s { - bool suspended; /* Thread is currently suspended */ - uint8_t hi_priority; /* Sporadic high priority */ - uint8_t low_priority; /* Sporadic low priority */ - uint8_t max_repl; /* Maximum number of replenishments */ - uint8_t nrepls; /* Number of active replenishments */ - uint32_t repl_period; /* Sporadic replenishment period */ - uint32_t budget; /* Sporadic execution budget period */ - uint32_t eventtime; /* Time thread suspended or [re-]started */ + bool suspended; /* Thread is currently suspended */ + uint8_t hi_priority; /* Sporadic high priority */ + uint8_t low_priority; /* Sporadic low priority */ + uint8_t max_repl; /* Maximum number of replenishments */ + uint8_t nrepls; /* Number of active replenishments */ + uint32_t repl_period; /* Sporadic replenishment period */ + uint32_t budget; /* Sporadic execution budget period */ + systime_t eventtime; /* Time thread suspended or [re-]started */ /* This is the last interval timer activated */ @@ -418,6 +432,7 @@ struct task_group_s /* waitpid support ************************************************************/ /* Simple mechanism used only when there is no support for SIGCHLD */ + uint8_t tg_nwaiters; /* Number of waiters */ sem_t tg_exitsem; /* Support for waitpid */ int *tg_statloc; /* Location to return exit status */ #endif @@ -434,7 +449,8 @@ struct task_group_s #ifndef CONFIG_DISABLE_SIGNALS /* POSIX Signal Control Fields ************************************************/ - sq_queue_t sigpendingq; /* List of pending signals */ + sq_queue_t tg_sigactionq; /* List of actions for signals */ + sq_queue_t tg_sigpendingq; /* List of pending signals */ #endif #ifndef CONFIG_DISABLE_ENVIRON @@ -544,8 +560,15 @@ struct tcb_s #endif uint8_t task_state; /* Current state of the thread */ +#ifdef CONFIG_SMP + uint8_t cpu; /* CPU index if running or assigned */ + cpu_set_t affinity; /* Bit set of permitted CPUs */ +#endif uint16_t flags; /* Misc. general status flags */ int16_t lockcount; /* 0=preemptable (not-locked) */ +#ifdef CONFIG_SMP + int16_t irqcount; /* 0=interrupts enabled */ +#endif #if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) int32_t timeslice; /* RR timeslice OR Sporadic budget */ @@ -582,7 +605,6 @@ struct tcb_s #ifndef CONFIG_DISABLE_SIGNALS sigset_t sigprocmask; /* Signals that are blocked */ sigset_t sigwaitmask; /* Waiting for pending signals */ - sq_queue_t sigactionq; /* List of actions for signals */ sq_queue_t sigpendactionq; /* List of pending signal actions */ sq_queue_t sigpostedq; /* List of posted signals */ siginfo_t sigunbinfo; /* Signal info when task unblocked */ diff --git a/include/nuttx/sched_note.h b/include/nuttx/sched_note.h new file mode 100644 index 0000000000000000000000000000000000000000..39096228b5890a11354505e9e5e644d2435ba84f --- /dev/null +++ b/include/nuttx/sched_note.h @@ -0,0 +1,257 @@ +/**************************************************************************** + * include/nuttx/sched_note.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_SCHED_NOTE_H +#define __INCLUDE_NUTTX_SCHED_NOTE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#ifdef CONFIG_SCHED_INSTRUMENTATION + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_BUFFER + +/* This type identifies a note structure */ + +enum note_type_e +{ + NOTE_START = 0, + NOTE_STOP, + NOTE_SWITCH +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION + , + NOTE_PREEMPT_LOCK, + NOTE_PREEMPT_UNLOCK +#endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION + , + NOTE_CSECTION_ENTER, + NOTE_CSECTION_LEAVE +#endif +}; + +/* This structure provides the common header of each note */ + +struct note_common_s +{ + uint8_t nc_length; /* Length of the note */ + uint8_t nc_type; /* See enum note_type_e */ + uint8_t nc_systime[4]; /* Time when note buffered */ +}; + +/* This is the specific form of the NOTE_START note */ + +struct note_start_s +{ + uint8_t nst_length; /* Length of the note */ + uint8_t nst_type; /* Must be NOTE_START */ + uint8_t nst_systime[4]; /* Time when note buffered */ + uint8_t nst_pid[2]; /* ID of the new thread/task */ +#if CONFIG_TASK_NAME_SIZE > 0 + char nst_name[1]; /* Start of the name of the thread/task */ +#endif +}; + +/* This is the specific form of the NOTE_STOP note */ + +struct note_stop_s +{ + uint8_t nsp_length; /* Length of the note */ + uint8_t nsp_type; /* Must be NOTE_STOP */ + uint8_t nsp_systime[4]; /* Time when note buffered */ + uint8_t nsp_pid[2]; /* ID of the thread/task that stopped */ +}; + +/* This is the specific form of the NOTE_SWITCH note */ + +struct note_switch_s +{ + uint8_t nsw_length; /* Length of the note */ + uint8_t nsw_type; /* Must be NOTE_SWITCH */ + uint8_t nsw_systime[4]; /* Time when note buffered */ + uint8_t nsw_pidout[2]; /* ID of the thread/task that was blocked */ + uint8_t nsw_pidin[2]; /* ID of the thread/task that was started */ +}; + +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION +/* This is the specific form of the NOTE_PREEMPT_LOCK/UNLOCK note */ + +struct note_preempt_s +{ + uint8_t npr_length; /* Length of the note */ + uint8_t npr_type; /* Must be NOTE_PREEMPT_LOCK or _UNLOCK */ + uint8_t npr_systime[4]; /* Time when note buffered */ + uint8_t npr_pid[2]; /* ID of the thread/task that change pre-emption */ + uint8_t npr_count[2]; /* Count of nested locks */ +}; +#endif /* CONFIG_SCHED_INSTRUMENTATION_PREEMPTION */ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION +/* This is the specific form of the NOTE_CSECTION_ENTER/LEAVE note */ + +struct note_csection_s +{ + uint8_t ncs_length; /* Length of the note */ + uint8_t ncs_type; /* Must be NOTE_CSECTION_ENTER or _LEAVE */ + uint8_t ncs_systime[4]; /* Time when note buffered */ + uint8_t ncs_pid[2]; /* ID of the thread/task that changed critical section */ +#ifdef CONFIG_SMP + uint8_t ncs_count[2]; /* Count of nested csections */ +#endif +}; +#endif /* CONFIG_SCHED_INSTRUMENTATION_CSECTION */ +#endif /* CONFIG_SCHED_INSTRUMENTATION_BUFFER */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/******************************************************************************** + * Name: sched_note_* + * + * Description: + * If instrumentation of the scheduler is enabled, then some outboard logic + * must provide the following interfaces. These interfaces are not availalble + * to application code. + * + * NOTE: if CONFIG_SCHED_INSTRUMENTATION_BUFFER, then these interfaces are + * *not* available to the platform-specific logic. Rather, they provided by + * the note buffering logic. See sched_note_get() below. + * + * Input Parameters: + * tcb - The TCB of the thread. + * + * Returned Value: + * None + * + ********************************************************************************/ + +void sched_note_start(FAR struct tcb_s *tcb); +void sched_note_stop(FAR struct tcb_s *tcb); +void sched_note_switch(FAR struct tcb_s *fromtcb, FAR struct tcb_s *totcb); + +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION +void sched_note_premption(FAR struct tcb_s *tcb, bool locked); +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION +void sched_note_csection(FAR struct tcb_s *tcb, bool enter); +#endif + +/**************************************************************************** + * Name: sched_note_get + * + * Description: + * Remove the next note from the tail of the circular buffer. The note + * is also removed from the circular buffer to make room for futher notes. + * + * Input Parameters: + * buffer - Location to return the next note + * buflen - The length of the user provided buffer. + * + * Returned Value: + * On success, the positive, non-zero length of the return note is + * provided. Zero is returned only if ther circular buffer is empty. A + * negated errno value is returned in the event of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_BUFFER +ssize_t sched_note_get(FAR uint8_t *buffer, size_t buflen); +#endif + +/**************************************************************************** + * Name: sched_note_size + * + * Description: + * Return the size of the next note at the tail of the circular buffer. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero is returned if the circular buffer is empty. Otherwise, the size + * of the next note is returned. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_BUFFER +ssize_t sched_note_size(void); +#endif + +/**************************************************************************** + * Name: note_register + * + * Description: + * Register a serial driver at /dev/note that can be used by an + * application to read data from the circular not buffer. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero is returned if the circular buffer is empty. Otherwise, a negated + * errno value is returned. + * + ****************************************************************************/ + +#if defined(CONFIG_SCHED_INSTRUMENTATION_BUFFER) && \ + defined(CONFIG_DRIVER_NOTE) +int note_register(void); +#endif + +#else /* CONFIG_SCHED_INSTRUMENTATION */ + +# define sched_note_start(t) +# define sched_note_stop(t) +# define sched_note_switch(t1, t2) +# define sched_note_premption(t,l) +# define sched_note_csection(t,e) + +#endif /* CONFIG_SCHED_INSTRUMENTATION */ +#endif /* __INCLUDE_NUTTX_SCHED_NOTE_H */ diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 5460ce15c5a05027d7372f747eb090758828e9b6..4a5bb32d32b6009ffcfef662ad1ca96b029875e8 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/semaphore.h * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include +#include #include /**************************************************************************** @@ -60,7 +61,9 @@ struct inode; struct nsem_inode_s { - /* Inode payload unique to named semaphores */ + /* Inode payload unique to named semaphores. ns_inode must appear first + * in this structure in order to support casting between type sem_t and + * types of struct nsem_inode_s. */ FAR struct inode *ns_inode; /* Containing inode */ sem_t ns_sem; /* The semaphore */ @@ -108,7 +111,27 @@ extern "C" * ****************************************************************************/ -int sem_tickwait(FAR sem_t *sem, uint32_t start, uint32_t delay); +int sem_tickwait(FAR sem_t *sem, systime_t start, uint32_t delay); + +/**************************************************************************** + * Name: sem_reset + * + * Description: + * Reset a semaphore count to a specific value. This is similar to part + * of the operation of sem_init(). But sem_reset() may need to wake up + * tasks waiting on a count. This kind of operation is sometimes required + * within the OS (only) for certain error handling conditions. + * + * Parameters: + * sem - Semaphore descriptor to be reset + * count - The requested semaphore count + * + * Return Value: + * 0 (OK) or a negated errno value if unsuccessful + * + ****************************************************************************/ + +int sem_reset(FAR sem_t *sem, int16_t count); #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/sensors/adxl345.h b/include/nuttx/sensors/adxl345.h index 4e806d5ea029ca8ef4d68eca7b3ffebeacad49a8..da563c8ac6022c5e8fe0c91eb1f09547fb3db4b8 100644 --- a/include/nuttx/sensors/adxl345.h +++ b/include/nuttx/sensors/adxl345.h @@ -41,10 +41,6 @@ ********************************************************************************************/ #include - -#include -#include - #include #if defined(CONFIG_SENSORS_ADXL345) @@ -101,9 +97,6 @@ # ifndef CONFIG_I2C # error "CONFIG_I2C is required in the I2C support" # endif -# ifndef CONFIG_I2C_TRANSFER -# error "CONFIG_I2C_TRANSFER is required in the I2C configuration" -# endif #endif /* I2C **************************************************************************************/ @@ -329,6 +322,9 @@ struct adxl345_config_s typedef FAR void *ADXL345_HANDLE; +struct i2c_master_s; +struct spi_dev_s; + /******************************************************************************************** * Public Function Prototypes ********************************************************************************************/ @@ -362,7 +358,7 @@ extern "C" ADXL345_HANDLE adxl345_instantiate(FAR struct spi_dev_s *dev, FAR struct adxl345_config_s *config); #else -ADXL345_HANDLE adxl345_instantiate(FAR struct i2c_dev_s *dev, +ADXL345_HANDLE adxl345_instantiate(FAR struct i2c_master_s *dev, FAR struct adxl345_config_s *config); #endif diff --git a/include/nuttx/sensors/as5048b.h b/include/nuttx/sensors/as5048b.h index 6e8c0c3aaed6af677519f56d6615e5c05714a1df..9a274d90ae571f6ffc65953e4fae84131c6ffeef 100644 --- a/include/nuttx/sensors/as5048b.h +++ b/include/nuttx/sensors/as5048b.h @@ -1,8 +1,8 @@ /**************************************************************************** * include/nuttx/sensors/as5048b.h * - * Copyright (C) 2015 Alexandru Duru. All rights reserved. - * Author: Alexandru Duru + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,8 +41,9 @@ ****************************************************************************/ #include -#include -#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_QENCODER) && defined(CONFIG_AS5048B) /**************************************************************************** * Pre-processor Definitions @@ -58,11 +59,10 @@ /* IOCTL Commands ***********************************************************/ -#define SNIOC_READZERO _SNIOC(0x0001) /* Arg: uint16_t* pointer */ -#define SNIOC_WRITEZERO _SNIOC(0x0002) /* Arg: uint16_t value */ -#define SNIOC_READAGC _SNIOC(0x0004) /* Arg: uint8_t* pointer */ -#define SNIOC_READDIAG _SNIOC(0x0005) /* Arg: uint8_t* pointer */ -#define SNIOC_READMAG _SNIOC(0x0006) /* Arg: uint16_t* pointer */ +#define QEIOC_ZEROPOSITION _QEIOC(QEIOC_USER+0) /* Arg: int32_t* pointer */ +#define QEIOC_AUTOGAINCTL _QEIOC(QEIOC_USER+1) /* Arg: uint8_t* pointer */ +#define QEIOC_DIAGNOSTICS _QEIOC(QEIOC_USER+2) /* Arg: uint8_t* pointer */ +#define QEIOC_MAGNITUDE _QEIOC(QEIOC_USER+3) /* Arg: int32_t* pointer */ /* Resolution ***************************************************************/ @@ -95,6 +95,12 @@ #define AS5048B_DIAG_COMPLOW (1 << 2) /* High Magnetic Field */ #define AS5048B_DIAG_COMPHIGH (1 << 3) /* Low Magnetic Field */ +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -108,29 +114,28 @@ extern "C" #endif /**************************************************************************** - * Name: as5048b_register + * Name: as5048b_initialize * * Description: - * Register the AS5048B character device as 'devpath'. + * Initialize the AS5048B device. * * Input Parameters: - * devpath - The full path to the driver to register, - * for example "/dev/angle0". - * i2c - An instance of the I2C interface to use to communicate - * with the AS5048B. - * addr - The I2C address of the AS5048B. + * i2c - An I2C driver instance. + * addr - The I2C address of the AS5048B. * * Returned Value: - * Zero (OK) on success; a negated errno value on failure. + * A new lower half quadrature encoder interface for the AS5048B on success; + * NULL on failure. * ****************************************************************************/ -int as5048b_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, - uint8_t addr); +FAR struct qe_lowerhalf_s *as5048b_initialize(FAR struct i2c_master_s *i2c, + uint8_t addr); #undef EXTERN #ifdef __cplusplus } #endif +#endif /* CONFIG_I2C && CONFIG_QENCODER && CONFIG_AS5048B */ #endif /* __INCLUDE_NUTTX_SENSORS_AS5048B */ diff --git a/include/nuttx/sensors/bmp180.h b/include/nuttx/sensors/bmp180.h index 668ce62815f86fe0a7a6fbb102da99d09626b405..0c12e242265a49dd5e69e5ca4f99726610916467 100644 --- a/include/nuttx/sensors/bmp180.h +++ b/include/nuttx/sensors/bmp180.h @@ -36,7 +36,9 @@ #ifndef __DRIVERS_SENSORS_BMP180_H #define __DRIVERS_SENSORS_BMP180_H -#if defined(CONFIG_BMP180) +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_BMP180) /******************************************************************************************** * Pre-processor Definitions @@ -53,6 +55,12 @@ * Enable very low register-level debug output. Requires CONFIG_DEBUG. */ +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + /******************************************************************************************** * Public Function Prototypes ********************************************************************************************/ @@ -81,12 +89,12 @@ extern "C" * ****************************************************************************/ -int bmp180_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c); +int bmp180_register(FAR const char *devpath, FAR struct i2c_master_s *i2c); #undef EXTERN #ifdef __cplusplus } #endif -#endif /* CONFIG_BMP180 */ +#endif /* CONFIG_I2C && CONFIG_BMP180 */ #endif /* __DRIVERS_BMP180_H */ diff --git a/include/nuttx/sensors/lis331dl.h b/include/nuttx/sensors/lis331dl.h index 2025e82952a9fd0fa897b2170c2dd514b9f00bd8..8d69b5d7c35ab391f309468acef2e7e72202b463 100644 --- a/include/nuttx/sensors/lis331dl.h +++ b/include/nuttx/sensors/lis331dl.h @@ -38,9 +38,11 @@ #ifndef __INCLUDE_NUTTX_SENSORS_LIS331DL_H #define __INCLUDE_NUTTX_SENSORS_LIS331DL_H -#include +#include #include +#if defined(CONFIG_I2C) && defined(CONFIG_LIS331DL) + /************************************************************************************ * Pre-Processor Declarations ************************************************************************************/ @@ -69,6 +71,8 @@ struct lis331dl_vector_s int8_t z; }; +struct i2c_master_s; + /************************************************************************************ * Public Function Prototypes ************************************************************************************/ @@ -96,7 +100,7 @@ struct lis331dl_vector_s * ************************************************************************************/ -FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_dev_s * i2c, +FAR struct lis331dl_dev_s *lis331dl_init(FAR struct i2c_master_s * i2c, uint16_t address); /************************************************************************************ @@ -204,4 +208,5 @@ FAR const struct lis331dl_vector_s * #endif #endif /* __ASSEMBLY__ */ +#endif /* CONFIG_I2C && CONFIG_LIS331DL */ #endif /* __INCLUDE_NUTTX_SENSORS_LIS331DL_H */ diff --git a/include/nuttx/sensors/lm75.h b/include/nuttx/sensors/lm75.h index bd01e51b53bf77c8442f9f2c1dc7623c72e0b30c..827620adab91089975dd3686c6b40f6de1d91557 100644 --- a/include/nuttx/sensors/lm75.h +++ b/include/nuttx/sensors/lm75.h @@ -43,6 +43,8 @@ #include #include +#if defined(CONFIG_I2C) && defined(CONFIG_I2C_LM75) + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -52,6 +54,14 @@ */ #define CONFIG_LM75_BASEADDR 0x48 +#define CONFIG_LM75_ADDR0 (CONFIG_LM75_BASEADDR + 0) +#define CONFIG_LM75_ADDR1 (CONFIG_LM75_BASEADDR + 1) +#define CONFIG_LM75_ADDR2 (CONFIG_LM75_BASEADDR + 2) +#define CONFIG_LM75_ADDR3 (CONFIG_LM75_BASEADDR + 3) +#define CONFIG_LM75_ADDR4 (CONFIG_LM75_BASEADDR + 4) +#define CONFIG_LM75_ADDR5 (CONFIG_LM75_BASEADDR + 5) +#define CONFIG_LM75_ADDR6 (CONFIG_LM75_BASEADDR + 6) +#define CONFIG_LM75_ADDR7 (CONFIG_LM75_BASEADDR + 7) /* IOCTL Commands ***********************************************************/ @@ -64,7 +74,7 @@ #define SNIOC_READTHYS _SNIOC(0x0007) /* Arg: b16_t* pointer */ #define SNIOC_WRITETHYS _SNIOC(0x0008) /* Arg: b16_t value */ #define SNIOC_READTOS _SNIOC(0x0009) /* Arg: b16_t* pointer */ -#define SNIOC_WRITRETOS _SNIOC(0x000a) /* Arg: b16_t value */ +#define SNIOC_WRITETOS _SNIOC(0x000a) /* Arg: b16_t value */ /* LM-75 Register Definitions ***********************************************/ /* LM-75 Registers addresses */ @@ -86,12 +96,10 @@ */ /**************************************************************************** - * Public Data + * Public Types ****************************************************************************/ -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ +struct i2c_master_s; /**************************************************************************** * Public Function Prototypes @@ -123,7 +131,7 @@ extern "C" * ****************************************************************************/ -int lm75_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, +int lm75_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, uint8_t addr); #undef EXTERN @@ -131,4 +139,5 @@ int lm75_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, } #endif +#endif /* CONFIG_I2C && CONFIG_I2C_LM75 */ #endif /* __INCLUDE_NUTTX_SENSORS_LM75_H */ diff --git a/include/nuttx/sensors/lm92.h b/include/nuttx/sensors/lm92.h index 7db294dfdf0146fb45b6b30a53362538c317c517..8b49a0da93603603a883dd1aea309110bcabb2d1 100644 --- a/include/nuttx/sensors/lm92.h +++ b/include/nuttx/sensors/lm92.h @@ -2,9 +2,9 @@ * include/nuttx/sensors/lm92.h * * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. - * Copyright (C) 2015 Alexandru Duru. All rights reserved. - * Author: Gregory Nutt - * Alexandru Duru + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Gregory Nutt + * Paul Alexander Patience * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,6 +45,8 @@ #include #include +#if defined(CONFIG_I2C) && defined(CONFIG_LM92) + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -101,12 +103,10 @@ */ /**************************************************************************** - * Public Data + * Public Types ****************************************************************************/ -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ +struct i2c_master_s; /**************************************************************************** * Public Function Prototypes @@ -139,7 +139,7 @@ extern "C" * ****************************************************************************/ -int lm92_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, +int lm92_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, uint8_t addr); #undef EXTERN @@ -147,4 +147,5 @@ int lm92_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, } #endif +#endif /* CONFIG_I2C && CONFIG_LM92 */ #endif /* __INCLUDE_NUTTX_SENSORS_LM92_H */ diff --git a/include/nuttx/sensors/lsm9ds1.h b/include/nuttx/sensors/lsm9ds1.h new file mode 100644 index 0000000000000000000000000000000000000000..cf3ef1b3c7682d335585c926d373793e2857c384 --- /dev/null +++ b/include/nuttx/sensors/lsm9ds1.h @@ -0,0 +1,151 @@ +/**************************************************************************** + * include/nuttx/sensors/lsm9ds1.h + * + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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 __INCLUDE_NUTTX_SENSORS_LSM9DS1 +#define __INCLUDE_NUTTX_SENSORS_LSM9DS1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SN_LSM9DS1) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_START _SNIOC(0x0001) /* Arg: None */ +#define SNIOC_STOP _SNIOC(0x0002) /* Arg: None */ +#define SNIOC_SETSAMPLERATE _SNIOC(0x0003) /* Arg: uint32_t value */ +#define SNIOC_SETFULLSCALE _SNIOC(0x0004) /* Arg: uint32_t value */ + +/* I2C Addresses ************************************************************/ +/* Accelerometer addresses */ + +#define LSM9DS1ACCEL_ADDR0 0x6a +#define LSM9DS1ACCEL_ADDR1 0x6b + +/* Gyroscope addresses */ + +#define LSM9DS1GYRO_ADDR0 LSM9DS1ACCEL_ADDR0 +#define LSM9DS1GYRO_ADDR1 LSM9DS1ACCEL_ADDR1 + +/* Magnetometer addresses */ + +#define LSM9DS1MAG_ADDR0 0x1c +#define LSM9DS1MAG_ADDR1 0x1e + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: lsm9ds1accel_register + * + * Description: + * Register the LSM9DS1 accelerometer character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/accel0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 accelerometer. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1accel_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +/**************************************************************************** + * Name: lsm9ds1gyro_register + * + * Description: + * Register the LSM9DS1 gyroscope character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/gyro0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 gyroscope. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1gyro_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +/**************************************************************************** + * Name: lsm9ds1mag_register + * + * Description: + * Register the LSM9DS1 magnetometer character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/mag0". + * i2c - An I2C driver instance. + * addr - The I2C address of the LSM9DS1 magnetometer. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lsm9ds1mag_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_SN_LSM9DS1 */ +#endif /* __INCLUDE_NUTTX_SENSORS_LSM9DS1 */ diff --git a/include/nuttx/sensors/max31855.h b/include/nuttx/sensors/max31855.h new file mode 100644 index 0000000000000000000000000000000000000000..4a4a91b9c43e1e20de8c39644c274c569969fabf --- /dev/null +++ b/include/nuttx/sensors/max31855.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * include/nuttx/input/max31855.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 __INCLUDE_NUTTX_SENSORS_MAX31855_H +#define __INCLUDE_NUTTX_SENSORS_MAX31855_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_MAX31855) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#define MAX31855_SPI_MAXFREQ 4000000 + +struct spi_dev_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: max31855_register + * + * Description: + * This function will register the max31855 driver as /dev/tempN + * where N is the minor device number + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * spi - An instance of the SPI interface to use to communicate with + * MAX31855 + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int max31855_register(FAR const char *devpath, FAR struct spi_dev_s *spi); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_MAX31855 */ +#endif /* __INCLUDE_NUTTX_SENSORS_MAX31855_H */ diff --git a/include/nuttx/sensors/max6675.h b/include/nuttx/sensors/max6675.h new file mode 100644 index 0000000000000000000000000000000000000000..0864c7434b01d6b3140cbc2021f2a8251e9239b2 --- /dev/null +++ b/include/nuttx/sensors/max6675.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * include/nuttx/input/max6675.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 __INCLUDE_NUTTX_SENSORS_MAX6675_H +#define __INCLUDE_NUTTX_SENSORS_MAX6675_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_MAX6675) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#define MAX6675_SPI_MAXFREQ 4000000 + +struct spi_dev_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: max6675_register + * + * Description: + * This function will register the max6675 driver as /dev/tempN + * where N is the minor device number + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * spi - An instance of the SPI interface to use to communicate with + * MAX6675 + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int max6675_register(FAR const char *devpath, FAR struct spi_dev_s *spi); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_MAX6675 */ +#endif /* __INCLUDE_NUTTX_SENSORS_MAX6675_H */ diff --git a/include/nuttx/sensors/mb7040.h b/include/nuttx/sensors/mb7040.h new file mode 100644 index 0000000000000000000000000000000000000000..0280ecadb6fc01a0458d89f103fb8d336f642700 --- /dev/null +++ b/include/nuttx/sensors/mb7040.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * include/nuttx/sensors/mb7040.h + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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 __INCLUDE_NUTTX_SENSORS_MB7040 +#define __INCLUDE_NUTTX_SENSORS_MB7040 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MB7040) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************ + * Prerequisites: + * + * CONFIG_I2C + * Enables support for I2C drivers + * CONFIG_MB7040 + * Enables support for the MB7040 driver + */ + +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_MEASURE _SNIOC(0x0001) /* Arg: None */ +#define SNIOC_RANGE _SNIOC(0x0002) /* Arg: int32_t* pointer */ +#define SNIOC_CHANGEADDR _SNIOC(0x0003) /* Arg: uint8_t value */ + +/* I2C Addresses ************************************************************/ + +#define MB7040_DEFAULTADDR 0x70 /* Default I2C Address */ + +/* Register Definitions *****************************************************/ +/* Register Addresses */ + +#define MB7040_RANGE_REG 0x51 +#define MB7040_ADDRUNLOCK1_REG 0xaa +#define MB7040_ADDRUNLOCK2_REG 0xa5 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mb7040_register + * + * Description: + * Register the MB7040 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/sonar0". + * i2c - An I2C driver instance. + * addr - The I2C address of the MB7040. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mb7040_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_MB7040 */ +#endif /* __INCLUDE_NUTTX_SENSORS_MB7040 */ diff --git a/include/nuttx/sensors/mcp9844.h b/include/nuttx/sensors/mcp9844.h new file mode 100644 index 0000000000000000000000000000000000000000..97a8f2bda32e68d24cc83f19e7c0854cb6c881eb --- /dev/null +++ b/include/nuttx/sensors/mcp9844.h @@ -0,0 +1,128 @@ +/**************************************************************************** + * include/nuttx/sensors/mcp9844.h + * + * Copyright (C) 2016, DS-Automotion GmbH. All rights reserved. + * Author: Alexander Entinger + * + * 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 __NUTTX_INCLUDE_NUTTX_SENSORS_MCP9844_H +#define __NUTTX_INCLUDE_NUTTX_SENSORS_MCP9844_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MCP9844) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_READTEMP _SNIOC(0x0001) /* Arg: mcp9844_temp_arg_s* pointer */ +#define SNIOC_SETRESOLUTION _SNIOC(0x0002) /* Arg: uint16_t value */ + +/* MCP9844 Register Definitions *********************************************/ + +/* MCP9844 Registers addresses */ + +#define MCP9844_CAPA_REG (0x00) /* Sensor Capability Register */ +#define MCP9844_CONF_REG (0x01) /* Sensor Configuration Register */ +#define MCP9844_TEMP_REG (0x05) /* Sensor Temperature Register */ +#define MCP9844_RESO_REG (0x09) /* Register to control the resolution of the temperature sensor */ + +/* Resolution Register Bit definitions */ + +#define MCP9844_RESO_REG_BIT_0 (1<<0) +#define MCP9844_RESO_REG_BIT_1 (1<<1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct mcp9844_temp_arg_s +{ + int8_t temp_pre_comma; + uint8_t temp_post_comma; +}; + +enum mcp9844_resolution_e +{ + RES_0_5 = 0, + RES_0_25 = MCP9844_RESO_REG_BIT_0, + RES_0_125 = MCP9844_RESO_REG_BIT_1, + RES_0_0625 = MCP9844_RESO_REG_BIT_1 | MCP9844_RESO_REG_BIT_0 +}; + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mcp9844_register + * + * Description: + * Register the MCP9844 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0" + * i2c - An instance of the I2C interface to use to communicate with MCP9844 + * addr - The I2C address of the MCP9844. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mcp9844_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_MCP9844 */ +#endif /* __NUTTX_INCLUDE_NUTTX_SENSORS_MCP9844_H */ diff --git a/include/nuttx/sensors/mpl115a.h b/include/nuttx/sensors/mpl115a.h index 9aa60495732e99577b7fd6d6fa5a4d971f72e4b5..c958c8025df9487c2208769fe68edb159f01010a 100644 --- a/include/nuttx/sensors/mpl115a.h +++ b/include/nuttx/sensors/mpl115a.h @@ -36,7 +36,9 @@ #ifndef __DRIVERS_SENSORS_MPL115A_H #define __DRIVERS_SENSORS_MPL115A_H -#if defined(CONFIG_MPL115A) +#include + +#if defined(CONFIG_SPI) && defined(CONFIG_MPL115A) /******************************************************************************************** * Pre-processor Definitions @@ -83,6 +85,12 @@ /* 0x0c - 0x11 are reserved */ #define MPL115A_CONVERT 0x12 /* Start Pressure and Temperature Conversion */ +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +struct spi_dev_s; + /******************************************************************************************** * Public Function Prototypes ********************************************************************************************/ @@ -118,5 +126,5 @@ int mpl115a_register(FAR const char *devpath, FAR struct spi_dev_s *spi); } #endif -#endif /* CONFIG_SENSORS_MPL115A */ +#endif /* CONFIG_SPI && CONFIG_MPL115A */ #endif /* __DRIVERS_SENSORS_MPL115A_H */ diff --git a/include/nuttx/sensors/ms58xx.h b/include/nuttx/sensors/ms58xx.h new file mode 100644 index 0000000000000000000000000000000000000000..fb20a3b21246766b530dcac18deebd328d10b1f8 --- /dev/null +++ b/include/nuttx/sensors/ms58xx.h @@ -0,0 +1,131 @@ +/**************************************************************************** + * include/nuttx/sensors/ms58xx.h + * + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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 __INCLUDE_NUTTX_SENSORS_MS58XX +#define __INCLUDE_NUTTX_SENSORS_MS58XX + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_MS58XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************ + * Prerequisites: + * + * CONFIG_I2C + * Enables support for I2C drivers + * CONFIG_MS58XX + * Enables support for the MS58XX driver + * CONFIG_MS58XX_VDD + */ + +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_MEASURE _SNIOC(0x0001) /* Arg: None */ +#define SNIOC_TEMPERATURE _SNIOC(0x0002) /* Arg: int32_t* pointer */ +#define SNIOC_PRESSURE _SNIOC(0x0003) /* Arg: int32_t* pointer */ +#define SNIOC_RESET _SNIOC(0x0004) /* Arg: None */ +#define SNIOC_OVERSAMPLING _SNIOC(0x0005) /* Arg: uint16_t value */ + +/* I2C Address **************************************************************/ + +#define MS58XX_ADDR0 0x76 +#define MS58XX_ADDR1 0x77 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum ms58xx_model_e +{ + MS58XX_MODEL_MS5803_02 = 0, + MS58XX_MODEL_MS5803_05 = 1, + MS58XX_MODEL_MS5803_07 = 2, + MS58XX_MODEL_MS5803_14 = 3, + MS58XX_MODEL_MS5803_30 = 4, + MS58XX_MODEL_MS5805_02 = 5, + MS58XX_MODEL_MS5806_02 = 6, + MS58XX_MODEL_MS5837_30 = 7 +}; + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: ms58xx_register + * + * Description: + * Register the MS58XX character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/press0". + * i2c - An I2C driver instance. + * addr - The I2C address of the MS58XX. + * osr - The oversampling ratio. + * model - The MS58XX model. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ms58xx_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr, uint16_t osr, enum ms58xx_model_e model); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_MS58XX */ +#endif /* __INCLUDE_NUTTX_SENSORS_MS58XX */ diff --git a/include/nuttx/sensors/qencoder.h b/include/nuttx/sensors/qencoder.h index 62ab322278a9bd5ac3c3b310b66e0759f850c64b..f765ee1956f1a66d2a19ce34c9f1ffeecbcb8ea6 100644 --- a/include/nuttx/sensors/qencoder.h +++ b/include/nuttx/sensors/qencoder.h @@ -102,7 +102,7 @@ struct qe_ops_s /* Return the current position measurement. */ - CODE int (*position)(FAR struct qe_lowerhalf_s *lower, int32_t *pos); + CODE int (*position)(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos); /* Reset the position measurement to zero. */ diff --git a/include/nuttx/sensors/zerocross.h b/include/nuttx/sensors/zerocross.h new file mode 100644 index 0000000000000000000000000000000000000000..9b93c7c215274fc44bdd6b1ea8999b0815aa302d --- /dev/null +++ b/include/nuttx/sensors/zerocross.h @@ -0,0 +1,151 @@ +/**************************************************************************** + * include/nuttx/zerocross.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __NUTTX_SENSORS_ZEROCROSS_H +#define __NUTTX_SENSORS_ZEROCROSS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_ZEROCROSS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************ + * CONFIG_ZEROCROSS - Enables support for the zero cross AC detection upper + * half + */ + +/* Command: ZCIOC_REGISTER + * Description: Register to receive a signal whenever there is zero cross + * interrupt event. + * Argument: A read-only pointer to an instance of struct zc_notify_s + * Return: Zero (OK) on success. Minus one will be returned on failure + * with the errno value set appropriately. + */ + +#define ZCIOC_REGISTER _ZCIOC(0x0001) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This is the vtable that is used to by the upper half of the zero cross + * to call back into the lower half of the zero cross driver. + */ + +struct zc_lowerhalf_s; + +/* This is the type of the discrete zero cross interrupt handler used with + * the struct zc_lowerhalf_s enable() method. + */ + +typedef CODE void (*zc_interrupt_t) + (FAR const struct zc_lowerhalf_s *lower, FAR void *arg); + +/* This is the interface between the lower half zero cross detection driver + * and the upper half zero cross detection driver. A (device-specific) + * instance of this structure is passed to the upper-half driver when the + * zero cross driver is registered. + * + * Normally that lower half logic will have its own, custom state structure + * that is simply cast to struct zc_lowerhalf_s. In order to perform such + * casts, the initial fields of the custom state structure match the initial + * fields of the following generic lower half state structure. + */ + +/* A reference to this structure is provided with the ZCIOC_REGISTER IOCTL + * command and describes the conditions under which the client would like + * to receive notification. + */ + +struct zc_notify_s +{ + uint8_t zc_signo; /* Signal number to use in the notification */ +}; + +struct zc_lowerhalf_s +{ + /* Enable interrupt on the defined pin used to zero cross detection */ + + CODE void (*zc_enable)(FAR const struct zc_lowerhalf_s *lower, + zc_interrupt_t handler, FAR void *arg); +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: zc_register + * + * Description: + * Register the Zero Cross lower half device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/zc0" + * lower - An instance of the lower half interface + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int zc_register(FAR const char *devpath, FAR struct zc_lowerhalf_s *lower); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_ZEROCROSS */ +#endif /* __NUTTX_SENSORS_ZEROCROSS_H */ diff --git a/include/nuttx/sercomm/msgb.h b/include/nuttx/sercomm/msgb.h index 68005bbb46cbfd453d5d5d97882443fcfbbc30a7..39067c3ba39ccc0a4ff6bc05de8ea9b3f28289d7 100644 --- a/include/nuttx/sercomm/msgb.h +++ b/include/nuttx/sercomm/msgb.h @@ -1,4 +1,4 @@ -/************************************************************************** +/**************************************************************************** * (C) 2008-2010 by Harald Welte * * This source code is derivated from Osmocom-BB project and was @@ -31,21 +31,21 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - **************************************************************************/ + ****************************************************************************/ #ifndef __INCLUDE_NUTTX_SERCOM_MSGB_H #define __INCLUDE_NUTTX_SERCOM_MSGB_H -/************************************************************************** +/**************************************************************************** * Included Files - **************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************** +/**************************************************************************** * Public Types - **************************************************************************/ + ****************************************************************************/ struct msgb { @@ -72,9 +72,9 @@ struct msgb unsigned char _data[0]; }; -/************************************************************************** +/**************************************************************************** * Public Function Prototypes - **************************************************************************/ + ****************************************************************************/ struct msgb *msgb_alloc(uint16_t size, const char *name); void msgb_free(struct msgb *m); @@ -82,9 +82,9 @@ void msgb_enqueue(struct llist_head *queue, struct msgb *msg); struct msgb *msgb_dequeue(struct llist_head *queue); void msgb_reset(struct msgb *m); -/************************************************************************** +/**************************************************************************** * Inline Functions - **************************************************************************/ + ****************************************************************************/ #define msgb_l1(m) ((void *)(m->l1h)) #define msgb_l2(m) ((void *)(m->l2h)) diff --git a/include/nuttx/serial/serial.h b/include/nuttx/serial/serial.h index 710345511f2e1db0571c8eb81e064fa0553219f5..493c0d53bad86cd2abed0a6912406caad184d481 100644 --- a/include/nuttx/serial/serial.h +++ b/include/nuttx/serial/serial.h @@ -1,7 +1,7 @@ /************************************************************************************ * include/nuttx/serial/serial.h * - * Copyright (C) 2007-2008, 2012-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2008, 2012-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -104,9 +104,16 @@ #define uart_send(dev,ch) dev->ops->send(dev,ch) #define uart_receive(dev,s) dev->ops->receive(dev,s) +#ifdef CONFIG_SERIAL_DMA +# define uart_dmasend(dev) dev->ops->dmasend(dev) +# define uart_dmareceive(dev) dev->ops->dmareceive(dev) +# define uart_dmarxfree(dev) dev->ops->dmarxfree(dev) +# define uart_dmatxavail(dev) dev->ops->dmatxavail(dev) +#endif + #ifdef CONFIG_SERIAL_IFLOWCONTROL -#define uart_rxflowcontrol(dev,n,u) \ - (dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u)) +# define uart_rxflowcontrol(dev,n,u) \ + (dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u)) #endif /************************************************************************************ @@ -127,6 +134,17 @@ struct uart_buffer_s FAR char *buffer; /* Pointer to the allocated buffer memory */ }; +#ifdef CONFIG_SERIAL_DMA +struct uart_dmaxfer_s +{ + FAR char *buffer; /* First DMA buffer */ + FAR char *nbuffer; /* Next DMA buffer */ + size_t length; /* Length of first DMA buffer */ + size_t nlength; /* Length of next DMA buffer */ + size_t nbytes; /* Bytes actually transferred by DMA from both buffers */ +}; +#endif /* CONFIG_SERIAL_DMA */ + /* This structure defines all of the operations providd by the architecture specific * logic. All fields must be provided with non-NULL function pointers by the * caller of uart_register(). @@ -199,6 +217,24 @@ struct uart_ops_s unsigned int nbuffered, bool upper); #endif +#ifdef CONFIG_SERIAL_DMA + /* Start transfer bytes from the TX circular buffer using DMA */ + + CODE void (*dmasend)(FAR struct uart_dev_s *dev); + + /* Start transfer bytes from the TX circular buffer using DMA */ + + CODE void (*dmareceive)(FAR struct uart_dev_s *dev); + + /* Notify DMA that there is free space in the RX buffer */ + + CODE void (*dmarxfree)(FAR struct uart_dev_s *dev); + + /* Notify DMA that there is data to be transferred in the TX buffer */ + + CODE void (*dmatxavail)(FAR struct uart_dev_s *dev); +#endif + /* This method will send one byte on the UART */ CODE void (*send)(FAR struct uart_dev_s *dev, int ch); @@ -266,6 +302,14 @@ struct uart_dev_s struct uart_buffer_s xmit; /* Describes transmit buffer */ struct uart_buffer_s recv; /* Describes receive buffer */ +#ifdef CONFIG_SERIAL_DMA + + /* DMA transfers */ + + struct uart_dmaxfer_s dmatx; /* Describes transmit DMA transfer */ + struct uart_dmaxfer_s dmarx; /* Describes receive DMA transfer */ +#endif + /* Driver interface */ FAR const struct uart_ops_s *ops; /* Arch-specific operations */ @@ -385,6 +429,58 @@ void uart_datasent(FAR uart_dev_t *dev); void uart_connected(FAR uart_dev_t *dev, bool connected); #endif +/************************************************************************************ + * Name: uart_xmitchars_dma + * + * Description: + * Set up to transfer bytes from the TX circular buffer using DMA + * + ************************************************************************************/ + +#ifdef CONFIG_SERIAL_DMA +void uart_xmitchars_dma(FAR uart_dev_t *dev); +#endif + +/************************************************************************************ + * Name: uart_xmitchars_done + * + * Description: + * Perform operations necessary at the complete of DMA including adjusting the + * TX circular buffer indices and waking up of any threads that may have been + * waiting for space to become available in the TX circular buffer. + * + ************************************************************************************/ + +#ifdef CONFIG_SERIAL_DMA +void uart_xmitchars_done(FAR uart_dev_t *dev); +#endif + +/************************************************************************************ + * Name: uart_recvchars_dma + * + * Description: + * Set up to receive bytes into the RX circular buffer using DMA + * + ************************************************************************************/ + +#ifdef CONFIG_SERIAL_DMA +void uart_recvchars_dma(FAR uart_dev_t *dev); +#endif + +/************************************************************************************ + * Name: uart_recvchars_done + * + * Description: + * Perform operations necessary at the complete of DMA including adjusting the + * RX circular buffer indices and waking up of any threads that may have been + * waiting for new data to become available in the RX circular buffer. + * + ************************************************************************************/ + +#ifdef CONFIG_SERIAL_DMA +void uart_recvchars_done(FAR uart_dev_t *dev); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/signal.h b/include/nuttx/signal.h new file mode 100644 index 0000000000000000000000000000000000000000..3f4adb50216bce54131d9c5eb2f1f9a764a22bf1 --- /dev/null +++ b/include/nuttx/signal.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * include/nuttx/signal.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_SIGNAL_H +#define __INCLUDE_NUTTX_SIGNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#if defined(CONFIG_SIG_EVTHREAD) && defined(CONFIG_BUILD_FLAT) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sig_notification + * + * Description: + * Notify a client a signal event via a function call. This function is + * an internal OS interface that implements the common logic for signal + * event notification for the case of SIGEV_THREAD. + * + * Input Parameters: + * pid - The task/thread ID a the client thread to be signaled. + * event - The instance of struct sigevent that describes how to signal + * the client. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sig_notification(pid_t pid, FAR struct sigevent *event); + +#endif /* CONFIG_SIG_EVTHREAD && CONFIG_BUILD_FLAT */ +#endif /* __INCLUDE_NUTTX_SIGNAL_H */ diff --git a/include/nuttx/spi/qspi.h b/include/nuttx/spi/qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..3db0826c39740a72fca201c22476f07cc9cf09ca --- /dev/null +++ b/include/nuttx/spi/qspi.h @@ -0,0 +1,319 @@ +/**************************************************************************** + * include/nuttx/qspi/qspi.h + * + * Copyright(C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_QSPI_QSPI_H +#define __INCLUDE_NUTTX_QSPI_QSPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Access macros ************************************************************/ + +/**************************************************************************** + * Name: QSPI_LOCK + * + * Description: + * On QSPI busses where there are multiple devices, it will be necessary to + * lock QSPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the QSPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the QSPI is properly + * configured for the device. If the QSPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock qspi bus, false: unlock QSPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define QSPI_LOCK(d,l) (d)->ops->lock(d,l) + +/**************************************************************************** + * Name: QSPI_SETFREQUENCY + * + * Description: + * Set the QSPI frequency. Required. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The QSPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +#define QSPI_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f)) + +/**************************************************************************** + * Name: QSPI_SETMODE + * + * Description: + * Set the QSPI mode. Optional. See enum qspi_mode_e for mode definitions. + * + * Input Parameters: + * dev - Device-specific state data + * mode - The QSPI mode requested + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define QSPI_SETMODE(d,m) (d)->ops->setmode(d,m) + +/**************************************************************************** + * Name: QSPI_SETBITS + * + * Description: + * Set the number if bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requests. + * If value is greater > 0 then it implies MSB first + * If value is below < 0, then it implies LSB first with -nbits + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define QSPI_SETBITS(d,b) (d)->ops->setbits(d,b) + +/**************************************************************************** + * Name: QSPI_COMMAND + * + * Description: + * Perform one QSPI command transfer + * + * Input Parameters: + * dev - Device-specific state data + * cmdinfo - Describes the command transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +#define QSPI_COMMAND(d,c) (d)->ops->command(d,c) + +/* QSPI Command Transfer Flags */ + +#define QSPICMD_ADDRESS (1 << 0) /* Bit 0: Enable address transfer */ +#define QSPICMD_READDATA (1 << 1) /* Bit 1: Enable read data transfer */ +#define QSPICMD_WRITEDATA (1 << 2) /* Bit 2: Enable write data transfer */ + +#define QSPICMD_ISADDRESS(f) (((f) & QSPICMD_ADDRESS) != 0) +#define QSPICMD_ISDATA(f) (((f) & (QSPICMD_READDATA | QSPICMD_WRITEDATA)) != 0) +#define QSPICMD_ISREAD(f) (((f) & QSPICMD_READDATA) != 0) +#define QSPICMD_ISWRITE(f) (((f) & QSPICMD_WRITEDATA) != 0) + +/**************************************************************************** + * Name: QSPI_MEMORY + * + * Description: + * Perform one QSPI memory transfer + * + * Input Parameters: + * dev - Device-specific state data + * meminfo - Describes the memory transfer to be performed. + * + * Returned Value: + * Zero (OK) on SUCCESS, a negated errno on value of failure + * + ****************************************************************************/ + +#define QSPI_MEMORY(d,m) (d)->ops->memory(d,m) + +/* QSPI Memory Transfer Flags */ + +#define QSPIMEM_READ (0) /* Bit 2: 0=Memory read data transfer */ +#define QSPIMEM_WRITE (1 << 2) /* Bit 2: 1=Memory write data transfer */ +#define QSPIMEM_DUALIO (1 << 3) /* Bit 3: Use Dual I/O (READ only) */ +#define QSPIMEM_QUADIO (1 << 4) /* Bit 4: Use Quad I/O (READ only) */ +#define QSPIMEM_SCRAMBLE (1 << 5) /* Bit 5: Scramble data */ +#define QSPIMEM_RANDOM (1 << 6) /* Bit 6: Use random key in scrambler */ + +#define QSPIMEM_ISREAD(f) (((f) & QSPIMEM_WRITE) == 0) +#define QSPIMEM_ISWRITE(f) (((f) & QSPIMEM_WRITE) != 0) +#define QSPIMEM_ISDUALIO(f) (((f) & QSPIMEM_DUALIO) != 0) +#define QSPIMEM_ISQUADIO(f) (((f) & QSPIMEM_QUADIO) != 0) +#define QSPIMEM_ISSCRAMBLE(f) (((f) & QSPIMEM_SCRAMBLE) != 0) + +#define QSPIMEM_ISRANDOM(f) \ + (((f) & (QSPIMEM_SCRAMBLE|QSPIMEM_RANDOM)) == \ + (QSPIMEM_SCRAMBLE|QSPIMEM_RANDOM)) + +/**************************************************************************** + * Name: QSPI_ALLOC + * + * Description: + * Allocate a buffer suitable for DMA data transfer + * + * Input Parameters: + * dev - Device-specific state data + * buflen - Buffer length to allocate in bytes + * + * Returned Value: + * Address of tha allocated memory on success; NULL is returned on any + * failure. + * + ****************************************************************************/ + +#define QSPI_ALLOC(d,b) (d)->ops->alloc(d,b) + +/**************************************************************************** + * Name: QSPI_FREE + * + * Description: + * Free memory returned by QSPI_ALLOC + * + * Input Parameters: + * dev - Device-specific state data + * buffer - Buffer previously allocated via QSPI_ALLOC + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#define QSPI_FREE(d,b) (d)->ops->free(d,b) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Certain QSPI devices may required different clocking modes */ + +enum qspi_mode_e +{ + QSPIDEV_MODE0 = 0, /* CPOL=0 CHPHA=0 */ + QSPIDEV_MODE1, /* CPOL=0 CHPHA=1 */ + QSPIDEV_MODE2, /* CPOL=1 CHPHA=0 */ + QSPIDEV_MODE3 /* CPOL=1 CHPHA=1 */ +}; + +/* This structure describes one command transfer */ + +struct qspi_cmdinfo_s +{ + uint8_t flags; /* See QSPICMD_* definitions */ + uint8_t addrlen; /* Address length in bytes (if QSPICMD_ADDRESS) */ + uint16_t cmd; /* Command */ + uint16_t buflen; /* Data buffer length in bytes (if QSPICMD_DATA) */ + uint32_t addr; /* Address (if QSPICMD_ADDRESS) */ + FAR void *buffer; /* Data buffer (if QSPICMD_DATA) */ +}; + +/* This structure describes one memory transfer */ + +struct qspi_meminfo_s +{ + uint8_t flags; /* See QSPMEM_* definitions */ + uint8_t addrlen; /* Address length in bytes */ + uint8_t dummies; /* Number of dummy read cycles (READ only) */ + uint16_t buflen; /* Data buffer length in bytes */ + uint16_t cmd; /* Memory access command */ + uint32_t addr; /* Memory Address */ + uint32_t key; /* Scrambler key */ + FAR void *buffer; /* Data buffer */ +}; + +/* The QSPI vtable */ + +struct qspi_dev_s; +struct qspi_ops_s +{ + CODE int (*lock)(FAR struct qspi_dev_s *dev, bool lock); + CODE uint32_t (*setfrequency)(FAR struct qspi_dev_s *dev, + uint32_t frequency); + CODE void (*setmode)(FAR struct qspi_dev_s *dev, + enum qspi_mode_e mode); + CODE void (*setbits)(FAR struct qspi_dev_s *dev, int nbits); + CODE int (*command)(FAR struct qspi_dev_s *dev, + FAR struct qspi_cmdinfo_s *cmdinfo); + CODE int (*memory)(FAR struct qspi_dev_s *dev, + FAR struct qspi_meminfo_s *meminfo); + CODE FAR void *(*alloc)(FAR struct qspi_dev_s *dev, size_t buflen); + CODE void (*free)(FAR struct qspi_dev_s *dev, FAR void *buffer); +}; + +/* QSPI private data. This structure only defines the initial fields of the + * structure visible to the QSPI client. The specific implementation may + * add additional, device specific fields + */ + +struct qspi_dev_s +{ + FAR const struct qspi_ops_s *ops; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __INCLUDE_NUTTX_QSPI_QSPI_H */ diff --git a/include/nuttx/spi/slave.h b/include/nuttx/spi/slave.h index 2fb7dd3762d6a9314def7422e267dbd8c9ed9a76..b53ce28f5110286ef09cc459f5ecd49f26bc1f50 100644 --- a/include/nuttx/spi/slave.h +++ b/include/nuttx/spi/slave.h @@ -269,14 +269,19 @@ * slave device and the SPI slave controller hardware. This interface * is implemented by the SPI slave device controller lower-half driver * and is provided to the the SPI slave device driver when that driver - * is initialized. That SPI slave device initialization function has - * the prototype: + * is initialized. That SPI slave device initialization function is + * unique to the SPI slave implementation. The prototype is probably + * something like: * - * FAR struct spi_sctrlr_s *up_spi_slave_initialize(int port); + * FAR struct spi_sctrlr_s *xyz_spi_slave_initialize(int port); * * Given an SPI port number, this function returns an instance of the * SPI slave controller interface. * + * The actual prototype and more detailed usage instructions should + * appear in a header file associated with the specific SPI slave + * implementation. + * * 2) struct spi_sdev_s: Defines the second interface between the SPI * slave device and the SPI slave controller hardware. This interface * is implemented by the SPI slave device. The slave device passes this @@ -387,7 +392,44 @@ * upon it. * * A typical DMA data transfer processes as follows: - * To be provided + * To be provided -- I do not have a design in mind to support DMA on the + * Slave side. The design might be very complex because: + * + * 1) You need DMA buffers of fixed size, but you cannot know the size of a + * transfer in advance, it could be much larger than your buffer or much + * smaller. The DMA would fail in either case. + * + * 2) You cannot setup the DMA before the transfer. In most SPI protocols, + * the first word send is a command to read or write something following + * by a sequence of transfers to implement the write. So you have very, + * very limited time window to setup the correct DMA to respond to the + * command. I am not certain that it can be done reliably. + * + * Inserting dummy words into the protocol between the first command word + * and the remaining data transfer could allow time to set up the DMA. + * + * 3) I mentioned that you do not know the size of the transfer in advance. + * If you set up the DMA to terminate to soon, then you lose the last part + * of the transfer. If you set the DMA up to be too large, then you will + * get no indication when the transfer completes. + * + * The chip select going high would be one possibility to detect the end + * of a transfer. You could cancel a DMA in progress if the CS changes, + * but I do not know if that would work. If there is only one device on + * the SPI bus, then most board designs will save a pin and simply tie CS + * to ground. So the CS is not always a reliable indicator of when the + * transfer completes. + * + * 4) The option is to use a timer but that would really slow down the + * transfers if each DMA has to end with a timeout. It would be faster + * non-DMA transfers. + * + * If the device as a very restricted protocol, like just register reads + * and writes, then it might possible to implement DMA. However, that + * solution would not be general and probably not an appropriate part of + * a general OS. But if the interface is unpredictable, such as reading/ + * variable amounts of data from FLASH, there is more risk. A general + * solution might not be possible. */ enum spi_smode_e @@ -467,23 +509,6 @@ extern "C" * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: up_spi_slave_initialize - * - * Description: - * Initialize the selected SPI port in slave mode. - * - * Input Parameter: - * port - Chip select number identifying the "logical" SPI port. Includes - * encoded port and chip select information. - * - * Returned Value: - * Valid SPI device structure reference on success; a NULL on failure - * - ****************************************************************************/ - -FAR struct spi_sctrlr_s *up_spi_slave_initialize(int port); - #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/spi/spi.h b/include/nuttx/spi/spi.h index 2a6e25ed0348749ac2280afc5c3ee7c727a97c21..5daacd30059ace89312ec6a2082f7f8442431d4c 100644 --- a/include/nuttx/spi/spi.h +++ b/include/nuttx/spi/spi.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/spi/spi.h * - * Copyright(C) 2008-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright(C) 2008-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,20 +45,23 @@ #include #include #include +#include +#include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /* Configuration ************************************************************/ -/* CONFIG_SPI_OWNBUS - Set if there is only one active device on the SPI bus. - * No locking or SPI configuration will be performed. It is not necessary - * for clients to lock, re-configure, etc.. +/* These SPI configuration options affect the form of the SPI interface: + * * CONFIG_SPI_EXCHANGE - Driver supports a single exchange method * (vs a recvblock() and sndblock ()methods). * CONFIG_SPI_CMDDATA - Devices on the SPI bus require out-of-band support * to distinguish command transfers from data transfers. Such devices * will often support either 9-bit SPI (yech) or 8-bit SPI and a GPIO * output that selects between command and data. + * CONFIG_SPI_HWFEATURES - Include an interface method to support special, + * hardware-specific SPI features. */ /* Access macros ************************************************************/ @@ -84,11 +87,7 @@ * ****************************************************************************/ -#ifndef CONFIG_SPI_OWNBUS -# define SPI_LOCK(d,l) (d)->ops->lock(d,l) -#else -# define SPI_LOCK(d,l) 0 -#endif +#define SPI_LOCK(d,l) (d)->ops->lock(d,l) /**************************************************************************** * Name: SPI_SELECT @@ -166,6 +165,44 @@ #define SPI_SETBITS(d,b) \ do { if ((d)->ops->setbits) (d)->ops->setbits(d,b); } while (0) +/**************************************************************************** + * Name: SPI_HWFEATURES + * + * Description: + * Set hardware-specific feature flags. + * + * Input Parameters: + * dev - Device-specific state data + * flags - H/W feature flags + * + * Returned Value: + * Zero (OK) if the selected H/W features are enabled; A negated errno + * value if any H/W feature is not supportable. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_HWFEATURES + /* If there are multiple SPI drivers, some may not support hardware + * feature selection. + */ + +# define SPI_HWFEATURES(d,f) \ + (((d)->ops->hwfeatures) ? (d)->ops->hwfeatures(d,f) : ((f) == 0 ? OK : -ENOSYS)) + + /* These are currently defined feature flags */ + +# ifdef CONFIG_SPI_CRCGENERATION +# HWFEAT_CRCGENERATION (1 << 0) /* Bit 0: Hardward CRC generation */ +# endif + +#else + /* Any attempt to select hardware features with CONFIG_SPI_HWFEATURES + * deselected will cause an assertion. + */ + +# define SPI_HWFEATURES(d,f) (((f) == 0) ? OK : -ENOSYS) +#endif + /**************************************************************************** * Name: SPI_STATUS * @@ -364,6 +401,8 @@ enum spi_dev_e SPIDEV_EEPROM, /* Select SPI EEPROM device */ SPIDEV_ACCELEROMETER, /* Select SPI Accelerometer device */ SPIDEV_BAROMETER, /* Select SPI Pressure/Barometer device */ + SPIDEV_TEMPERATURE, /* Select SPI Temperature sensor device */ + SPIDEV_IEEE802154, /* Select SPI IEEE 802.15.4 wireless device */ SPIDEV_USER /* Board-specific values start here */ }; @@ -377,22 +416,30 @@ enum spi_mode_e SPIDEV_MODE3 /* CPOL=1 CHPHA=1 */ }; +#ifdef CONFIG_SPI_HWFEATURES +/* This is a type wide enough to support all hardware features */ + +typedef uint8_t spi_hwfeatures_t; +#endif + /* The SPI vtable */ struct spi_dev_s; struct spi_ops_s { -#ifndef CONFIG_SPI_OWNBUS CODE int (*lock)(FAR struct spi_dev_s *dev, bool lock); -#endif CODE void (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); CODE uint32_t (*setfrequency)(FAR struct spi_dev_s *dev, uint32_t frequency); CODE void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode); CODE void (*setbits)(FAR struct spi_dev_s *dev, int nbits); +#ifdef CONFIG_SPI_HWFEATURES + CODE int (*hwfeatures)(FAR struct spi_dev_s *dev, + spi_hwfeatures_t features); +#endif CODE uint8_t (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid); #ifdef CONFIG_SPI_CMDDATA - CODE int (*cmddata)(FAR struct spi_dev_s *dev, enum spi_dev_e devid + CODE int (*cmddata)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); #endif CODE uint16_t (*send)(FAR struct spi_dev_s *dev, uint16_t wd); @@ -433,42 +480,6 @@ extern "C" #define EXTERN extern #endif -/**************************************************************************** - * Name: up_spiinitialize - * - * Description: - * Initialize the selected SPI port in master mode. - * - * This is a generic prototype for the SPI initialize logic. Specific - * architectures may support different SPI initialization functions if, - * for example, those architectures support multiple, incompatible SPI - * implementations. In any event, the prototype of those architecture- - * specific initialization functions should be the same as - * up_spiinitialize() - * - * As an example, the LPC17xx family supports an SPI block and several SSP - * blocks that may be programmed to support the SPI function. In this - * case, the LPC17xx architecture supports these two initialization - * functions: - * - * FAR struct spi_dev_s *lpc17_spiinitialize(int port); - * FAR struct spi_dev_s *lpc17_sspinitialize(int port); - * - * Another example would be the STM32 families that support both SPI - * blocks as well as USARTs that can be configured to perform the SPI - * function as well (the STM32 USARTs do not support SPI as of this - * writing). - * - * Input Parameter: - * Port number (for hardware that has multiple SPI interfaces) - * - * Returned Value: - * Valid SPI device structure reference on success; a NULL on failure - * - ****************************************************************************/ - -FAR struct spi_dev_s *up_spiinitialize(int port); - #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/spi/spi_bitbang.h b/include/nuttx/spi/spi_bitbang.h index b54a3b3d1a853fa501dc62dfa9042836b5a13c4f..fee6a9f1fca19e9a0121627c4b7232b069cc2ba3 100644 --- a/include/nuttx/spi/spi_bitbang.h +++ b/include/nuttx/spi/spi_bitbang.h @@ -127,9 +127,7 @@ struct spi_bitbang_s FAR const struct spi_bitbang_ops_s *low; /* Low-level operations */ uint32_t holdtime; /* SCK hold time to achieve requested frequency */ bitexchange_t exchange; /* The select bit exchange function */ -#ifndef CONFIG_SPI_OWNBUS sem_t exclsem; /* Supports mutually exclusive access to SPI */ -#endif #ifdef CONFIG_SPI_BITBANG_VARWIDTH uint8_t nbits; /* Number of bits in the transfer */ #endif diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h new file mode 100644 index 0000000000000000000000000000000000000000..544facfef91ec38f281e13729c2aee0373875ce3 --- /dev/null +++ b/include/nuttx/spinlock.h @@ -0,0 +1,305 @@ +/**************************************************************************** + * include/nuttx/spinlock.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_SPINLOCK_H +#define __INCLUDE_NUTTX_SPINLOCK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifdef CONFIG_SPINLOCK + +/* The architecture specific spinlock.h header file must also provide the + * following: + * + * SP_LOCKED - A definition of the locked state value (usually 1) + * SP_UNLOCKED - A definition of the unlocked state value (usually 0) + * spinlock_t - The type of a spinlock memory object. + * + * SP_LOCKED and SP_UNLOCKED must constants of type spinlock_t. + */ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct spinlock_s +{ + volatile spinlock_t sp_lock; /* Indicates if the spinlock is locked or + * not. See the* values SP_LOCKED and + * SP_UNLOCKED. */ +#ifdef CONFIG_SMP + uint8_t sp_cpu; /* CPU holding the lock */ + uint16_t sp_count; /* The count of references by this CPU on + * the lock */ +#endif +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: up_testset + * + * Description: + * Perform and atomic test and set operation on the provided spinlock. + * + * This function must be provided via the architecture-specific logoic. + * + * Input Parameters: + * lock - The address of spinlock object. + * + * Returned Value: + * The spinlock is always locked upon return. The value of previous value + * of the spinlock variable is returned, either SP_LOCKED if the spinlock + * as previously locked (meaning that the test-and-set operation failed to + * obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked + * (meaning that we successfully obtained the lock) + * + ****************************************************************************/ + +spinlock_t up_testset(volatile FAR spinlock_t *lock); + +/**************************************************************************** + * Name: spin_initialize + * + * Description: + * Initialize a non-reentrant spinlock object to its initial, unlocked state. + * + * Input Parameters: + * lock - A reference to the spinlock object to be initialized. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +/* void spin_initialize(FAR spinlock_t *lock); */ +#define spin_initialize(i) do { (l) = SPI_UNLOCKED; } while (0) + +/**************************************************************************** + * Name: spin_initializer + * + * Description: + * Initialize a re-entrant spinlock object to its initial, unlocked state. + * + * Input Parameters: + * lock - A reference to the spinlock object to be initialized. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void spin_initializer(FAR struct spinlock_s *lock); + +/**************************************************************************** + * Name: spin_lock + * + * Description: + * If this CPU does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and is prone to deadlocks in + * the case that any logic on the same CPU attempts to take the lock + * more than one + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_lock(FAR volatile spinlock_t *lock); + +/**************************************************************************** + * Name: spin_lockr + * + * Description: + * If this CPU does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is re-entrant in the sense that it can called + * numerous times from the same CPU without blocking. Of course, + * spin_unlock() must be called the same number of times. NOTE: the + * thread that originallly took the look may be executing on a different + * CPU when it unlocks the spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_lockr(FAR struct spinlock_s *lock); + +/**************************************************************************** + * Name: spin_unlock + * + * Description: + * Release one count on a non-reentrant spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to unlock. + * + * Returned Value: + * None. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +/* void spin_unlock(FAR spinlock_t *lock); */ +#define spin_unlock(l) do { *(l) = SP_UNLOCKED; } while (0) + +/**************************************************************************** + * Name: spin_unlockr + * + * Description: + * Release one count on a re-entrant spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to unlock. + * + * Returned Value: + * None. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_unlockr(FAR struct spinlock_s *lock); + +/**************************************************************************** + * Name: spin_islocked + * + * Description: + * Release one count on a non-reentrant spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to test. + * + * Returned Value: + * A boolean value: true the spinlock is locked; false if it is unlocked. + * + ****************************************************************************/ + +/* bool spin_islocked(FAR spinlock_t lock); */ +#define spin_islocked(l) (*(l) == SP_LOCKED) + +/**************************************************************************** + * Name: spin_islockedr + * + * Description: + * Release one count on a re-entrant spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to test. + * + * Returned Value: + * A boolean value: true the spinlock is locked; false if it is unlocked. + * + ****************************************************************************/ + +/* bool spin_islockedr(FAR struct spinlock_s *lock); */ +#define spin_islockedr(l) ((l)->sp_lock == SP_LOCKED) + +/**************************************************************************** + * Name: spin_setbit + * + * Description: + * Makes setting a CPU bit in a bitset an atomic action + * + * Input Parameters: + * set - A reference to the bitset to set the CPU bit in + * cpu - The bit number to be set + * setlock - A reference to the lock lock protecting the set + * orlock - Will be set to SP_LOCKED while holding setlock + * + * Returned Value: + * None + * + ****************************************************************************/ + +void spin_setbit(FAR volatile cpu_set_t *set, unsigned int cpu, + FAR volatile spinlock_t *setlock, + FAR volatile spinlock_t *orlock); + +/**************************************************************************** + * Name: spin_clrbit + * + * Description: + * Makes clearing a CPU bit in a bitset an atomic action + * + * Input Parameters: + * set - A reference to the bitset to set the CPU bit in + * cpu - The bit number to be set + * setlock - A reference to the lock lock protecting the set + * orlock - Will be set to SP_UNLOCKED if all bits become cleared in set + * + * Returned Value: + * None + * + ****************************************************************************/ + +void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, + FAR volatile spinlock_t *setlock, + FAR volatile spinlock_t *orlock); + +#endif /* CONFIG_SPINLOCK */ +#endif /* __INCLUDE_NUTTX_SPINLOCK_H */ diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h index 139741ff050bf36c5d6482d500a17ff24f1ec026..ab57b33b35d1bc145272984db41e1f6423c7d864 100644 --- a/include/nuttx/streams.h +++ b/include/nuttx/streams.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/streams.h * - * Copyright (C) 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -194,7 +194,7 @@ struct lib_rawsostream_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -413,9 +413,10 @@ int lib_snoflush(FAR struct lib_sostream_s *this); * ****************************************************************************/ -int lib_sprintf(FAR struct lib_outstream_s *obj, FAR const char *fmt, ...); +int lib_sprintf(FAR struct lib_outstream_s *obj, + FAR const IPTR char *fmt, ...); int lib_vsprintf(FAR struct lib_outstream_s *obj, - FAR const char *src, va_list ap); + FAR const IPTR char *src, va_list ap); #undef EXTERN #if defined(__cplusplus) diff --git a/include/nuttx/symtab.h b/include/nuttx/symtab.h new file mode 100644 index 0000000000000000000000000000000000000000..d835a17b0db842635034c297a3c3f5a593bc6539 --- /dev/null +++ b/include/nuttx/symtab.h @@ -0,0 +1,164 @@ +/**************************************************************************** + * include/nuttx/binfmt/symtab.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_SYMTAB_H +#define __INCLUDE_NUTTX_SYMTAB_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* struct symbtab_s describes one entry in the symbol table. A symbol table + * is a fixed size array of struct symtab_s. The information is intentionally + * minimal and supports only: + * + * 1. Function pointers as sym_values. Of other kinds of values need to be + * supported, then typing information would also need to be included in + * the structure. + * + * 2. Fixed size arrays. There is no explicit provisional for dyanamically + * adding or removing entries from the symbol table (realloc might be + * used for that purpose if needed). The intention is to support only + * fixed size arrays completely defined at compilation or link time. + */ + +struct symtab_s +{ + FAR const char *sym_name; /* A pointer to the symbol name string */ + FAR const void *sym_value; /* The value associated witht the string */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: symtab_findbyname + * + * Description: + * Find the symbol in the symbol table with the matching name. + * This version assumes that table is not ordered with respect to symbol + * name and, hence, access time will be linear with respect to nsyms. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s * +symtab_findbyname(FAR const struct symtab_s *symtab, + FAR const char *name, int nsyms); + +/**************************************************************************** + * Name: symtab_findorderedbyname + * + * Description: + * Find the symbol in the symbol table with the matching name. + * This version assumes that table ordered with respect to symbol name. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s * +symtab_findorderedbyname(FAR const struct symtab_s *symtab, + FAR const char *name, int nsyms); + +/**************************************************************************** + * Name: symtab_findbyvalue + * + * Description: + * Find the symbol in the symbol table whose value closest (but not greater + * than), the provided value. This version assumes that table is not ordered + * with respect to symbol name and, hence, access time will be linear with + * respect to nsyms. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s * +symtab_findbyvalue(FAR const struct symtab_s *symtab, + FAR void *value, int nsyms); + +/**************************************************************************** + * Name: symtab_findorderedbyvalue + * + * Description: + * Find the symbol in the symbol table whose value closest (but not greater + * than), the provided value. This version assumes that table is ordered + * with respect to symbol name. + * + * Returned Value: + * A reference to the symbol table entry if an entry with the matching + * name is found; NULL is returned if the entry is not found. + * + ****************************************************************************/ + +FAR const struct symtab_s * +symtab_findorderedbyvalue(FAR const struct symtab_s *symtab, + FAR void *value, int nsyms); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_SYMTAB_H */ + diff --git a/include/nuttx/timers/cs2100-cp.h b/include/nuttx/timers/cs2100-cp.h index 9947f99d86106e64ea983af97c7f123c223badec..fe72836770b97675d5580cd7d3ee4d77d83f9c1b 100644 --- a/include/nuttx/timers/cs2100-cp.h +++ b/include/nuttx/timers/cs2100-cp.h @@ -43,7 +43,7 @@ #include #include -#include +#include #ifdef CONFIG_TIMERS_CS2100CP @@ -54,10 +54,6 @@ #ifndef CONFIG_I2C # error I2C driver support is required (CONFIG_I2C) -#else -# ifndef CONFIG_I2C_TRANSFER -# error I2C transfer method is required (CONFIG_I2C_TRANSFER) -# endif #endif #ifndef CONFIG_TIMERS_CS2100CP_CLKINBW @@ -163,13 +159,14 @@ struct cs2100_config_s { - FAR struct i2c_dev_s *i2c; /* Instance of an I2C interface */ - uint32_t refclk; /* RefClk/XTAL frequency */ - uint32_t clkin; /* Frequency CLK_IN provided to the CS2100-CP */ - uint32_t clkout; /* Desired CLK_OUT frequency */ - uint8_t i2caddr; /* CP2100-CP I2C address */ - uint8_t loopbw; /* Minimum loop bandwidth: 1-128 */ - bool xtal; /* false: Refclck, true: Crystal on XTI/XTO */ + FAR struct i2c_master_s *i2c; /* Instance of an I2C interface */ + uint32_t i2cfreq; /* I2C frequency */ + uint32_t refclk; /* RefClk/XTAL frequency */ + uint32_t clkin; /* Frequency CLK_IN provided to the CS2100-CP */ + uint32_t clkout; /* Desired CLK_OUT frequency */ + uint8_t i2caddr; /* CP2100-CP I2C address */ + uint8_t loopbw; /* Minimum loop bandwidth: 1-128 */ + bool xtal; /* false: Refclck, true: Crystal on XTI/XTO */ }; /******************************************************************************************** @@ -188,7 +185,7 @@ extern "C" * Public Function Prototypes ********************************************************************************************/ -struct i2c_dev_s; /* Forward reference */ +struct i2c_master_s; /* Forward reference */ /******************************************************************************************** * Name: cs2100_enable diff --git a/include/nuttx/timers/ds3231.h b/include/nuttx/timers/ds3231.h new file mode 100644 index 0000000000000000000000000000000000000000..2aa0cfcf54838ec0a480037be13ba41d71ae3768 --- /dev/null +++ b/include/nuttx/timers/ds3231.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * include/nuttx/timers/ds3231.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_TIMERS_DS3231_H +#define __INCLUDE_NUTTX_TIMERS_DS3231_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_RTC_DSXXXX + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: dsxxxx_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence by board-specific logic. + * + * After dsxxxx_rtc_initialize() is called, the OS function clock_synchronize() + * should also be called to synchronize the system timer to a hardware RTC. That + * operation is normally performed automatically by the system during clock + * initialization. However, when an external RTC is used, the board logic will + * need to explicitly re-synchronize the system timer to the RTC when the RTC + * becomes available. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +struct i2c_master_s; /* Forward reference */ +int dsxxxx_rtc_initialize(FAR struct i2c_master_s *i2c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_RTC_DSXXXX */ +#endif /* __INCLUDE_NUTTX_TIMERS_DS3231_H */ diff --git a/include/nuttx/timers/pcf85263.h b/include/nuttx/timers/pcf85263.h new file mode 100644 index 0000000000000000000000000000000000000000..4018e1ca658399c164dba5e3648b7418ddd00bc5 --- /dev/null +++ b/include/nuttx/timers/pcf85263.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * include/nuttx/timers/pcf85263.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_TIMERS_PCF85263_H +#define __INCLUDE_NUTTX_TIMERS_PCF85263_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_RTC_PCF85263 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: pcf85263_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. This function is + * called once during the OS initialization sequence by board-specific logic. + * + * After pcf85263_rtc_initialize() is called, the OS function clock_synchronize() + * should also be called to synchronize the system timer to a hardware RTC. That + * operation is normally performed automatically by the system during clock + * initialization. However, when an external RTC is used, the board logic will + * need to explicitly re-synchronize the system timer to the RTC when the RTC + * becomes available. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +struct i2c_master_s; /* Forward reference */ +int pcf85263_rtc_initialize(FAR struct i2c_master_s *i2c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_RTC_PCF85263 */ +#endif /* __INCLUDE_NUTTX_TIMERS_PCF85263_H */ diff --git a/include/nuttx/timers/rtc.h b/include/nuttx/timers/rtc.h index d714e040f1c1f8bdc464f31c21fe663189740a99..a6e3edcc19d9995e6a4108d74ee6930ef72a0a1d 100644 --- a/include/nuttx/timers/rtc.h +++ b/include/nuttx/timers/rtc.h @@ -111,7 +111,7 @@ * RTC upper half driver is built. */ -#if CONFIG_RTC_DRIVER +#ifdef CONFIG_RTC_DRIVER /* IOCTL Commands ***********************************************************/ /* RTC driver IOCTL commands. These are Linux compatible command names, not @@ -291,7 +291,7 @@ struct rtc_time int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Years since 1900 */ -#ifdef CONFIG_LIBC_LOCALTIME +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) int tm_wday; /* Day of the week (0-6) (unused) */ int tm_yday; /* Day of the year (0-365) (unused) */ int tm_isdst; /* Non-0 if daylight savings time is in effect (unused) */ diff --git a/include/nuttx/timers/timer.h b/include/nuttx/timers/timer.h index 8e6926083c26b7535879c6dd9d20792591176ae3..5d11498e71e844f1d4b584a359f08e22ff0f7841 100644 --- a/include/nuttx/timers/timer.h +++ b/include/nuttx/timers/timer.h @@ -45,6 +45,7 @@ #include #include #include +#include #ifdef CONFIG_TIMER diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h new file mode 100644 index 0000000000000000000000000000000000000000..39c9529716063d4b49685f9059cdb5a0a4bb3c4d --- /dev/null +++ b/include/nuttx/tls.h @@ -0,0 +1,140 @@ +/**************************************************************************** + * include/nuttx/tls.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __INCLUDE_NUTTX_TLS_H +#define __INCLUDE_NUTTX_TLS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_TLS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_TLS_LOG2_MAXSTACK +# error CONFIG_TLS_LOG2_MAXSTACK is not defined +#endif + +#ifndef CONFIG_TLS_NELEM +# warning CONFIG_TLS_NELEM is not defined +# define CONFIG_TLS_NELEM 1 +#endif + +#if CONFIG_TLS_NELEM < 1 +# error CONFIG_TLS_NELEM must be at least one +# undef CONFIG_TLS_NELEM +# define CONFIG_TLS_NELEM 1 +#endif + +/* TLS Definitions **********************************************************/ + +#define TLS_STACK_ALIGN (1L << CONFIG_TLS_LOG2_MAXSTACK) +#define TLS_STACK_MASK (TLS_STACK_ALIGN - 1) +#define TLS_MAXSTACK (TLS_STACK_ALIGN) +#define TLS_INFO(sp) ((FAR struct tls_info_s *)((sp) & ~TLS_STACK_MASK)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* When TLS is enabled, up_createstack() will align allocated stacks to the + * TLS_STACK_ALIGN value. An instance of the following structure will be + * implicitly positioned at the "lower" end of the stack. Assuming a + * "push down" stack, this is at the "far" end of the stack (and can be + * clobbered if the stack overflows). + * + * If an MCU has a "push up" then that TLS structure will lie at the top + * of the stack and stack allocation and initialization logic must take + * care to preserve this structure content. + * + * The stack memory is fully accessible to user mode threads. TLS is not + * available from interrupt handlers (nor from the IDLE thread). + */ + +struct tls_info_s +{ + uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_get_element + * + * Description: + * Return an the TLS element associated with the 'elem' index + * + * Input Parameters: + * elem - Index of TLS element to return + * + * Returned Value: + * The value of TLS element associated with 'elem'. Errors are not reported. + * Aero is returned in the event of an error, but zero may also be valid + * value and returned when there is no error. The only possible error would + * be if elemn < 0 or elem >=CONFIG_TLS_NELEM. + * + ****************************************************************************/ + +uintptr_t tls_get_element(int elem); + +/**************************************************************************** + * Name: tls_get_element + * + * Description: + * Set the TLS element associated with the 'elem' index to 'value' + * + * Input Parameters: + * elem - Index of TLS element to set + * value - The new value of the TLS element + * + * Returned Value: + * None. Errors are not reported. The only possible error would be if + * elem < 0 or elem >=CONFIG_TLS_NELEM. + * + ****************************************************************************/ + +void tls_set_element(int elem, uintptr_t value); + +#endif /* CONFIG_TLS */ +#endif /* __INCLUDE_NUTTX_TLS_H */ diff --git a/include/nuttx/usb/composite.h b/include/nuttx/usb/composite.h index 6b5fd8db8e729d8c25e66c66602d7023bc72bc69..722f9c46670ad5d61cedf395ab8187bdbdb5346e 100644 --- a/include/nuttx/usb/composite.h +++ b/include/nuttx/usb/composite.h @@ -131,7 +131,7 @@ FAR void *composite_initialize(void); * Returned Value: * None * - ***************************************************************************/ + ****************************************************************************/ void composite_uninitialize(FAR void *handle); diff --git a/include/nuttx/usb/usbdev_trace.h b/include/nuttx/usb/usbdev_trace.h index b05eaca210a816fd407aa14ec1c79f7d752fc819..445ef5f560a3933c8b8edc224588a20291e66fc3 100644 --- a/include/nuttx/usb/usbdev_trace.h +++ b/include/nuttx/usb/usbdev_trace.h @@ -462,7 +462,7 @@ EXTERN const struct trace_msg_t g_usb_trace_strings_intdecode[]; * Public Function Prototypes ****************************************************************************/ -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_enable * * Description: @@ -478,7 +478,7 @@ EXTERN const struct trace_msg_t g_usb_trace_strings_intdecode[]; * Assumptions: * - May be called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB)) usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset); @@ -486,7 +486,7 @@ usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset); # define usbtrace_enable(idset) #endif -/******************************************************************************* +/**************************************************************************** * Name: usbtrace * * Description: @@ -495,7 +495,7 @@ usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset); * Assumptions: * May be called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB)) void usbtrace(uint16_t event, uint16_t value); @@ -503,7 +503,7 @@ void usbtrace(uint16_t event, uint16_t value); # define usbtrace(event, value) #endif -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_enumerate * * Description: @@ -512,7 +512,7 @@ void usbtrace(uint16_t event, uint16_t value); * Assumptions: * NEVER called from an interrupt handler * - *******************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_USBDEV_TRACE int usbtrace_enumerate(trace_callback_t callback, void *arg); @@ -520,13 +520,13 @@ int usbtrace_enumerate(trace_callback_t callback, void *arg); # define usbtrace_enumerate(event) #endif -/******************************************************************************* +/**************************************************************************** * Name: usbtrace_trprint * * Description: * Print the trace record using the supplied printing function * - *******************************************************************************/ + ****************************************************************************/ void usbtrace_trprintf(trprintf_t trprintf, uint16_t event, uint16_t value); diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index 1e72ae26353453f44795174d5fdd14a9a1399a62..587917701cd263034888f19cec970acc9dfa46fe 100644 --- a/include/nuttx/usb/usbhost.h +++ b/include/nuttx/usb/usbhost.h @@ -163,7 +163,7 @@ #define CLASS_DISCONNECTED(devclass) ((devclass)->disconnected(devclass)) -/******************************************************************************* +/**************************************************************************** * Name: CONN_WAIT * * Description: @@ -186,7 +186,7 @@ * - Called from a single thread so no mutual exclusion is required. * - Never called from an interrupt handler. * - *******************************************************************************/ + ****************************************************************************/ #define CONN_WAIT(conn,hport) ((conn)->wait(conn,hport)) @@ -1103,7 +1103,7 @@ int usbhost_mouse_init(void); int usbhost_wlaninit(void); -/******************************************************************************* +/**************************************************************************** * Name: usbhost_enumerate * * Description: @@ -1135,7 +1135,7 @@ int usbhost_wlaninit(void); * - Called from a single thread so no mutual exclusion is required. * - Never called from an interrupt handler. * - *******************************************************************************/ + ****************************************************************************/ int usbhost_enumerate(FAR struct usbhost_hubport_s *hub, FAR struct usbhost_class_s **devclass); diff --git a/include/nuttx/usb/usbhost_devaddr.h b/include/nuttx/usb/usbhost_devaddr.h index 718d804cae0601e33ae661f824d4bef360b37aee..df4514f3954196778a65b5af46689aba2be07ebf 100644 --- a/include/nuttx/usb/usbhost_devaddr.h +++ b/include/nuttx/usb/usbhost_devaddr.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/**************************************************************************** * include/nuttx/usb/usbhost_devaddr.h * Manage USB device addresses * @@ -38,31 +38,31 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *******************************************************************************/ + ****************************************************************************/ #ifndef _INCLUDE_NUTTX_USB_USBHOST_DEVADDR_H #define _INCLUDE_NUTTX_USB_USBHOST_DEVADDR_H -/******************************************************************************* +/**************************************************************************** * Included Files - *******************************************************************************/ + ****************************************************************************/ #include #include #include -/******************************************************************************* +/**************************************************************************** * Pre-processor Definitions - *******************************************************************************/ -/* Configuration ***************************************************************/ + ****************************************************************************/ +/* Configuration ************************************************************/ #define USBHOST_DEVADDR_HASHSIZE 8 #define USBHOST_DEVADDR_HASHMASK (USBHOST_DEVADDR_HASHSIZE-1) -/******************************************************************************* +/**************************************************************************** * Public Types - *******************************************************************************/ + ****************************************************************************/ struct usbhost_devaddr_s { @@ -71,9 +71,9 @@ struct usbhost_devaddr_s uint32_t alloctab[4]; /* Bit allocation table */ }; -/******************************************************************************* +/**************************************************************************** * Public Data - *******************************************************************************/ + ****************************************************************************/ #undef EXTERN #if defined(__cplusplus) @@ -84,14 +84,14 @@ extern "C" # define EXTERN extern #endif -/******************************************************************************* +/**************************************************************************** * Public Functions - *******************************************************************************/ + ****************************************************************************/ struct usbhost_hubport_s; /* Forward reference */ struct usbhost_roothubport_s; /* Forward reference */ -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_initialize * * Description: @@ -105,11 +105,11 @@ struct usbhost_roothubport_s; /* Forward reference */ * Returned Value: * None * - *******************************************************************************/ + ****************************************************************************/ void usbhost_devaddr_initialize(FAR struct usbhost_roothubport_s *rhport); -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_create * * Description: @@ -123,11 +123,11 @@ void usbhost_devaddr_initialize(FAR struct usbhost_roothubport_s *rhport); * On success, a new device function address in the the range 0x01 to 0x7f * is returned. On failure, a negated errno value is returned. * - *******************************************************************************/ + ****************************************************************************/ int usbhost_devaddr_create(FAR struct usbhost_hubport_s *hport); -/******************************************************************************* +/**************************************************************************** * Name: usbhost_devaddr_destroy * * Description: @@ -141,7 +141,7 @@ int usbhost_devaddr_create(FAR struct usbhost_hubport_s *hport); * Returned Value: * None * - *******************************************************************************/ + ****************************************************************************/ void usbhost_devaddr_destroy(FAR struct usbhost_hubport_s *hport, uint8_t devaddr); diff --git a/include/nuttx/video/fb.h b/include/nuttx/video/fb.h index da41267719c0b51df98df9f6187204a8f8f945d5..4046fb546ca94f8d912b3c837779b45abfe2e027 100644 --- a/include/nuttx/video/fb.h +++ b/include/nuttx/video/fb.h @@ -372,7 +372,7 @@ extern "C" * multiple planes of video. * up_fbuninitialize - Uninitialize the framebuffer support * - ***************************************************************************/ + ****************************************************************************/ int up_fbinitialize(void); FAR struct fb_vtable_s *up_fbgetvplane(int vplane); diff --git a/include/nuttx/video/ov2640.h b/include/nuttx/video/ov2640.h index 4c037fdea29366569dc529b0b20f49a0ff352848..b398994d973a280c27a7fbaac96089c846d3aeca 100644 --- a/include/nuttx/video/ov2640.h +++ b/include/nuttx/video/ov2640.h @@ -77,8 +77,8 @@ extern "C" * ****************************************************************************/ -struct i2c_dev_s; -int ov2640_initialize(FAR struct i2c_dev_s *i2c); +struct i2c_master_s; +int ov2640_initialize(FAR struct i2c_master_s *i2c); #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/wdog.h b/include/nuttx/wdog.h index a5e6945d5b127c7a386481222cbe05ed6cc9a0ca..beb138809338f19f98baac3452f71c7199ec0f59 100644 --- a/include/nuttx/wdog.h +++ b/include/nuttx/wdog.h @@ -167,7 +167,7 @@ extern "C" WDOG_ID wd_create(void); int wd_delete(WDOG_ID wdog); -int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...); +int wd_start(WDOG_ID wdog, int32_t delay, wdentry_t wdentry, int argc, ...); int wd_cancel(WDOG_ID wdog); int wd_gettime(WDOG_ID wdog); diff --git a/include/nuttx/wireless/cc3000.h b/include/nuttx/wireless/cc3000.h index 6747bd7193b33e2c16b5701cdc5c32e0ee9bfab8..f369dc07943103663fc3299dcd7e66fa238bcc63 100644 --- a/include/nuttx/wireless/cc3000.h +++ b/include/nuttx/wireless/cc3000.h @@ -110,7 +110,7 @@ extern "C" #define EXTERN extern #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_init * * Description: @@ -146,7 +146,7 @@ extern "C" * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void wlan_init(size_t max_tx_len, tWlanCB sWlanCB, tFWPatches sFWPatches, diff --git a/include/nuttx/wireless/cc3000/cc3000_common.h b/include/nuttx/wireless/cc3000/cc3000_common.h index b28ef353c8fe18f2d4c97f2b13d9bb5bc227b8d5..4a11f74591b4545c6957e8a65c4d2f5c2b891d77 100644 --- a/include/nuttx/wireless/cc3000/cc3000_common.h +++ b/include/nuttx/wireless/cc3000/cc3000_common.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * cc3000_common.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,14 +30,14 @@ * (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 _INCLUDE_NUTTX_WIRELESS_CC3000_CC3000_COMMON_H #define _INCLUDE_NUTTX_WIRELESS_CC3000_CC3000_COMMON_H -/***************************************************************************** +/**************************************************************************** * Included files - *****************************************************************************/ + ****************************************************************************/ #include #include @@ -46,9 +46,9 @@ #include #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* Error codes */ @@ -199,9 +199,9 @@ #define STREAM_TO_STREAM(p, a, l) {register int16_t _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];} -/***************************************************************************** +/**************************************************************************** * Public Types - *****************************************************************************/ + ****************************************************************************/ typedef struct wlan_buffer_desc_s { @@ -250,9 +250,9 @@ typedef struct uint8_t InformHostOnTxComplete; } sSimplLinkInformation; -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" @@ -261,11 +261,11 @@ extern "C" extern volatile sSimplLinkInformation tSLInformation; -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: wlan_get_buffer * * Input Parameters: @@ -274,11 +274,11 @@ extern volatile sSimplLinkInformation tSLInformation; * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void wlan_get_buffer(wlan_buffer_desc *pdes); -/***************************************************************************** +/**************************************************************************** * Name: SimpleLinkWaitEvent * * Description: @@ -292,11 +292,11 @@ void wlan_get_buffer(wlan_buffer_desc *pdes); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams); -/***************************************************************************** +/**************************************************************************** * Name: SimpleLinkWaitData * * Description: @@ -311,11 +311,11 @@ void SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen); -/***************************************************************************** +/**************************************************************************** * Name: UINT32_TO_STREAM_f * * Description: @@ -329,11 +329,11 @@ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen); * Returned Value: * Pointer to the new stream * - *****************************************************************************/ + ****************************************************************************/ uint8_t *UINT32_TO_STREAM_f(uint8_t *p, unsigned long u32); -/***************************************************************************** +/**************************************************************************** * Name: UINT16_TO_STREAM_f * * Description: @@ -347,11 +347,11 @@ uint8_t *UINT32_TO_STREAM_f(uint8_t *p, unsigned long u32); * Returned Value: * Pointer to the new stream * - *****************************************************************************/ + ****************************************************************************/ uint8_t *UINT16_TO_STREAM_f(uint8_t *p, uint16_t u16); -/***************************************************************************** +/**************************************************************************** * Name: STREAM_TO_UINT16_f * * Description: @@ -365,11 +365,11 @@ uint8_t *UINT16_TO_STREAM_f(uint8_t *p, uint16_t u16); * Returned Value: * Pointer to the new 16 bit * - *****************************************************************************/ + ****************************************************************************/ uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset); -/***************************************************************************** +/**************************************************************************** * Name: STREAM_TO_UINT32_f * * Description: @@ -383,7 +383,7 @@ uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset); * Returned Value: * Pointer to the new 32 bit * - *****************************************************************************/ + ****************************************************************************/ unsigned long STREAM_TO_UINT32_f(char* p, uint16_t offset); diff --git a/include/nuttx/wireless/cc3000/evnt_handler.h b/include/nuttx/wireless/cc3000/evnt_handler.h index 6ffaa2c369f688733cf1a0d46496f9df6eac9636..fe5f4ecdad024d1a9580fb12dfa464941e9bbab4 100644 --- a/include/nuttx/wireless/cc3000/evnt_handler.h +++ b/include/nuttx/wireless/cc3000/evnt_handler.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * * evnt_handler.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ diff --git a/include/nuttx/wireless/cc3000/hci.h b/include/nuttx/wireless/cc3000/hci.h index 42c162b4e45c976f677ff6c5de2c1dc250197046..409fd9d1e94dbaaa0254b1f949d5febd3a4608ec 100644 --- a/include/nuttx/wireless/cc3000/hci.h +++ b/include/nuttx/wireless/cc3000/hci.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * hci.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,20 +30,20 @@ * (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 _INCLUDE_NUTTX_WIRELESS_CC3000_HCI_H #define _INCLUDE_NUTTX_WIRELESS_CC3000_HCI_H -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include "cc3000_common.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define SPI_HEADER_SIZE (5) #define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) @@ -197,20 +197,20 @@ #define HCI_EVENT_STATUS_OFFSET (4) #define HCI_DATA_LENGTH_OFFSET (3) -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Name: hci_command_send * * Description: @@ -224,13 +224,13 @@ extern "C" * Returned Value: * Zero * - *****************************************************************************/ + ****************************************************************************/ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength); -/****************************************************************************** +/**************************************************************************** * Name: hci_data_send * * Description: @@ -246,13 +246,13 @@ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, uint16_t usDataLength, const uint8_t *ucTail, uint16_t usTailLength); -/****************************************************************************** +/**************************************************************************** * Name: hci_data_command_send * * Description: @@ -267,12 +267,12 @@ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength,uint16_t ucDataLength); -/****************************************************************************** +/**************************************************************************** * Name: hci_patch_send * * Description: @@ -287,7 +287,7 @@ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff, * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch, uint16_t usDataLength); diff --git a/include/nuttx/wireless/cc3000/include/cc3000_upif.h b/include/nuttx/wireless/cc3000/include/cc3000_upif.h index 1240655ee15473c29c17341592c67eded28cc4ae..26c2e1097212fcb5b0b742a3a3fbd914d9085046 100644 --- a/include/nuttx/wireless/cc3000/include/cc3000_upif.h +++ b/include/nuttx/wireless/cc3000/include/cc3000_upif.h @@ -56,7 +56,7 @@ #include #include -#if defined(CONFIG_WIRELESS) && defined(CONFIG_WL_CC3000) +#if defined(CONFIG_DRIVERS_WIRELESS) && defined(CONFIG_WL_CC3000) /**************************************************************************** * Pre-processor Definitions @@ -188,5 +188,5 @@ int cc3000_register(FAR struct spi_dev_s *spi, } #endif -#endif /* CONFIG_WIRELESS && CONFIG_INPUT_CC3000 */ +#endif /* CONFIG_DRIVERS_WIRELESS && CONFIG_INPUT_CC3000 */ #endif /* __INCLUDE_NUTTX_WIRELESS_CC3000_INCLUDE_CC3000_UPIFL_H */ diff --git a/include/nuttx/wireless/cc3000/include/sys/socket.h b/include/nuttx/wireless/cc3000/include/sys/socket.h index 87e39c9501354470a7fd405d8341da0d4a063ebd..f40f7b64061d13b71b653944f2788a6a031e69fa 100644 --- a/include/nuttx/wireless/cc3000/include/sys/socket.h +++ b/include/nuttx/wireless/cc3000/include/sys/socket.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * socket.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,7 +30,7 @@ * (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 __INCLUDE_NUTTX_WIRELESS_CC3000_INCLUDE_SYS_SOCKET_H #define __INCLUDE_NUTTX_WIRELESS_CC3000_INCLUDE_SYS_SOCKET_H @@ -43,9 +43,9 @@ #include #include -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define socket(a,t,p) cc3000_socket(a,t,p) #define closesocket(s) cc3000_closesocket(s) @@ -62,24 +62,24 @@ #define gethostbyname(h,l,i) cc3000_gethostbyname(h,l,i) #define mdnsadvertiser(e,n,l) cc3000_mdnsadvertiser(e,n,l) -/***************************************************************************** +/**************************************************************************** * Public Types - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: socket * * Decription: @@ -100,11 +100,11 @@ extern "C" * On success, socket handle that is used for consequent socket * operations. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int socket(int domain, int type, int protocol); -/***************************************************************************** +/**************************************************************************** * Name: closesocket * * Decription: @@ -116,11 +116,11 @@ int socket(int domain, int type, int protocol); * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int closesocket(int sockfd); -/***************************************************************************** +/**************************************************************************** * Name: accept * * Decription: @@ -163,11 +163,11 @@ int closesocket(int sockfd); * - On connection pending, SOC_IN_PROGRESS (-2) * - On failure, SOC_ERROR (-1) * - *****************************************************************************/ + ****************************************************************************/ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); -/***************************************************************************** +/**************************************************************************** * Name: bind * * Decription: @@ -188,11 +188,11 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen); -/***************************************************************************** +/**************************************************************************** * Name: listen * * Decription: @@ -214,11 +214,11 @@ int bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen); * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ int listen(int sockfd, int backlog); -/***************************************************************************** +/**************************************************************************** * Name: connect * * Decription: @@ -246,11 +246,11 @@ int listen(int sockfd, int backlog); * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen); -/***************************************************************************** +/**************************************************************************** * Name: select * * Decription: @@ -287,14 +287,14 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen); * will return without delay. * *exceptfds - return the sockets which closed recently. * - *****************************************************************************/ + ****************************************************************************/ struct timeval; int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); #ifndef CC3000_TINY_DRIVER -/***************************************************************************** +/**************************************************************************** * Name: setsockopt * * Decription: @@ -340,12 +340,12 @@ int cc3000_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int setsockopt(int sockfd, int level, int option, FAR const void *value, socklen_t value_len); #endif -/***************************************************************************** +/**************************************************************************** * Name: getsockopt * * Decription: @@ -391,11 +391,11 @@ int setsockopt(int sockfd, int level, int option, FAR const void *value, socklen * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ int getsockopt(int sockfd, int level, int option, FAR void *value, FAR socklen_t *value_len); -/***************************************************************************** +/**************************************************************************** * Name: recv * * Decription: @@ -415,11 +415,11 @@ int getsockopt(int sockfd, int level, int option, FAR void *value, FAR socklen_t * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags); -/***************************************************************************** +/**************************************************************************** * Name: recvfrom * * Decription: @@ -446,12 +446,12 @@ ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags); * Return the number of bytes received, or -1 if an error * occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from, FAR socklen_t *fromlen); -/***************************************************************************** +/**************************************************************************** * Name: send * * Decription: @@ -471,11 +471,11 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags); -/***************************************************************************** +/**************************************************************************** * Name: sendto * * Decription: @@ -499,13 +499,13 @@ ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags); * Return the number of bytes transmitted, or -1 if an * error occurred * - *****************************************************************************/ + ****************************************************************************/ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags, FAR const struct sockaddr *to, socklen_t tolen); #ifndef CC3000_TINY_DRIVER -/***************************************************************************** +/**************************************************************************** * Name: gethostbyname * * Decription: @@ -526,12 +526,12 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags, * Returned Value: * On success, positive is returned. On error, negative is returned * - *****************************************************************************/ + ****************************************************************************/ int gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out_ip_addr); #endif -/***************************************************************************** +/**************************************************************************** * Name: mdnsAdvertiser * * Decription: @@ -547,7 +547,7 @@ int gethostbyname(char * hostname, uint16_t usNameLen, unsigned long* out_ip_add * On success, zero is returned, return SOC_ERROR if socket was not * opened successfully, or if an error occurred. * - *****************************************************************************/ + ****************************************************************************/ int mdnsadvertiser(uint16_t mdnsEnabled, char *deviceServiceName, uint16_t deviceServiceNameLength); diff --git a/include/nuttx/wireless/cc3000/netapp.h b/include/nuttx/wireless/cc3000/netapp.h index 8d0785c73c309fe04538524ecd3e22e5351a647b..e42b5876a4039b4f15b62dbcb0ebcfd3a08cebf4 100644 --- a/include/nuttx/wireless/cc3000/netapp.h +++ b/include/nuttx/wireless/cc3000/netapp.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * netapp.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,18 +30,18 @@ * (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 _INCLUDE_NUTTX_WIRELESS_CC3000_NETAPP_H #define _INCLUDE_NUTTX_WIRELESS_CC3000_NETAPP_H -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Types - *****************************************************************************/ + ****************************************************************************/ typedef struct _netapp_dhcp_ret_args_t { @@ -74,20 +74,20 @@ typedef struct _netapp_pingreport_args unsigned long avg_round_time; } netapp_pingreport_args_t; -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Name: netapp_config_mac_adrress * * Description: @@ -101,11 +101,11 @@ extern "C" * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ long netapp_config_mac_adrress(uint8_t *mac); -/****************************************************************************** +/**************************************************************************** * Name: netapp_dhcp * * Description: @@ -130,12 +130,12 @@ long netapp_config_mac_adrress(uint8_t *mac); * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, unsigned long *aucDefaultGateway, unsigned long *aucDNSServer); -/****************************************************************************** +/**************************************************************************** * Name: netapp_timeout_values * * Description: @@ -183,7 +183,7 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask, * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, @@ -191,7 +191,7 @@ long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, unsigned long *aucInactivity); #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_send * * Description: @@ -213,14 +213,14 @@ long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP, * Returned Value: * Return on success 0, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout); #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_stop * * Description: @@ -232,13 +232,13 @@ long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, * Returned Value: * On success, zero is returned. On error, -1 is returned. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_ping_stop(void); #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ping_report * * Description: @@ -263,14 +263,14 @@ long netapp_ping_stop(void); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER void netapp_ping_report(void); #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_ipconfig * * Description: @@ -298,11 +298,11 @@ void netapp_ping_report(void); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig); -/****************************************************************************** +/**************************************************************************** * Name: netapp_arp_flush * * Description: @@ -314,13 +314,13 @@ void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig); * Returned Value: * None * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_arp_flush(void); #endif -/****************************************************************************** +/**************************************************************************** * Name: netapp_set_debug_level * * Description: @@ -344,7 +344,7 @@ long netapp_arp_flush(void); * Returned Value: * On success, zero is returned. On error, -1 is returned * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER long netapp_set_debug_level(unsigned long ulLevel); diff --git a/include/nuttx/wireless/cc3000/nvmem.h b/include/nuttx/wireless/cc3000/nvmem.h index 35902def69118d3950d9dfee7981dba8024780e9..f9b3b48695c353d69841a9da78bfbe82dccd9028 100644 --- a/include/nuttx/wireless/cc3000/nvmem.h +++ b/include/nuttx/wireless/cc3000/nvmem.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * nvmem.h - CC3000 Host Driver Implementation. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * @@ -30,20 +30,20 @@ * (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 _INCLUDE_NUTTX_WIRELESS_CC3000_NVMEM_H #define _INCLUDE_NUTTX_WIRELESS_CC3000_NVMEM_H -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include "cc3000_common.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* NVMEM file ID - system files*/ @@ -69,20 +69,20 @@ #define NVMEM_MAX_ENTRY (16) -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/****************************************************************************** +/**************************************************************************** * Name: nvmem_read * * Description: @@ -106,12 +106,12 @@ extern "C" * Returned Value: * Number of bytes read, otherwise error. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, uint8_t *buff); -/****************************************************************************** +/**************************************************************************** * Name: nvmem_write * * Description: @@ -132,12 +132,12 @@ signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, uint8_t *buff); -/****************************************************************************** +/**************************************************************************** * Name: nvmem_set_mac_address * * Description: @@ -150,11 +150,11 @@ signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_set_mac_address(uint8_t *mac); -/****************************************************************************** +/**************************************************************************** * Name: nvmem_get_mac_address * * Description: @@ -167,11 +167,11 @@ uint8_t nvmem_set_mac_address(uint8_t *mac); * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_get_mac_address(uint8_t *mac); -/****************************************************************************** +/**************************************************************************** * Name: nvmem_write_patch * * Description: @@ -188,12 +188,12 @@ uint8_t nvmem_get_mac_address(uint8_t *mac); * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData); -/****************************************************************************** +/**************************************************************************** * Name: nvmem_read_sp_version * * Description: @@ -207,13 +207,13 @@ uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER uint8_t nvmem_read_sp_version(uint8_t *patchVer); #endif -/****************************************************************************** +/**************************************************************************** * Name: nvmem_create_entry * * Description: @@ -233,7 +233,7 @@ uint8_t nvmem_read_sp_version(uint8_t *patchVer); * Returned Value: * On success 0, error otherwise. * - *****************************************************************************/ + ****************************************************************************/ signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen); diff --git a/include/nuttx/wireless/cc3000/security.h b/include/nuttx/wireless/cc3000/security.h deleted file mode 100644 index c3ed8f40e777cda04ee8827155c1e56bfbc6cfd8..0000000000000000000000000000000000000000 --- a/include/nuttx/wireless/cc3000/security.h +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************** - * security.h - CC3000 Host Driver Implementation. - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 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. - * - * Neither the name of Texas Instruments Incorporated 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 _INCLUDE_NUTTX_WIRELESS_CC3000_SECURITY_H -#define _INCLUDE_NUTTX_WIRELESS_CC3000_SECURITY_H - -/***************************************************************************** - * Included Files - *****************************************************************************/ - -#include "nvmem.h" - -/***************************************************************************** - * Pre-processor Definitions - *****************************************************************************/ - -#define AES128_KEY_SIZE 16 - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - -/***************************************************************************** - * Public Data - *****************************************************************************/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** - * Public Function Prototypes -/***************************************************************************** - -/***************************************************************************** - * Name: aes_encrypt - * - * Description: - * AES128 encryption: Given AES128 key and 16 bytes plain text, cipher - * text of 16 bytes is computed. The AES implementation is in mode ECB - * (Electronic Code Book). - * - * Input Parameters: - * key AES128 key of size 16 bytes - * state 16 bytes of plain text and cipher text - * - * Returned Value - * None - * - *****************************************************************************/ - -void aes_encrypt(uint8_t *state, uint8_t *key); - -/***************************************************************************** - * Name: aes_decrypt - * - * Description: - * AES128 decryption: Given AES128 key and 16 bytes cipher text, plain - * text of 16 bytes is computed The AES implementation is in mode ECB - * (Electronic Code Book). - * - * Input Parameters: - * key AES128 key of size 16 bytes - * state 16 bytes of plain text and cipher text - * - * Returned Value - * None - * - *****************************************************************************/ - -void aes_decrypt(uint8_t *state, uint8_t *key); - -/***************************************************************************** - * Name: aes_read_key - * - * Description: - * Reads AES128 key from EEPROM. Reads the AES128 key from fileID #12 in - * EEPROM returns an error if the key does not exist. - * - * Input Parameters: - * key AES128 key of size 16 bytes - * - * Returned Value - * On success 0, error otherwise. - * - *****************************************************************************/ - -signed long aes_read_key(uint8_t *key); - -/***************************************************************************** - * Name: aes_write_key - * - * Description: - * Writes AES128 key from EEPROM Writes the AES128 key to fileID #12 in - * EEPROM - * - * Input Parameters: - * key AES128 key of size 16 bytes - * - * Returned Value - * On success 0, error otherwise. - * - *****************************************************************************/ - -signed long aes_write_key(uint8_t *key); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CC3000_UNENCRYPTED_SMART_CONFIG */ -#endif /* _INCLUDE_NUTTX_WIRELESS_CC3000_SECURITY_H */ diff --git a/include/nuttx/wireless/cc3000/wlan.h b/include/nuttx/wireless/cc3000/wlan.h index e41724a46ed6aa5da9f5b104894acdd931c5a724..b0a07c67d83813a5b5244f7dada0ebec330de5ac 100644 --- a/include/nuttx/wireless/cc3000/wlan.h +++ b/include/nuttx/wireless/cc3000/wlan.h @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * include/nuttx/wireless/cc3000/wlan.h * * wlan.h - CC3000 Host Driver Implementation. @@ -32,40 +32,40 @@ * (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 __INCLUDE_NUTTX_WIRELESS_CC3000_WLAN_H #define __INCLUDE_NUTTX_WIRELESS_CC3000_WLAN_H -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include "cc3000_common.h" -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ #define WLAN_SEC_UNSEC (0) #define WLAN_SEC_WEP (1) #define WLAN_SEC_WPA (2) #define WLAN_SEC_WPA2 (3) -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/***************************************************************************** +/**************************************************************************** * Public Function Prototypes - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: wlan_init * * Input Parameters: @@ -109,14 +109,14 @@ extern "C" * * WARNING: This function must be called before ANY other wlan driver function * - *****************************************************************************/ + ****************************************************************************/ void wlan_init(size_t max_tx_len, tWlanCB sWlanCB, tFWPatches sFWPatches, tDriverPatches sDriverPatches, tBootLoaderPatches sBootLoaderPatches); -/***************************************************************************** +/**************************************************************************** * Name: wlan_start * * Input Parameters: @@ -141,11 +141,11 @@ void wlan_init(size_t max_tx_len, * WARNING: This function must be called after wlan_init and before any * other wlan API * - *****************************************************************************/ + ****************************************************************************/ void wlan_start(uint16_t usPatchesAvailableAtHost); -/***************************************************************************** +/**************************************************************************** * Name: wlan_stop * * Input Parameters: @@ -157,11 +157,11 @@ void wlan_start(uint16_t usPatchesAvailableAtHost); * Description: * Stop WLAN device by putting it into reset state. * - *****************************************************************************/ + ****************************************************************************/ void wlan_stop(void); -/***************************************************************************** +/**************************************************************************** * Name: wlan_connect * * Input Parameters: @@ -191,16 +191,17 @@ void wlan_stop(void); * type WEP, please confirm that the key is set as ASCII and not * as HEX. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CC3000_TINY_DRIVER -long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, - uint8_t *bssid, uint8_t *key, long key_len); +long wlan_connect(unsigned long ulSecType, FAR const char *ssid, + long ssid_len, FAR const uint8_t *bssid, + FAR const uint8_t *key, long key_len); #else -long wlan_connect(char *ssid, long ssid_len); +long wlan_connect(FAR const char *ssid, long ssid_len); #endif -/***************************************************************************** +/**************************************************************************** * Name: wlan_disconnect * * Input Parameters: @@ -212,11 +213,11 @@ long wlan_connect(char *ssid, long ssid_len); * Description: * Disconnect connection from AP. * - *****************************************************************************/ + ****************************************************************************/ long wlan_disconnect(void); -/***************************************************************************** +/**************************************************************************** * Name: wlan_add_profile * * Input Parameters: @@ -242,7 +243,7 @@ long wlan_disconnect(void); * profile based on security policy, signal strength, etc * parameters. All the profiles are stored in CC3000 NVMEM. * - *****************************************************************************/ + ****************************************************************************/ long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, unsigned long ulSsidLen, uint8_t *ucBssid, @@ -252,7 +253,7 @@ long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, unsigned long ulKeyMgmt, uint8_t* ucPf_OrKey, unsigned long ulPassPhraseLen); -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_del_profile * * Input Parameters: @@ -266,11 +267,11 @@ long wlan_add_profile(unsigned long ulSecType, uint8_t* ucSsid, * * @Note In order to delete all stored profile, set index to 255. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_del_profile(unsigned long ulIndex); -/***************************************************************************** +/**************************************************************************** * Name: wlan_set_event_mask * * Input Parameters: @@ -292,11 +293,11 @@ long wlan_ioctl_del_profile(unsigned long ulIndex); * Mask event according to bit mask. In case that event is * masked (1), the device will not send the masked event to host. * - *****************************************************************************/ + ****************************************************************************/ long wlan_set_event_mask(unsigned long ulMask); -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_statusget * * Input Parameters: @@ -309,11 +310,11 @@ long wlan_set_event_mask(unsigned long ulMask); * Description: * get wlan status: disconnected, scanning, connecting or connected * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_statusget(void); -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_set_connection_policy * * Input Parameters: @@ -343,13 +344,13 @@ long wlan_ioctl_statusget(void); * enabled, the device will try to connect to any AP. * * Note that the policy settings are stored in the CC3000 NVMEM. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, unsigned long ulUseProfiles); -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_get_scan_results * * Input Parameters: @@ -380,11 +381,11 @@ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, * * NOTE: scan_timeout, is not supported on this version. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults); -/***************************************************************************** +/**************************************************************************** * Name: wlan_ioctl_set_scan_params * * Input Parameters: @@ -419,7 +420,7 @@ long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, uint8_t *ucResults * * @Note uiDefaultTxPower, is not supported on this version. * - *****************************************************************************/ + ****************************************************************************/ long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime, @@ -430,7 +431,7 @@ long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiDefaultTxPower, unsigned long *aiIntervalList); -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_start * * Input Parameters: @@ -449,11 +450,11 @@ long wlan_ioctl_set_scan_params(unsigned long uiEnable, * @Note An asynchronous event - Smart Config Done will be generated as soon * as the process finishes successfully. * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_start(unsigned long algoEncryptedFlag); -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_stop * * Input Parameters: @@ -465,11 +466,11 @@ long wlan_smart_config_start(unsigned long algoEncryptedFlag); * Description: * Stop the acquire profile procedure * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_stop(void); -/***************************************************************************** +/**************************************************************************** * Name: wlan_smart_config_set_prefix * * Input Parameters: @@ -484,11 +485,45 @@ long wlan_smart_config_stop(void); * * @Note The prefix is stored in CC3000 NVMEM * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_set_prefix(char* cNewPrefix); -/***************************************************************************** +/**************************************************************************** + * Name: aes_read_key + * + * Description: + * Reads AES128 key from EEPROM. Reads the AES128 key from fileID #12 in + * EEPROM returns an error if the key does not exist. + * + * Input Parameters: + * key AES128 key of size 16 bytes + * + * Returned Value + * On success 0, error otherwise. + * + ****************************************************************************/ + +signed long aes_read_key(FAR uint8_t *key); + +/**************************************************************************** + * Name: aes_write_key + * + * Description: + * Writes AES128 key from EEPROM Writes the AES128 key to fileID #12 in + * EEPROM + * + * Input Parameters: + * key AES128 key of size 16 bytes + * + * Returned Value + * On success 0, error otherwise. + * + ****************************************************************************/ + +signed long aes_write_key(FAR uint8_t *key); + +/**************************************************************************** * Name: wlan_smart_config_process * * Input Parameters: @@ -503,7 +538,7 @@ long wlan_smart_config_set_prefix(char* cNewPrefix); * The encrypted data is decrypted and stored as a profile. * behavior is as defined by connection policy. * - *****************************************************************************/ + ****************************************************************************/ long wlan_smart_config_process(void); diff --git a/include/nuttx/wireless/ieee802154/ieee802154.h b/include/nuttx/wireless/ieee802154/ieee802154.h new file mode 100644 index 0000000000000000000000000000000000000000..0211940414584a0eab8ac538fc571bdca71cc525 --- /dev/null +++ b/include/nuttx/wireless/ieee802154/ieee802154.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * include/nuttx/net/ieee802154.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Includes some definitions that a compatible with the LGPL GNU C Library + * header file of the same name. + * + * 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 __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H +#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H */ diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h new file mode 100644 index 0000000000000000000000000000000000000000..c3439feb897a0c4975fe32b0734c793e5df88819 --- /dev/null +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -0,0 +1,224 @@ +/**************************************************************************** + * include/nuttx/wireless/ieee802154/ieee802154_radio.h + * + * Copyright (C) 2014-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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 __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H +#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* None at the moment */ + +/* IEEE 802.15.4 MAC Interface **********************************************/ + +/* Frame control field masks, 2 bytes + * Seee IEEE 802.15.4/2003 7.2.1.1 page 112 + */ + +#define IEEE802154_FC1_FTYPE 0x03 /* Frame type, bits 0-2 */ +#define IEEE802154_FC1_SEC 0x08 /* Security Enabled, bit 3 */ +#define IEEE802154_FC1_PEND 0x10 /* Frame pending, bit 4 */ +#define IEEE802154_FC1_ACKREQ 0x20 /* Acknowledge request, bit 5 */ +#define IEEE802154_FC1_INTRA 0x40 /* Intra PAN, bit 6 */ +#define IEEE802154_FC2_DADDR 0x0C /* Dest addressing mode, bits 10-11 */ +#define IEEE802154_FC2_VERSION 0x30 /* Source addressing mode, bits 12-13 */ +#define IEEE802154_FC2_SADDR 0xC0 /* Source addressing mode, bits 14-15 */ + +/* Frame Type */ + +#define IEEE802154_FRAME_BEACON 0x00 +#define IEEE802154_FRAME_DATA 0x01 +#define IEEE802154_FRAME_ACK 0x02 +#define IEEE802154_FRAME_COMMAND 0x03 + +/* Security Enabled */ + +#define IEEE802154_SEC_OFF 0x00 +#define IEEE802154_SEC_ON 0x08 + +/* Flags */ + +#define IEEE802154_PEND 0x10 +#define IEEE802154_ACK_REQ 0x20 +#define IEEE802154_INTRA 0x40 + +/* Dest Addressing modes */ + +#define IEEE802154_DADDR_NONE 0x00 +#define IEEE802154_DADDR_SHORT 0x08 +#define IEEE802154_DADDR_EXT 0x0A + +/* Src Addressing modes */ + +#define IEEE802154_SADDR_NONE 0x00 +#define IEEE802154_SADDR_SHORT 0x80 +#define IEEE802154_SADDR_EXT 0xA0 + +/* Some addresses */ + +#define IEEE802154_PAN_DEFAULT (uint16_t)0xFFFF +#define IEEE802154_SADDR_UNSPEC (uint16_t)0xFFFF +#define IEEE802154_SADDR_BCAST (uint16_t)0xFFFE +#define IEEE802154_EADDR_UNSPEC (uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff" + +#define IEEE802154_CMD_ASSOC_REQ 0x01 +#define IEEE802154_CMD_ASSOC_RSP 0x02 +#define IEEE802154_CMD_DIS_NOT 0x03 +#define IEEE802154_CMD_DATA_REQ 0x04 +#define IEEE802154_CMD_PANID_CONF_NOT 0x05 +#define IEEE802154_CMD_ORPHAN_NOT 0x06 +#define IEEE802154_CMD_BEACON_REQ 0x07 +#define IEEE802154_CMD_COORD_REALIGN 0x08 +#define IEEE802154_CMD_GTS_REQ 0x09 + +/* Device modes */ + +#define IEEE802154_MODE_DEVICE 0x00 +#define IEEE802154_MODE_COORD 0x01 /* avail in mrf24j40, but why? */ +#define IEEE802154_MODE_PANCOORD 0x02 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ieee802154_packet_s +{ + uint8_t len; + uint8_t data[127]; + uint8_t lqi; + uint8_t rssi; +}; + +struct ieee802154_cca_s +{ + uint8_t use_ed : 1; /* CCA using ED */ + uint8_t use_cs : 1; /* CCA using carrier sense */ + uint8_t edth; /* Energy detection threshold for CCA */ + uint8_t csth; /* Carrier sense threshold for CCA */ +}; + +struct ieee802154_dev_s; + +struct ieee802154_devops_s +{ + CODE int (*setchannel)(FAR struct ieee802154_dev_s *dev, uint8_t channel); + CODE int (*getchannel)(FAR struct ieee802154_dev_s *dev, + FAR uint8_t *channel); + + CODE int (*setpanid)(FAR struct ieee802154_dev_s *dev, uint16_t panid); + CODE int (*getpanid)(FAR struct ieee802154_dev_s *dev, + FAR uint16_t *panid); + + CODE int (*setsaddr)(FAR struct ieee802154_dev_s *dev, uint16_t saddr); + CODE int (*getsaddr)(FAR struct ieee802154_dev_s *dev, + FAR uint16_t *saddr); + + CODE int (*seteaddr)(FAR struct ieee802154_dev_s *dev, + FAR uint8_t *laddr); + CODE int (*geteaddr)(FAR struct ieee802154_dev_s *dev, + FAR uint8_t *laddr); + + CODE int (*setpromisc)(FAR struct ieee802154_dev_s *dev, bool promisc); + CODE int (*getpromisc)(FAR struct ieee802154_dev_s *dev, + FAR bool *promisc); + + CODE int (*setdevmode)(FAR struct ieee802154_dev_s *dev, uint8_t devmode); + CODE int (*getdevmode)(FAR struct ieee802154_dev_s *dev, + FAR uint8_t *devmode); + + CODE int (*settxpower)(FAR struct ieee802154_dev_s *dev, + int32_t txpwr); /* unit = 1 mBm = 1/100 dBm */ + CODE int (*gettxpower)(FAR struct ieee802154_dev_s *dev, + FAR int32_t *txpwr); + + CODE int (*setcca)(FAR struct ieee802154_dev_s *dev, + FAR struct ieee802154_cca_s *cca); + CODE int (*getcca)(FAR struct ieee802154_dev_s *dev, + FAR struct ieee802154_cca_s *cca); + + CODE int (*ioctl)(FAR struct ieee802154_dev_s *ieee, int cmd, + unsigned long arg); + CODE int (*energydetect)(FAR struct ieee802154_dev_s *dev, + FAR uint8_t *energy); + CODE int (*rxenable)(FAR struct ieee802154_dev_s *dev, bool state, + FAR struct ieee802154_packet_s *packet); + CODE int (*transmit)(FAR struct ieee802154_dev_s *dev, + FAR struct ieee802154_packet_s *packet); + + /*TODO beacon/sf order*/ +}; + +struct ieee802154_dev_s +{ + FAR const struct ieee802154_devops_s *ops; + + /* Packet reception management */ + + struct ieee802154_packet_s *rxbuf; + sem_t rxsem; + + /* Packet transmission management */ + + sem_t txsem; +}; + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H */ diff --git a/include/nuttx/wireless/ieee802154/mrf24j40.h b/include/nuttx/wireless/ieee802154/mrf24j40.h new file mode 100644 index 0000000000000000000000000000000000000000..2c78faee01a3ec67925fe04aa916ad5d66c04e65 --- /dev/null +++ b/include/nuttx/wireless/ieee802154/mrf24j40.h @@ -0,0 +1,111 @@ +/**************************************************************************** + * include/nuttx/wireless/ieee802154/mrf24j40.h + * + * Copyright (C) 2014-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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 __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H +#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H + +/**************************************************************************** + * Included files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The MRF24J40 provides interrupts to the MCU via a GPIO pin. The + * following structure provides an MCU-independent mechanism for controlling + * the MRF24J40 GPIO interrupt. + * + * The MRF24J40 interrupt is an active low, *level* interrupt. From Datasheet: + * "Note 1: The INTEDGE polarity defaults to: + * 0 = Falling Edge. Ensure that the inter- + * rupt polarity matches the interrupt pin + * polarity of the host microcontroller. + * Note 2: The INT pin will remain high or low, + * depending on INTEDGE polarity setting, + * until INTSTAT register is read." + */ + +struct mrf24j40_lower_s +{ + int (*attach)(FAR const struct mrf24j40_lower_s *lower, xcpt_t handler); + void (*enable)(FAR const struct mrf24j40_lower_s *lower, int state); +}; + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Function: mrf24j40_init + * + * Description: + * Initialize the IEEE802.15.4 driver. The MRF24J40 device is assumed to be + * in the post-reset state upon entry to this function. + * + * Parameters: + * spi - A reference to the platform's SPI driver for the MRF24J40 + * lower - The MCU-specific interrupt used to control low-level MCU + * functions (i.e., MRF24J40 GPIO interrupts). + * devno - If more than one MRF24J40 is supported, then this is the + * zero based number that identifies the MRF24J40; + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ +FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi, + FAR const struct mrf24j40_lower_s *lower); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H */ diff --git a/include/nuttx/wireless/pn532.h b/include/nuttx/wireless/pn532.h new file mode 100644 index 0000000000000000000000000000000000000000..450b7c7ba3edc250ba8b1f07b0324e73ed3fa4c2 --- /dev/null +++ b/include/nuttx/wireless/pn532.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * include/wireless/pn532.h + * + * Copyright(C) 2012, 2013, 2016 Offcode Ltd. All rights reserved. + * Authors: Janne Rosberg + * Teemu Pirinen + * Juho Grundstrĥm + * + * 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 __NUTTX_WIRELESS_PN532_H +#define __NUTTX_WIRELESS_PN532_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define PN532_MIFARE_ISO14443A (0x00) + +/* IOCTL Commands ***********************************************************/ + +#define PN532IOC_SET_SAM_CONF _WLIOC_USER(0x0001) +#define PN532IOC_READ_PASSIVE _WLIOC_USER(0x0002) +#define PN532IOC_SET_RF_CONF _WLIOC_USER(0x0003) +#define PN532IOC_SEND_CMD_READ_PASSIVE _WLIOC_USER(0x0004) +#define PN532IOC_GET_DATA_READY _WLIOC_USER(0x0005) +#define PN532IOC_GET_TAG_ID _WLIOC_USER(0x0006) +#define PN532IOC_GET_STATE _WLIOC_USER(0x0007) +#define PN532IOC_READ_TAG_DATA _WLIOC_USER(0x0008) +#define PN532IOC_WRITE_TAG_DATA _WLIOC_USER(0x0009) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum pn532_state_E +{ + PN532_STATE_NOT_INIT, + PN532_STATE_IDLE, + PN532_STATE_CMD_SENT, + PN532_STATE_DATA_READY, +}; + +struct pn532_dev_s; +struct pn532_config_s +{ + int (*reset)(uint8_t enable); + + /* External CS, if NULL then SPIDEV_WIRELESS CS is used */ + + int (*select)(struct pn532_dev_s *dev, bool sel); + int (*irqattach)(void* dev, xcpt_t isr); +}; + +enum PN_SAM_MODE +{ + PN_SAM_NORMAL_MODE = 0x01, + PN_SAM_VIRTUAL_CARD, + PN_SAM_WIRED_CARD, + SAM_DUAL_CARD +}; + +struct pn_sam_settings_s +{ + enum PN_SAM_MODE mode; /* Mode */ + uint8_t timeout; /* Timeout: LSB=50ms 0x14*50ms = 1sec */ + uint8_t irq_en; /* If 1 - enable P-70, IRQ */ +}; + +enum PN_RF_CONFIG_ITEM +{ + PN_RF_CONFIG_RF_FIELD = 0x01, + PN_RF_CONFIG_VARIOUS_TIMINGS = 0x02, + + PN_RF_CONFIG_ITEM_ANALOG_106A = 0x0A, + PN_RF_CONFIG_ITEM_ANALOG_212 = 0x0B, +}; + +struct pn_rf_config_s +{ + uint8_t cfg_item; /* Item */ + uint8_t data_size; /* number of config items */ + uint8_t config[11]; /* Item config data */ +}; + +struct pn_mifare_tag_data_s +{ + uint32_t data; + uint8_t address; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: pn532_register + * + * Description: + * Register the PN532 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/nfc0" + * spi - An instance of the SPI interface to use to communicate with PN532 + * config - Device persistent board data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pn532_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + FAR struct pn532_config_s *config); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __NUTTX_WIRELESS_PN532_H */ diff --git a/include/nuttx/wireless/wireless.h b/include/nuttx/wireless/wireless.h index 67146c7416f97bb48fc822aeb8690df70ac9789b..fd87265228dad81dc4085de1754c2b701c30aca0 100644 --- a/include/nuttx/wireless/wireless.h +++ b/include/nuttx/wireless/wireless.h @@ -47,7 +47,7 @@ #include #include -#ifdef CONFIG_WIRELESS +#ifdef CONFIG_DRIVERS_WIRELESS /************************************************************************************ * Pre-processor Definitions diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h index a194783978bbdfcdbc1c172cfd89ca81ae193aa9..59fa8f0a9202b74bcec5894d9786ce13c6306f25 100644 --- a/include/nuttx/wqueue.h +++ b/include/nuttx/wqueue.h @@ -47,6 +47,8 @@ #include #include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -290,8 +292,8 @@ struct work_s struct dq_entry_s dq; /* Implements a doubly linked list */ worker_t worker; /* Work callback */ FAR void *arg; /* Callback argument */ - uint32_t qtime; /* Time work queued */ - uint32_t delay; /* Delay until work performed */ + systime_t qtime; /* Time work queued */ + systime_t delay; /* Delay until work performed */ }; /**************************************************************************** @@ -359,7 +361,7 @@ int work_usrstart(void); ****************************************************************************/ int work_queue(int qid, FAR struct work_s *work, worker_t worker, - FAR void *arg, uint32_t delay); + FAR void *arg, systime_t delay); /**************************************************************************** * Name: work_cancel diff --git a/include/poll.h b/include/poll.h index 3c47ca19831dd4f595060821a848e037177e16d2..859163af39589a493858e5f9b76e049aa45e5c9f 100644 --- a/include/poll.h +++ b/include/poll.h @@ -115,7 +115,7 @@ struct pollfd }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN diff --git a/include/pthread.h b/include/pthread.h index 4de07d62a2254d1f3ea90308866f5b8c4a176560..b2ebffda45bec72cb786da09507437f309a8e40c 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -1,7 +1,7 @@ /******************************************************************************** * include/pthread.h * - * Copyright (C) 2007-2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ #include /* C99 boolean types */ #include /* For getpid */ #include /* Needed for sem_t */ -#include /* Needed for sigset_t */ +#include /* Needed for sigset_t, includes this file */ #include /* Needed for struct timespec */ /******************************************************************************** @@ -158,8 +158,11 @@ extern "C" /* pthread-specific types */ -typedef int pthread_key_t; -typedef FAR void *pthread_addr_t; +typedef int pthread_key_t; +#define __PTHREAD_KEY_T_DEFINED 1 + +typedef FAR void *pthread_addr_t; +#define __PTHREAD_ADDR_T_DEFINED 1 typedef pthread_addr_t (*pthread_startroutine_t)(pthread_addr_t); typedef pthread_startroutine_t pthread_func_t; @@ -175,6 +178,10 @@ struct pthread_attr_s uint8_t max_repl; /* Maximum pending replenishments */ #endif +#ifdef CONFIG_SMP + cpu_set_t affinity; /* Set of permitted CPUs for the thread */ +#endif + size_t stacksize; /* Size of the stack allocated for the pthread */ #ifdef CONFIG_SCHED_SPORADIC @@ -182,17 +189,24 @@ struct pthread_attr_s struct timespec budget; /* Initial budget */ #endif }; + typedef struct pthread_attr_s pthread_attr_t; +#define __PTHREAD_ATTR_T_DEFINED 1 typedef pid_t pthread_t; +#define __PTHREAD_T_DEFINED 1 typedef int pthread_condattr_t; +#define __PTHREAD_CONDATTR_T_DEFINED 1 struct pthread_cond_s { sem_t sem; }; + typedef struct pthread_cond_s pthread_cond_t; +#define __PTHREAD_COND_T_DEFINED 1 + #define PTHREAD_COND_INITIALIZER {SEM_INITIALIZER(0)} struct pthread_mutexattr_s @@ -202,7 +216,9 @@ struct pthread_mutexattr_s uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ #endif }; + typedef struct pthread_mutexattr_s pthread_mutexattr_t; +#define __PTHREAD_MUTEXATTR_T_DEFINED 1 struct pthread_mutex_s { @@ -213,7 +229,9 @@ struct pthread_mutex_s int nlocks; /* The number of recursive locks held */ #endif }; + typedef struct pthread_mutex_s pthread_mutex_t; +#define __PTHREAD_MUTEX_T_DEFINED 1 #ifdef CONFIG_MUTEX_TYPES # define PTHREAD_MUTEX_INITIALIZER {-1, SEM_INITIALIZER(1), PTHREAD_MUTEX_DEFAULT, 0} @@ -225,25 +243,26 @@ struct pthread_barrierattr_s { int pshared; }; + typedef struct pthread_barrierattr_s pthread_barrierattr_t; +#define __PTHREAD_BARRIERATTR_T_DEFINED 1 struct pthread_barrier_s { sem_t sem; unsigned int count; }; + typedef struct pthread_barrier_s pthread_barrier_t; +#define __PTHREAD_BARRIER_T_DEFINED 1 typedef bool pthread_once_t; +#define __PTHREAD_ONCE_T_DEFINED 1 -/* Forware references */ +/* Forward references */ struct sched_param; /* Defined in sched.h */ -/******************************************************************************** - * Public Data - ********************************************************************************/ - /******************************************************************************** * Public Function Prototypes ********************************************************************************/ @@ -271,6 +290,16 @@ int pthread_attr_setinheritsched(FAR pthread_attr_t *attr, int pthread_attr_getinheritsched(FAR const pthread_attr_t *attr, FAR int *inheritsched); +#ifdef CONFIG_SMP +/* Set or obtain thread affinity attributes */ + +int pthread_attr_setaffinity_np(FAR pthread_attr_t *attr, + size_t cpusetsize, + FAR const cpu_set_t *cpuset); +int pthread_attr_getaffinity_np(FAR const pthread_attr_t *attr, + size_t cpusetsize, cpu_set_t *cpuset); +#endif + /* Set or obtain the default stack size */ int pthread_attr_setstacksize(FAR pthread_attr_t *attr, long stacksize); @@ -327,6 +356,15 @@ int pthread_setschedparam(pthread_t thread, int policy, FAR const struct sched_param *param); int pthread_setschedprio(pthread_t thread, int prio); +#ifdef CONFIG_SMP +/* Thread affinity */ + +int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, + FAR const cpu_set_t *cpuset); +int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, + FAR cpu_set_t *cpuset); +#endif + /* Thread-specific Data Interfaces */ int pthread_key_create(FAR pthread_key_t *key, @@ -413,4 +451,78 @@ int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); } #endif +/******************************************************************************** + * Minimal Type Definitions + ********************************************************************************/ + +#else /* __INCLUDE_PTHREAD_H */ + +#include +#include + +/* Avoid circular dependencies by assuring that simple type definitions are + * available in any inclusion ordering. + */ + +#ifndef __PTHREAD_KEY_T_DEFINED +typedef int pthread_key_t; +# define __PTHREAD_KEY_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_ADDR_T_DEFINED +typedef FAR void *pthread_addr_t; +# define __PTHREAD_ADDR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_ATTR_T_DEFINED +struct pthread_attr_s; +typedef struct pthread_attr_s pthread_attr_t; +# define __PTHREAD_ATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_T_DEFINED +typedef pid_t pthread_t; +# define __PTHREAD_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_CONDATTR_T_DEFINED +typedef int pthread_condattr_t; +# define __PTHREAD_CONDATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_COND_T_DEFINED +struct pthread_cond_s; +typedef struct pthread_cond_s pthread_cond_t; +# define __PTHREAD_COND_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEXATTR_T_DEFINED +struct pthread_mutexattr_s; +typedef struct pthread_mutexattr_s pthread_mutexattr_t; +# define __PTHREAD_MUTEXATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEX_T_DEFINED +struct pthread_mutex_s; +typedef struct pthread_mutex_s pthread_mutex_t; +# define __PTHREAD_MUTEX_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_BARRIERATTR_T_DEFINED +struct pthread_barrierattr_s; +typedef struct pthread_barrierattr_s pthread_barrierattr_t; +# define __PTHREAD_BARRIERATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_BARRIER_T_DEFINED +struct pthread_barrier_s; +typedef struct pthread_barrier_s pthread_barrier_t; +# define __PTHREAD_BARRIER_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_ONCE_T_DEFINED +typedef bool pthread_once_t; +# define __PTHREAD_ONCE_T_DEFINED 1 +#endif + #endif /* __INCLUDE_PTHREAD_H */ diff --git a/include/sched.h b/include/sched.h index 4fe16542d60f802e965985278c18f6bda9a01f6e..b9a21f0f6f07d0a7a244c1d276b28a1456394907 100644 --- a/include/sched.h +++ b/include/sched.h @@ -66,6 +66,115 @@ #define PTHREAD_KEYS_MAX CONFIG_NPTHREAD_KEYS +/* CPU affinity mask helpers ***************************************************/ +/* These are not standard but are defined for Linux compatibility */ + +#ifdef CONFIG_SMP + +/* void CPU_ZERO(FAR cpu_set_t *set); */ + +# define CPU_ZERO(s) do { *(s) = 0; } while (0) + +/* void CPU_SET(int cpu, FAR cpu_set_t *set); */ + +# define CPU_SET(c,s) do { *(s) |= (1 << (c)); } while (0) + +/* void CPU_CLR(int cpu, FAR cpu_set_t *set); */ + +# define CPU_CLR(c,s) do { *(s) &= ~(1 << (c)); } while (0) + +/* int CPU_ISSET(int cpu, FAR const cpu_set_t *set); */ + +# define CPU_ISSET(c,s) ((*(s) & (1 << (c))) != 0) + +/* int CPU_COUNT(FAR const cpu_set_t *set); */ + +# define CPU_COUNT(s) sched_cpu_count(s) + +/* void CPU_AND(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_AND(d,s1,s2) do { *(d) = *(s1) & *(s2); } while (0) + +/* void CPU_OR(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_OR(d,s1,s2) do { *(d) = *(s1) | *(s2); } while (0) + +/* void CPU_XOR(FAR cpu_set_t *destset, FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_XOR(d,s1,s2) do { *(d) = *(s1) ^ *(s2); } while (0) + +/* int CPU_EQUAL(FAR const cpu_set_t *set1, FAR const cpu_set_t *set2); */ + +# define CPU_EQUAL(s1,s2) (*(s2) == *(s2)) + +/* REVISIT: Variably sized CPU sets are not supported */ +/* FAR cpu_set_t *CPU_ALLOC(int num_cpus); */ + +# define CPU_ALLOC(n) (FAR cpu_set_t *)malloc(sizeof(cpu_set_t)); + +/* void CPU_FREE(cpu_set_t *set); */ + +# define CPU_ALLOC(s) free(s) + +/* size_t CPU_ALLOC_SIZE(int num_cpus); */ + +# define CPU_ALLOC_SIZE(n) sizeof(cpu_set_t) + +/* void CPU_ZERO_S(size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_ZERO_S(n,s) CPU_ZERO_S(s) + +/* void CPU_SET_S(int cpu, size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_SET_S(c,n,s) CPU_SET(c,s) + +/* void CPU_CLR_S(int cpu, size_t setsize, FAR cpu_set_t *set); */ + +# define CPU_CLR_S(c,n,s) CPU_CLR(c,s) + +/* int CPU_ISSET_S(int cpu, size_t setsize, FAR const cpu_set_t *set); */ + +# define CPU_ISSET_S(c,n,s) CPU_ISSET(c,s) + +/* int CPU_COUNT_S(size_t setsize, FAR const cpu_set_t *set); */ + +# define CPU_COUNT_S(n,s) CPU_COUNT(s) + +/* void CPU_AND_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_AND_S(n,d,s1,s2) CPU_AND(d,s1,s2) + +/* void CPU_OR_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_OR_S(n,d,s1,s2) CPU_OR(d,s1,s2) + +/* void CPU_XOR_S(size_t setsize, FAR cpu_set_t *destset, + * FAR const cpu_set_t *srcset1, + * FAR const cpu_set_t *srcset2); + */ + +# define CPU_XOR_S(n,d,s1,s2) CPU_XOR(d,s1,s2) + +/* int CPU_EQUAL_S(size_t setsize, FAR const cpu_set_t *set1, + * FAR const cpu_set_t *set2); + */ + +# define CPU_EQUAL_S(n,s1,s2) CPU_EQUAL(s1,s2) + +#endif /* CONFIG_SMP */ + /******************************************************************************** * Public Type Definitions ********************************************************************************/ @@ -131,29 +240,21 @@ int sched_get_priority_max(int policy); int sched_get_priority_min(int policy); int sched_rr_get_interval(pid_t pid, FAR struct timespec *interval); +#ifdef CONFIG_SMP +/* Task affinity */ + +int sched_setaffinity(pid_t pid, size_t cpusetsize, + FAR const cpu_set_t *mask); +int sched_getaffinity(pid_t pid, size_t cpusetsize, FAR cpu_set_t *mask); +int sched_cpu_count(FAR const cpu_set_t *set); +#endif /* CONFIG_SMP */ + /* Task Switching Interfaces (non-standard) */ int sched_lock(void); int sched_unlock(void); int sched_lockcount(void); -/* If instrumentation of the scheduler is enabled, then some outboard logic - * must provide the following interfaces. - */ - -#ifdef CONFIG_SCHED_INSTRUMENTATION - -void sched_note_start(FAR struct tcb_s *tcb); -void sched_note_stop(FAR struct tcb_s *tcb); -void sched_note_switch(FAR struct tcb_s *pFromTcb, - FAR struct tcb_s *pToTcb); - -#else -# define sched_note_start(t) -# define sched_note_stop(t) -# define sched_note_switch(t1, t2) -#endif /* CONFIG_SCHED_INSTRUMENTATION */ - #undef EXTERN #if defined(__cplusplus) } diff --git a/include/semaphore.h b/include/semaphore.h index 5818f0fb7e0f48c5530c2c8c47f3a43029e18fd9..142ef51ada64adb675fb31cdee778468d56552f4 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -85,7 +85,7 @@ struct semholder_s struct sem_s { - int16_t semcount; /* >0 -> Num counts available */ + volatile int16_t semcount; /* >0 -> Num counts available */ /* <0 -> Num tasks waiting for semaphore */ /* If priority inheritance is enabled, then we have to keep track of which * tasks hold references to the semaphore. @@ -115,7 +115,7 @@ typedef struct sem_s sem_t; #endif /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/include/signal.h b/include/signal.h index 30f97ef687d056a2d0d990eb8b44b6c9d36f3cd0..57c5742d838a211421731f1bf10b573561e39d8c 100644 --- a/include/signal.h +++ b/include/signal.h @@ -46,6 +46,10 @@ #include #include +#ifdef CONFIG_SIG_EVTHREAD +# include /* Needed for pthread_attr_t, includes this file */ +#endif + /******************************************************************************** * Pre-processor Definitions ********************************************************************************/ @@ -162,8 +166,11 @@ /* Values for the sigev_notify field of struct sigevent */ -#define SIGEV_NONE 0 /* No notification desired */ -#define SIGEV_SIGNAL 1 /* Notify via signal */ +#define SIGEV_NONE 0 /* No asynchronous notification is delivered */ +#define SIGEV_SIGNAL 1 /* Notify via signal,with an application-defined value */ +#ifdef CONFIG_SIG_EVTHREAD +# define SIGEV_THREAD 3 /* A notification function is called */ +#endif /* Special values of of sa_handler used by sigaction and sigset. They are all * treated like NULL for now. This is okay for SIG_DFL and SIG_IGN because @@ -189,6 +196,7 @@ /* This defines a set of 32 signals (numbered 0 through 31). */ typedef uint32_t sigset_t; /* Bit set of 32 signals */ +#define __SIGSET_T_DEFINED 1 /* This defines the type of the siginfo si_value field */ @@ -203,11 +211,22 @@ union sigval * available on a queue */ +#ifdef CONFIG_CAN_PASS_STRUCTS +typedef CODE void (*sigev_notify_function_t)(union sigval value); +#else +typedef CODE void (*sigev_notify_function_t)(FAR void *sival_ptr); +#endif + struct sigevent { - uint8_t sigev_notify; /* Notification method: SIGEV_SIGNAL or SIGEV_NONE */ + uint8_t sigev_notify; /* Notification method: SIGEV_SIGNAL, SIGEV_NONE, or SIGEV_THREAD */ uint8_t sigev_signo; /* Notification signal */ union sigval sigev_value; /* Data passed with notification */ + +#ifdef CONFIG_SIG_EVTHREAD + sigev_notify_function_t sigev_notify_function; /* Notification function */ + FAR pthread_attr_t *sigev_notify_attributes; /* Notification attributes (not used) */ +#endif }; /* The following types is used to pass parameters to/from signal handlers */ @@ -216,6 +235,7 @@ struct siginfo { uint8_t si_signo; /* Identifies signal */ uint8_t si_code; /* Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ */ + uint8_t si_errno; /* Zero or errno value associated with signal */ union sigval si_value; /* Data passed with signal */ #ifdef CONFIG_SCHED_HAVE_PARENT pid_t si_pid; /* Sending task ID */ @@ -224,6 +244,7 @@ struct siginfo }; typedef struct siginfo siginfo_t; +#define __SIGINFO_T_DEFINED 1 /* Non-standard convenience definition of signal handling function types. * These should be used only internally within the NuttX signal logic. @@ -250,10 +271,6 @@ struct sigaction #define sa_handler sa_u._sa_handler #define sa_sigaction sa_u._sa_sigaction -/******************************************************************************** - * Public Data - ********************************************************************************/ - /******************************************************************************** * Public Function Prototypes ********************************************************************************/ @@ -296,4 +313,27 @@ int sigqueue(int pid, int signo, FAR void *sival_ptr); } #endif +/******************************************************************************** + * Minimal Type Definitions + ********************************************************************************/ + +#else /* __INCLUDE_SIGNAL_H */ + +#include + +/* Avoid circular dependencies by assuring that simple type definitions are + * available in any inclusion ordering. + */ + +#ifndef __SIGSET_T_DEFINED +typedef uint32_t sigset_t; +# define __SIGSET_T_DEFINED 1 +#endif + +#ifndef __SIGINFO_T_DEFINED +struct siginfo; +typedef struct siginfo siginfo_t; +# define __SIGINFO_T_DEFINED 1 +#endif + #endif /* __INCLUDE_SIGNAL_H */ diff --git a/include/stddef.h b/include/stddef.h index ecc5eb94ce1efe00b6b1861f32735ee921edd53f..2b59c58a3d2a64faf2f9ebf072ae30ff53df8e09 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -65,7 +65,7 @@ * Reference: Opengroup.org */ -#define offsetof(a,b) ((size_t)(&(((a *)(0))->b))) +#define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) /**************************************************************************** * Type Definitions diff --git a/include/stdio.h b/include/stdio.h index 13e99eb4a93c74d612c140facf244b8463d34540..20994e22ffdcc9ccae542d7f0c2921ce80c0d36f 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/stdio.h * - * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -58,7 +58,13 @@ #define FILENAME_MAX _POSIX_NAME_MAX -/* File system error values *************************************************/ +/* The size of the I/O buffers */ + +#if CONFIG_STDIO_BUFFER_SIZE > 0 +# define BUFSIZ CONFIG_STDIO_BUFFER_SIZE +#endif + +/* File system error values */ #define EOF (-1) @@ -94,7 +100,7 @@ #define L_tmpnam CONFIG_LIBC_MAX_TMPFILE -/* the maximum number of unique temporary file names that can be generated */ +/* The maximum number of unique temporary file names that can be generated */ #define TMP_MAX 56800235584ull @@ -107,7 +113,7 @@ typedef struct file_struct FILE; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -137,34 +143,40 @@ int fgetc(FAR FILE *stream); int fgetpos(FAR FILE *stream, FAR fpos_t *pos); char *fgets(FAR char *s, int n, FAR FILE *stream); FAR FILE *fopen(FAR const char *path, FAR const char *type); -int fprintf(FAR FILE *stream, FAR const char *format, ...); +int fprintf(FAR FILE *stream, FAR const IPTR char *format, ...); int fputc(int c, FAR FILE *stream); int fputs(FAR const char *s, FAR FILE *stream); size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream); +FAR FILE *freopen(FAR const char *path, FAR const char *mode, + FAR FILE *stream); int fseek(FAR FILE *stream, long int offset, int whence); int fsetpos(FAR FILE *stream, FAR fpos_t *pos); long ftell(FAR FILE *stream); -size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, FAR FILE *stream); +size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, + FAR FILE *stream); FAR char *gets(FAR char *s); FAR char *gets_s(FAR char *s, rsize_t n); int ungetc(int c, FAR FILE *stream); /* Operations on the stdout stream, buffers, paths, and the whole printf-family */ -int printf(FAR const char *format, ...); +int printf(FAR const IPTR char *format, ...); int puts(FAR const char *s); int rename(FAR const char *oldpath, FAR const char *newpath); -int sprintf(FAR char *buf, FAR const char *format, ...); -int asprintf (FAR char **ptr, FAR const char *fmt, ...); -int snprintf(FAR char *buf, size_t size, FAR const char *format, ...); +int sprintf(FAR char *buf, FAR const IPTR char *format, ...); +int asprintf (FAR char **ptr, FAR const IPTR char *fmt, ...); +int snprintf(FAR char *buf, size_t size, + FAR const IPTR char *format, ...); int sscanf(FAR const char *buf, FAR const char *fmt, ...); void perror(FAR const char *s); -int vprintf(FAR const char *format, va_list ap); -int vfprintf(FAR FILE *stream, const char *format, va_list ap); -int vsprintf(FAR char *buf, const char *format, va_list ap); -int avsprintf(FAR char **ptr, const char *fmt, va_list ap); -int vsnprintf(FAR char *buf, size_t size, const char *format, va_list ap); +int vprintf(FAR const IPTR FAR char *format, va_list ap); +int vfprintf(FAR FILE *stream, FAR const IPTR char *format, + va_list ap); +int vsprintf(FAR char *buf, FAR const IPTR char *format, va_list ap); +int vasprintf(FAR char **ptr, FAR const IPTR char *fmt, va_list ap); +int vsnprintf(FAR char *buf, size_t size, FAR const IPTR char *format, + va_list ap); int vsscanf(FAR const char *buf, FAR const char *s, va_list ap); /* Operations on file descriptors including: @@ -175,8 +187,8 @@ int vsscanf(FAR const char *buf, FAR const char *s, va_list ap); */ FAR FILE *fdopen(int fd, FAR const char *type); -int dprintf(int fd, FAR const char *fmt, ...); -int vdprintf(int fd, FAR const char *fmt, va_list ap); +int dprintf(int fd, FAR const IPTR char *fmt, ...); +int vdprintf(int fd, FAR const IPTR char *fmt, va_list ap); /* Operations on paths */ diff --git a/include/stdlib.h b/include/stdlib.h index 70e9f707e75fc4c6f97e4814b0451d29da660c18..aa259c9d50c16739669caaf8d0cb3b4e78bf3bcd 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/stdlib.h * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -76,7 +76,7 @@ */ #ifndef CONFIG_DISABLE_ENVIRON -# define environ get_environ_ptr() +# define environ get_environ_ptr() #endif /**************************************************************************** @@ -95,6 +95,36 @@ struct mallinfo * by free (not in use) chunks.*/ }; +/* Structure type returned by the div() function. */ + +struct div_s +{ + int quot; /* Quotient */ + int rem; /* Remainder */ +}; + +typedef struct div_s div_t; + +/* Structure type returned by the ldiv() function. */ + +struct ldiv_s +{ + long quot; /* Quotient */ + long rem; /* Remainder */ +}; + +typedef struct ldiv_s ldiv_t; + +/* Structure type returned by the lldiv() function. */ + +struct lldiv_s +{ + long quot; /* Quotient */ + long rem; /* Remainder */ +}; + +typedef struct lldiv_s lldiv_t; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -116,12 +146,12 @@ int rand(void); /* Environment variable support */ #ifndef CONFIG_DISABLE_ENVIRON -FAR char **get_environ_ptr( void ); +FAR char **get_environ_ptr(void); FAR char *getenv(FAR const char *name); int putenv(FAR const char *string); int clearenv(void); -int setenv(const char *name, const char *value, int overwrite); -int unsetenv(const char *name); +int setenv(FAR const char *name, FAR const char *value, int overwrite); +int unsetenv(FAR const char *name); #endif /* Process exit functions */ @@ -142,15 +172,16 @@ void _exit(int status); /* See unistd.h */ /* String to binary conversions */ -long strtol(const char *, char **, int); -unsigned long strtoul(const char *, char **, int); +long strtol(FAR const char *nptr, FAR char **endptr, int base); +unsigned long strtoul(FAR const char *nptr, FAR char **endptr, int base); #ifdef CONFIG_HAVE_LONG_LONG -long long strtoll(const char *, char **, int); -unsigned long long strtoull(const char *, char **, int); +long long strtoll(FAR const char *nptr, FAR char **endptr, int base); +unsigned long long strtoull(FAR const char *nptr, FAR char **endptr, + int base); #endif -double_t strtod(const char *, char **); +double_t strtod(FAR const char *str, FAR char **endptr); -#define atoi(nptr) strtol((nptr), NULL, 10) +#define atoi(nptr) ((int)strtol((nptr), NULL, 10)) #define atol(nptr) strtol((nptr), NULL, 10) #ifdef CONFIG_HAVE_LONG_LONG #define atoll(nptr) strtoll((nptr), NULL, 10) @@ -159,37 +190,54 @@ double_t strtod(const char *, char **); /* Binary to string conversions */ -char *itoa(int value, char *str, int base); +FAR char *itoa(int val, FAR char *str, int base); /* Memory Management */ FAR void *malloc(size_t); -void free(FAR void*); -FAR void *realloc(FAR void*, size_t); +void free(FAR void *); +FAR void *realloc(FAR void *, size_t); FAR void *memalign(size_t, size_t); FAR void *zalloc(size_t); FAR void *calloc(size_t, size_t); -/* Misc */ +#ifdef CONFIG_CAN_PASS_STRUCTS +struct mallinfo mallinfo(void); +#else +int mallinfo(FAR struct mallinfo *info); +#endif + +/* Arithmetic */ int abs(int j); long int labs(long int j); #ifdef CONFIG_HAVE_LONG_LONG long long int llabs(long long int j); #endif + +#ifdef CONFIG_CAN_PASS_STRUCTS +div_t div(int numer, int denom); +ldiv_t ldiv(long numer, long denom); +#ifdef CONFIG_HAVE_LONG_LONG +lldiv_t lldiv(long long numer, long long denom); +#endif +#endif + +/* Temporary files */ + int mktemp(FAR char *path_template); int mkstemp(FAR char *path_template); /* Sorting */ -void qsort(FAR void *base, size_t nmemb, size_t size, - int (*compar)(FAR const void *, FAR const void *)); +void qsort(FAR void *base, size_t nel, size_t width, + CODE int (*compar)(FAR const void *, FAR const void *)); -#ifdef CONFIG_CAN_PASS_STRUCTS -struct mallinfo mallinfo(void); -#else -int mallinfo(struct mallinfo *info); -#endif +/* Binary search */ + +FAR void *bsearch(FAR const void *key, FAR const void *base, size_t nel, + size_t width, CODE int (*compar)(FAR const void *, + FAR const void *)); #undef EXTERN #if defined(__cplusplus) diff --git a/include/sys/boardctl.h b/include/sys/boardctl.h index 5e8adaf6d82761f3a4659386af0308a9e9ada9b0..ac7989b92207ae739f5f4d23ceed9f8c2b9cc026 100644 --- a/include/sys/boardctl.h +++ b/include/sys/boardctl.h @@ -56,19 +56,42 @@ * DESCRIPTION: Perform one-time application initialization. * ARG: None * CONFIGURATION: CONFIG_LIB_BOARDCTL - * DEPENDENCIES: Board logic must provide board_app_initialization + * DEPENDENCIES: Board logic must provide board_app_initialization() * * CMD: BOARDIOC_POWEROFF * DESCRIPTION: Power off the board * ARG: Integer value providing power off status information * CONFIGURATION: CONFIG_BOARDCTL_POWEROFF - * DEPENDENCIES: Board logic must provide board_power_off + * DEPENDENCIES: Board logic must provide the board_power_off() interface. * * CMD: BOARDIOC_RESET * DESCRIPTION: Reset the board * ARG: Integer value providing power off status information * CONFIGURATION: CONFIG_BOARDCTL_RESET - * DEPENDENCIES: Board logic must provide board_reset + * DEPENDENCIES: Board logic must provide the board_reset() interface. + * + * CMD: BOARDIOC_UNIQUEID + * DESCRIPTION: Return a unique ID associated with the board (such as a + * serial number or a MAC address). + * ARG: A writable array of size CONFIG_BOARDCTL_UNIQUEID_SIZE in + * which to receive the board unique ID. + * DEPENDENCIES: Board logic must provide the board_uniqueid() interface. + * + * CMD: BOARDIOC_APP_SYMTAB + * DESCRIPTION: Select the application symbol table. This symbol table + * provides the symbol definitions exported to application + * code from application space. + * ARG: A pointer to an instance of struct boardioc_symtab_s + * CONFIGURATION: CONFIG_BOARDCTL_APP_SYMTAB + * DEPENDENCIES: None + * + * CMD: BOARDIOC_OS_SYMTAB + * DESCRIPTION: Select the OS symbol table. This symbol table provides + * the symbol definitions exported by the OS to kernel + * modules. + * ARG: A pointer to an instance of struct boardioc_symtab_s + * CONFIGURATION: CONFIG_BOARDCTL_OS_SYMTAB + * DEPENDENCIES: None * * CMD: BOARDIOC_TSCTEST_SETUP * DESCRIPTION: Touchscreen controller test configuration @@ -94,6 +117,12 @@ * CONFIGURATION: CONFIG_LIB_BOARDCTL && CONFIG_BOARDCTL_PWMTEST * DEPENDENCIES: Board logic must provide board_pwm_setup() * + * CMD: BOARDIOC_CAN_INITIALIZE + * DESCRIPTION: CAN device initialization + * ARG: None + * CONFIGURATION: CONFIG_LIB_BOARDCTL && CONFIG_BOARDCTL_CANINIT + * DEPENDENCIES: Board logic must provide board_can_initialize() + * * CMD: BOARDIOC_GRAPHICS_SETUP * DESCRIPTION: Configure graphics that require special initialization * procedures @@ -105,11 +134,15 @@ #define BOARDIOC_INIT _BOARDIOC(0x0001) #define BOARDIOC_POWEROFF _BOARDIOC(0x0002) #define BOARDIOC_RESET _BOARDIOC(0x0003) -#define BOARDIOC_TSCTEST_SETUP _BOARDIOC(0x0004) -#define BOARDIOC_TSCTEST_TEARDOWN _BOARDIOC(0x0005) -#define BOARDIOC_ADCTEST_SETUP _BOARDIOC(0x0006) -#define BOARDIOC_PWMTEST_SETUP _BOARDIOC(0x0007) -#define BOARDIOC_GRAPHICS_SETUP _BOARDIOC(0x0008) +#define BOARDIOC_UNIQUEID _BOARDIOC(0x0004) +#define BOARDIOC_APP_SYMTAB _BOARDIOC(0x0005) +#define BOARDIOC_OS_SYMTAB _BOARDIOC(0x0006) +#define BOARDIOC_TSCTEST_SETUP _BOARDIOC(0x0007) +#define BOARDIOC_TSCTEST_TEARDOWN _BOARDIOC(0x0008) +#define BOARDIOC_ADCTEST_SETUP _BOARDIOC(0x0009) +#define BOARDIOC_PWMTEST_SETUP _BOARDIOC(0x000a) +#define BOARDIOC_CAN_INITIALIZE _BOARDIOC(0x000b) +#define BOARDIOC_GRAPHICS_SETUP _BOARDIOC(0x000c) /* If CONFIG_BOARDCTL_IOCTL=y, then boad-specific commands will be support. * In this case, all commands not recognized by boardctl() will be forwarded @@ -118,7 +151,7 @@ * User defined board commands may begin with this value: */ -#define BOARDIOC_USER _BOARDIOC(0x0009) +#define BOARDIOC_USER _BOARDIOC(0x000d) /**************************************************************************** * Public Type Definitions @@ -144,6 +177,18 @@ struct boardioc_graphics_s #endif }; +/* In order to full describe a symbol table, a vector containing the address + * of the symbol table and the number of elements in the symbol table is + * required. + */ + +struct symtab_s; /* Forward reference */ +struct boardioc_symtab_s +{ + FAR struct symtab_s *symtab; + int nsymbols; +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/include/sys/sendfile.h b/include/sys/sendfile.h index 5db6ff70c3ef071f90f54f495a51545b691157a6..22cb8271ef6521c34b150f3b6d10d9eb5a54ba9f 100644 --- a/include/sys/sendfile.h +++ b/include/sys/sendfile.h @@ -70,7 +70,7 @@ extern "C" #define EXTERN extern #endif -/************************************************************************ +/**************************************************************************** * Name: sendfile * * Description: @@ -112,7 +112,7 @@ extern "C" * EINVAL - Bad input parameters. * ENOMEM - Could not allocated an I/O buffer * - ************************************************************************/ + ****************************************************************************/ ssize_t sendfile(int outfd, int infd, FAR off_t *offset, size_t count); diff --git a/include/sys/socket.h b/include/sys/socket.h index 4c7b79ee79b6eeb466b93cdd2938c45853e0c62f..1d88cb73ab7f908d17c57ab2b145f3fbd1777244 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/sys/socket.h * - * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,34 +50,24 @@ * the protocol family which will be used for communication. */ -/* Protocol families */ +/* Supported Protocol Families */ -#define PF_UNSPEC 0 /* Protocol family unspecified */ -#define PF_UNIX 1 /* Local communication */ -#define PF_LOCAL 1 /* Local communication */ -#define PF_INET 2 /* IPv4 Internet protocols */ -#define PF_INET6 3 /* IPv6 Internet protocols */ -#define PF_IPX 4 /* IPX - Novell protocols */ -#define PF_NETLINK 5 /* Kernel user interface device */ -#define PF_X25 6 /* ITU-T X.25 / ISO-8208 protocol */ -#define PF_AX25 7 /* Amateur radio AX.25 protocol */ -#define PF_ATMPVC 8 /* Access to raw ATM PVCs */ -#define PF_APPLETALK 9 /* Appletalk */ -#define PF_PACKET 10 /* Low level packet interface */ +#define PF_UNSPEC 0 /* Protocol family unspecified */ +#define PF_UNIX 1 /* Local communication */ +#define PF_LOCAL 1 /* Local communication */ +#define PF_INET 2 /* IPv4 Internet protocols */ +#define PF_INET6 3 /* IPv6 Internet protocols */ +#define PF_PACKET 4 /* Low level packet interface */ -/* Address families */ +/* Supported Address Families. Opengroup.org requires only AF_UNSPEC, + * AF_UNIX, AF_INET and AF_INET6. + */ #define AF_UNSPEC PF_UNSPEC #define AF_UNIX PF_UNIX #define AF_LOCAL PF_LOCAL #define AF_INET PF_INET #define AF_INET6 PF_INET6 -#define AF_IPX PF_IPX -#define AF_NETLINK PF_NETLINK -#define AF_X25 PF_X25 -#define AF_AX25 PF_AX25 -#define AF_ATMPVC PF_ATMPVC -#define AF_APPLETALK PF_APPLETALK #define AF_PACKET PF_PACKET /* The socket created by socket() has the indicated type, which specifies @@ -155,6 +145,12 @@ #define SOL_SOCKET 0 /* Only socket-level options supported */ +/* Values for the 'how' argument of shutdown() */ + +#define SHUT_RD 1 /* Bit 0: Disables further receive operations */ +#define SHUT_WR 2 /* Bit 1: Disables further send operations */ +#define SHUT_RDWR 3 /* Bits 0+1: Disables further send and receive operations */ + /**************************************************************************** * Type Definitions ****************************************************************************/ @@ -227,6 +223,8 @@ ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags); ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from, FAR socklen_t *fromlen); +int shutdown(int sockfd, int how); + int setsockopt(int sockfd, int level, int option, FAR const void *value, socklen_t value_len); int getsockopt(int sockfd, int level, int option, diff --git a/include/sys/stat.h b/include/sys/stat.h index a27d2243653f2d55bc1472acec78edc612b5d7a4..3f2658b5f184b4e6ed77690c1e199819398acb9f 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -117,7 +117,7 @@ struct stat }; /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #undef EXTERN diff --git a/include/sys/statfs.h b/include/sys/statfs.h index 4daf188e9a051493aa9ec42ed0e44b3afc27ffca..1d1786a3f81c53b2cd52e8aa470cf086bb24f92a 100644 --- a/include/sys/statfs.h +++ b/include/sys/statfs.h @@ -103,6 +103,7 @@ #define NXFFS_MAGIC 0x4747 #define SMARTFS_MAGIC 0x54524D53 #define UNIONFS_MAGIC 0x53464e55 +#define HOSTFS_MAGIC 0x54534f48 /**************************************************************************** * Type Definitions diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 835f40e085b64d6b0afc5b9081268bdf3e867123..198b27c95332027e814ddb119ff3c1546995774e 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -2,7 +2,7 @@ * include/sys/syscall.h * This file contains the system call numbers. * - * Copyright (C) 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -152,12 +152,24 @@ # ifdef CONFIG_SCHED_HAVE_PARENT # define SYS_wait (__SYS_waitpid+1) # define SYS_waitid (__SYS_waitpid+2) -# define __SYS_posix_spawn (__SYS_waitpid+3) +# define __SYS_insmod (__SYS_waitpid+3) # else -# define __SYS_posix_spawn (__SYS_waitpid+1) +# define __SYS_insmod (__SYS_waitpid+1) #endif #else -# define __SYS_posix_spawn __SYS_waitpid +# define __SYS_insmod __SYS_waitpid +#endif + +/* The following can only be defined if we are configured to load + * OS modules from a file system. + */ + +#ifdef CONFIG_MODULE +# define SYS_insmod __SYS_insmod +# define SYS_rmmod (__SYS_insmod+1) +# define __SYS_posix_spawn (__SYS_insmod+2) +#else +# define __SYS_posix_spawn __SYS_insmod #endif /* The following can only be defined if we are configured to execute @@ -365,13 +377,21 @@ # define SYS_pthread_setspecific (__SYS_pthread+26) # define SYS_pthread_yield (__SYS_pthread+27) +# ifndef CONFIG_SMP +# define SYS_pthread_setaffinity_np (__SYS_pthread+28) +# define SYS_pthread_getaffinity_np (__SYS_pthread+29) +# define __SYS_pthread_signals (__SYS_pthread+30) +# else +# define __SYS_pthread_signals (__SYS_pthread+28) +# endif + # ifndef CONFIG_DISABLE_SIGNALS -# define SYS_pthread_cond_timedwait (__SYS_pthread+28) -# define SYS_pthread_kill (__SYS_pthread+29) -# define SYS_pthread_sigmask (__SYS_pthread+30) -# define __SYS_mqueue (__SYS_pthread+31) +# define SYS_pthread_cond_timedwait (__SYS_pthread_signals+0) +# define SYS_pthread_kill (__SYS_pthread_signals+1) +# define SYS_pthread_sigmask (__SYS_pthread_signals+2) +# define __SYS_mqueue (__SYS_pthread_signals+3) # else -# define __SYS_mqueue (__SYS_pthread+28) +# define __SYS_mqueue __SYS_pthread_signals # endif #else diff --git a/include/sys/time.h b/include/sys/time.h index 20ff459e1b4f793ab9e4796073b75381fdddb90f..b36e30fca9a46e4c65775feb8b6200f6e5d10159 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -48,6 +48,67 @@ * Pre-processor Definitions ****************************************************************************/ +/* The following are non-standard interfaces in the sense that they are not + * in POSIX.1-2001 nor are they specified at OpenGroup.org. These interfaces + * are present on most BSD derivatives, however, including Linux. + */ + +/* void timeradd(FAR struct timeval *a, FAR struct timeval *b, + * FAR struct timeval *res); + */ + +#define timeradd(tvp, uvp, vvp) \ + do \ + { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) \ + { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } \ + while (0) + +/* void timersub(FAR struct timeval *a, FAR struct timeval *b, + * FAR struct timeval *res); + */ + +#define timersub(tvp, uvp, vvp) \ + do \ + { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + if ((uvp)->tv_usec > (tvp)->tv_usec) \ + { \ + (vvp)->tv_sec--; \ + (tvp)->tv_usec += 1000000; \ + } \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + } \ + while (0) + +/* void timerclear(FAR struct timeval *tvp); */ + +#define timerclear(tvp) \ + do \ + { \ + tvp)->tv_sec = 0; \ + tvp)->tv_usec = 0; \ + } \ + while (0) + +/* int timerisset(FAR struct timeval *tvp); */ + +#define timerisset(tvp) \ + ((tvp)->tv_sec != 0 || (tvp)->tv_usec != 0) + +/* int timercmp(FAR struct timeval *a, FAR struct timeval *b, CMP); */ + +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) + /**************************************************************************** * Public Type Definitions ****************************************************************************/ diff --git a/include/sys/types.h b/include/sys/types.h index 14c04e9c78a6fc0237e0ce1a160d03058a2c3042..a818cc2a80ac6f73731a01a68863852426b90091 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -142,10 +142,14 @@ typedef int16_t ssize_t; typedef uint16_t rsize_t; #else /* CONFIG_SMALL_MEMORY */ +/* As a general rule, the size of size_t should be the same as the size of + * uintptr_t: 32-bits on a machine with 32-bit addressing but 64-bits on a + * machine with 64-bit addressing. + */ -typedef uint32_t size_t; -typedef int32_t ssize_t; -typedef uint32_t rsize_t; +typedef uintptr_t size_t; +typedef intptr_t ssize_t; +typedef uintptr_t rsize_t; #endif /* CONFIG_SMALL_MEMORY */ @@ -240,6 +244,20 @@ typedef uint32_t clock_t; typedef uint32_t useconds_t; typedef int32_t suseconds_t; +#ifdef CONFIG_SMP +/* This is the smallest integer type that will hold a bitset of all CPUs */ + +#if (CONFIG_SMP_NCPUS <= 8) +typedef volatile uint8_t cpu_set_t; +#elif (CONFIG_SMP_NCPUS <= 16) +typedef volatile uint16_t cpu_set_t; +#elif (CONFIG_SMP_NCPUS <= 32) +typedef volatile uint32_t cpu_set_t; +#else +# error SMP: Extensions needed to support this number of CPUs +#endif +#endif /* CONFIG_SMP */ + /* BSD types provided only to support porting to NuttX. */ typedef unsigned char u_char; @@ -258,12 +276,12 @@ typedef FAR char *caddr_t; /* Task entry point */ -typedef CODE int (*main_t)(int argc, char *argv[]); +typedef CODE int (*main_t)(int argc, FAR char *argv[]); #endif /* __ASSEMBLY__ */ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #endif /* __INCLUDE_SYS_TYPES_H */ diff --git a/include/syslog.h b/include/syslog.h index b06997f1f3cf7db4764cad2c7563311deeb28dba..6c1316a7e61477eea4f0a754e326bb388a5112a2 100644 --- a/include/syslog.h +++ b/include/syslog.h @@ -41,6 +41,7 @@ ****************************************************************************/ #include +#include #include #include @@ -132,7 +133,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -167,8 +168,8 @@ void closelog(void); * ****************************************************************************/ -int syslog(int priority, FAR const char *format, ...); -int vsyslog(int priority, FAR const char *src, va_list ap); +int syslog(int priority, FAR const IPTR char *format, ...); +int vsyslog(int priority, FAR const IPTR char *src, va_list ap); /**************************************************************************** * Name: lowsyslog and lowvsyslog @@ -198,8 +199,8 @@ int vsyslog(int priority, FAR const char *src, va_list ap); #ifdef CONFIG_ARCH_LOWPUTC -int lowsyslog(int priority, FAR const char *format, ...); -int lowvsyslog(int priority, FAR const char *format, va_list ap); +int lowsyslog(int priority, FAR const IPTR char *format, ...); +int lowvsyslog(int priority, FAR const IPTR char *format, va_list ap); #else diff --git a/include/time.h b/include/time.h index 8608c22fdfb22e617850125ab6d3ba113f554959..0fd4b7611bc8ca43f46d060c4d570e2dca34dbe0 100644 --- a/include/time.h +++ b/include/time.h @@ -205,7 +205,7 @@ FAR struct tm *localtime_r(FAR const time_t *timep, FAR struct tm *result); size_t strftime(FAR char *s, size_t max, FAR const char *format, FAR const struct tm *tm); -#ifdef CONFIG_TIME_EXTENDED +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) FAR char *asctime(FAR const struct tm *tp); FAR char *asctime_r(FAR const struct tm *tp, FAR char *buf); FAR char *ctime(FAR const time_t *timep); diff --git a/libc/Kconfig b/libc/Kconfig index e51915d1c274bbb8a6881ee87b503db846091d8d..276cc502e5d228070e2040aeac9952dd72c114cc 100644 --- a/libc/Kconfig +++ b/libc/Kconfig @@ -504,6 +504,49 @@ config ARCH_BZERO endif # ARCH_OPTIMIZED_FUNCTIONS +config ARCH_HAVE_TLS + bool + default n + ---help--- + Selected by the configuration system if the current architecture + supports TLS. + +menuconfig TLS + bool "Thread Local Storage (TLS)" + default n + depends on ARCH_HAVE_TLS + ---help--- + Build in support for stack based thread local storage (TLS). + +if TLS + +config TLS_LOG2_MAXSTACK + int "Maximum stack size (log2)" + default 13 + range 11 24 + ---help--- + Stack based TLS works by fetch thread information from the beginning + of the stack memory allocation. In order to do this, the memory + must be aligned in such a way that the executing logic can simply + masking the current stack pointer to get the beginning of the stack + allocation. + + This setting specifies the alignment of the stack as a power of 2: + 11=2KB, 12=4KB, 13=8KB, etc. The exact alignment is not so critical + except that (1) a very large value can cause you to run out of + alignable memory (and fail memory allocations), and (2) smaller + values will limit the maximum size of the stack (hence the naming + of this configuration value). + +config TLS_NELEM + int "Number of TLS elements" + default 1 + ---help--- + The number of unique TLS elements. These can be accessed with + the user library functions tls_get_element() and tls_set_element(). + +endif # TLS + config LIBC_NETDB bool default n @@ -533,7 +576,7 @@ config NETDB_BUFSIZE endif # NETDB_HOSTFILE -config NETDB_DNSCLIENT +menuconfig NETDB_DNSCLIENT bool "DNS Name resolution" default n depends on NET && NET_UDP @@ -592,20 +635,68 @@ config NETDB_DNSCLIENT_MAXRESPONSE can be received by the DNS resolver. The default is 96 but may need to be larger on enterprise networks (perhaps 176). + +config NETDB_RESOLVCONF + bool "DNS resolver file support" + default n + depends on FS_READABLE + ---help--- + Enable DNS server look ups in resolver file like /etc/resolv.conf. + +if NETDB_RESOLVCONF + +config NETDB_RESOLVCONF_PATH + string "Path to host configuration file" + default "/etc/resolv.conf" + +config NETDB_RESOLVCONF_NONSTDPORT + bool "Non-standard port support" + default n + ---help--- + By default, the resolv.conf file will hold only records like: + + nameserver xx.xx.xx.xx + nameserver xxxx:::::::xxxx + + The default port of 53 is always assumed. + + If this option is selected, then OpenBSD style resolv.conf files + will be supported. This adds logic for a bracket port notation + like: + + nameserver [xx.xx.xx.xx]:ppppp + nameserver [xxxx:::::::xxxx]:ppppp + +endif # NETDB_RESOLVCONF + choice prompt "DNS server address type" - default NETDB_DNSSERVER_NOADDR + default NETDB_DNSSERVER_IPv4 if NET_IPv4 + default NETDB_DNSSERVER_IPv6 if !NET_IPv4 && NET_IPv6 + default NETDB_DNSSERVER_NOADDR if !NET_IPv4 && !NET_IPv6 + depends on !NETDB_RESOLVCONF config NETDB_DNSSERVER_NOADDR bool "No default DNS server address" + ---help--- + There is not default DNS nameserver address. Application must call + dns_add_server() at runtime to add the DNS server address. config NETDB_DNSSERVER_IPv4 bool "IPv4 DNS server address" depends on NET_IPv4 + ---help--- + An IPv4 default DNS nameserver address will be provided. Application + may overwrite this start default server address by calling + dns_add_server() at runtime. config NETDB_DNSSERVER_IPv6 bool "IPv6 DNS server address" depends on NET_IPv6 + ---help--- + An IPv6 default DNS nameserver address will be provided. Application + may overwrite this start default server address by calling + dns_add_server() at runtime. endchoice # DNS server address type @@ -615,7 +706,7 @@ config NETDB_DNSSERVER_IPv4ADDR depends on NETDB_DNSSERVER_IPv4 ---help--- Default DNS server IPv4 address in host byte order. Default value - 10.0.0.0.1. This may be changed via dns_setserver(). + 10.0.0.0.1. This may be changed via dns_add_nameserver(). if NETDB_DNSSERVER_IPv6 diff --git a/libc/Makefile b/libc/Makefile index 76d3e473aa7f163352f38ae1a6d913ae236963a7..f07366f07687fc4f519839f2ee8316323cd7a75c 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -61,29 +61,31 @@ CSRCS = DEPPATH := --dep-path . VPATH := . -include stdio/Make.defs -include stdlib/Make.defs -include unistd/Make.defs -include sched/Make.defs -include syslog/Make.defs -include string/Make.defs include aio/Make.defs -include pthread/Make.defs -include semaphore/Make.defs -include signal/Make.defs -include math/Make.defs +include audio/Make.defs +include dirent/Make.defs include fixedmath/Make.defs +include libgen/Make.defs +include math/Make.defs +include misc/Make.defs include net/Make.defs include netdb/Make.defs -include time/Make.defs -include libgen/Make.defs -include dirent/Make.defs -include termios/Make.defs -include spawn/Make.defs +include pthread/Make.defs include queue/Make.defs +include sched/Make.defs +include semaphore/Make.defs +include signal/Make.defs +include spawn/Make.defs +include stdio/Make.defs +include stdlib/Make.defs +include string/Make.defs +include symtab/Make.defs +include syslog/Make.defs +include termios/Make.defs +include time/Make.defs +include tls/Make.defs +include unistd/Make.defs include wqueue/Make.defs -include misc/Make.defs -include audio/Make.defs # REVISIT: Backslash causes problems in $(COBJS) target DELIM := $(strip /) diff --git a/libc/aio/aio.h b/libc/aio/aio.h index f1376be9ab522215a1a792aee8b55e583f3fdcda..f28340f3c2f9d3f04aa2d1df6a7a6a1e43891605 100644 --- a/libc/aio/aio.h +++ b/libc/aio/aio.h @@ -53,7 +53,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN diff --git a/libc/aio/aio_error.c b/libc/aio/aio_error.c index 4d1eca99c5b5696c89dbd93c9a551d7e2f5965a0..896ac97056deaea60d5327842026a4583be45570 100644 --- a/libc/aio/aio_error.c +++ b/libc/aio/aio_error.c @@ -55,11 +55,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/aio/aio_return.c b/libc/aio/aio_return.c index 076d8fb293c744d478e5a7dd88d5f72f78b01662..cfc58743796c712f38a7f95de62070ab43c4cc93 100644 --- a/libc/aio/aio_return.c +++ b/libc/aio/aio_return.c @@ -55,11 +55,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/aio/aio_suspend.c b/libc/aio/aio_suspend.c index 89982fc89d623e09b9e8cb566843e106cebafea0..948462cd909b5e314db1245fc20dec075291b442 100644 --- a/libc/aio/aio_suspend.c +++ b/libc/aio/aio_suspend.c @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/aio/lio_listio.c b/libc/aio/lio_listio.c index 5b2277347b322f02d1e388b1841430c7cfa3bcb6..b123a4e7357d3f984ee8cc4259279afe11a10c9e 100644 --- a/libc/aio/lio_listio.c +++ b/libc/aio/lio_listio.c @@ -45,16 +45,13 @@ #include #include -#include "lib_internal.h" +#include + +#include "libc.h" #include "aio/aio.h" #ifdef CONFIG_FS_AIO -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Configuration ************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -69,14 +66,6 @@ struct lio_sighand_s struct sigaction oact; /* Signal handler to restore */ }; -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -205,14 +194,23 @@ static void lio_sighandler(int signo, siginfo_t *info, void *ucontext) if (sighand->sig->sigev_notify == SIGEV_SIGNAL) { #ifdef CONFIG_CAN_PASS_STRUCTS - (void)sigqueue(sighand->pid, sighand->sig->sigev_signo, - sighand->sig->sigev_value); + DEBUGASSERT(sigqueue(sighand->pid, sighand->sig->sigev_signo, + sighand->sig->sigev_value)); #else - (void)sigqueue(sighand->pid, sighand->sig->sigev_signo, - sighand->sig->sigev_value.sival_ptr); + DEBUGASSERT(sigqueue(sighand->pid, sighand->sig->sigev_signo, + sighand->sig->sigev_value.sival_ptr)); #endif } +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ + + else if (ighand->sig->sigev_notify == SIGEV_THREAD) + { + DEBUGASSERT(sig_notification(sighand->pid, &sighand->sig)); + } +#endif + /* And free the container */ lib_free(sighand); @@ -305,7 +303,7 @@ static int lio_sigsetup(FAR struct aiocb * const *list, int nent, /* Attach our signal handler */ - printf("waiter_main: Registering signal handler\n" ); + printf("waiter_main: Registering signal handler\n"); act.sa_sigaction = lio_sighandler; act.sa_flags = SA_SIGINFO; @@ -352,7 +350,7 @@ static int lio_waitall(FAR struct aiocb * const *list, int nent) /* Loop until all I/O completes */ - for (;;) + for (; ; ) { /* Check if all I/O has completed */ @@ -651,7 +649,7 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, */ status = lio_waitall(list, nent); - if (status < 0 && ret != OK) + if (status < 0 && ret == OK) { /* Something bad happened while waiting and this is the first * error to be reported. @@ -679,7 +677,7 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, /* Setup a signal handler to detect when until all I/O completes. */ status = lio_sigsetup(list, nent, sig); - if (status < 0 && ret != OK) + if (status < 0 && ret == OK) { /* Something bad happened while setting up the signal and this * is the first error to be reported. @@ -698,8 +696,7 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, status = sigqueue(getpid(), sig->sigev_signo, sig->sigev_value.sival_ptr); #endif - - if (status < 0 && ret != OK) + if (status < 0 && ret == OK) { /* Something bad happened while signalling ourself and this is * the first error to be reported. @@ -711,6 +708,24 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, } } +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ + + else if (sig && sig->sigev_notify == SIGEV_THREAD) + { + status = sig_notification(sighand->pid, &sighand->sig); + if (status < 0 && ret == OK) + { + /* Something bad happened while performing the notification + * and this is the first error to be reported. + */ + + retcode = -status; + ret = ERROR; + } + } +#endif + /* Case 3: mode == LIO_NOWAIT and sig == NULL * * Just return now. diff --git a/libc/audio/lib_buffer.c b/libc/audio/lib_buffer.c index cfcf43f2dc2151580178707ad0e3c3e459945575..af4e719879e649246856b2d7105a7b0b3113aa36 100644 --- a/libc/audio/lib_buffer.c +++ b/libc/audio/lib_buffer.c @@ -52,7 +52,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if defined(CONFIG_AUDIO) @@ -67,11 +67,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/fixedmath/lib_b16atan2.c b/libc/fixedmath/lib_b16atan2.c index f0a00f8df4808ba25091aad2b2881680e3958ef2..4cdb76e09cf56676e20d4ff626705145c8e510dd 100644 --- a/libc/fixedmath/lib_b16atan2.c +++ b/libc/fixedmath/lib_b16atan2.c @@ -65,7 +65,7 @@ #endif /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/fixedmath/lib_b16cos.c b/libc/fixedmath/lib_b16cos.c index 0ebe482624283bef07d21e83fdbd4400022516bb..5ff4215cf0c85a9991d03fdd99d9ffd1577d5706 100644 --- a/libc/fixedmath/lib_b16cos.c +++ b/libc/fixedmath/lib_b16cos.c @@ -44,7 +44,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/fixedmath/lib_b16sin.c b/libc/fixedmath/lib_b16sin.c index 9cd2f0da3e1d213336e28049fae7f05641cc0721..c63e170a766b9b8460f24b9eb6c207b9a40e5f02 100644 --- a/libc/fixedmath/lib_b16sin.c +++ b/libc/fixedmath/lib_b16sin.c @@ -48,7 +48,7 @@ #define b16_1P27323954 0x000145f3 /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/fixedmath/lib_fixedmath.c b/libc/fixedmath/lib_fixedmath.c index 9e9213b4fcf6d51dfdba39f198652e2cfc012780..d5dff82243a7170821d706ea77d8081b28604e35 100644 --- a/libc/fixedmath/lib_fixedmath.c +++ b/libc/fixedmath/lib_fixedmath.c @@ -140,21 +140,21 @@ b16_t b16mulb16(b16_t m1, b16_t m2) /**************************************************************************** * Name: ub16mulub16 - **************************************************************************/ + ****************************************************************************/ ub16_t ub16mulub16(ub16_t m1, ub16_t m2) { - /* Let: - * - * m1 = m1i*2**16 + m1f (b16) - * m2 = m2i*2**16 + m2f (b16) - * - * Then: - * - * m1*m2 = (m1i*m2i)*2**32 + (m1i*m2f + m2i*m1f)*2**16 + m1f*m2f (b32) - * = (m1i*m2i)*2**16 + (m1i*m2f + m2i*m1f) + m1f*m2f*2**-16 (b16) - * = a*2**16 + b + c*2**-16 - */ + /* Let: + * + * m1 = m1i*2**16 + m1f (b16) + * m2 = m2i*2**16 + m2f (b16) + * + * Then: + * + * m1*m2 = (m1i*m2i)*2**32 + (m1i*m2f + m2i*m1f)*2**16 + m1f*m2f (b32) + * = (m1i*m2i)*2**16 + (m1i*m2f + m2i*m1f) + m1f*m2f*2**-16 (b16) + * = a*2**16 + b + c*2**-16 + */ uint32_t m1i = ((uint32_t)m1 >> 16); uint32_t m2i = ((uint32_t)m1 >> 16); @@ -166,7 +166,7 @@ ub16_t ub16mulub16(ub16_t m1, ub16_t m2) /**************************************************************************** * Name: b16sqr - **************************************************************************/ + ****************************************************************************/ b16_t b16sqr(b16_t a) { @@ -191,19 +191,19 @@ b16_t b16sqr(b16_t a) /**************************************************************************** * Name: b16divb16 - **************************************************************************/ + ****************************************************************************/ ub16_t ub16sqr(ub16_t a) { - /* Let: - * - * m = mi*2**16 + mf (b16) - * - * Then: - * - * m*m = (mi*mi)*2**32 + 2*(m1*m2)*2**16 + mf*mf (b32) - * = (mi*mi)*2**16 + 2*(mi*mf) + mf*mf*2**-16 (b16) - */ + /* Let: + * + * m = mi*2**16 + mf (b16) + * + * Then: + * + * m*m = (mi*mi)*2**32 + 2*(m1*m2)*2**16 + mf*mf (b32) + * = (mi*mi)*2**16 + 2*(mi*mf) + mf*mf*2**-16 (b16) + */ uint32_t mi = ((uint32_t)a >> 16); uint32_t mf = ((uint32_t)a & 0x0000ffff); @@ -213,7 +213,7 @@ ub16_t ub16sqr(ub16_t a) /**************************************************************************** * Name: b16divb16 - **************************************************************************/ + ****************************************************************************/ b16_t b16divb16(b16_t num, b16_t denom) { @@ -227,7 +227,7 @@ b16_t b16divb16(b16_t num, b16_t denom) /**************************************************************************** * Name: ub16divub16 - **************************************************************************/ + ****************************************************************************/ ub16_t ub16divub16(ub16_t num, ub16_t denom) { @@ -235,16 +235,16 @@ ub16_t ub16divub16(ub16_t num, ub16_t denom) uint32_t numf; uint32_t product; - /* Let: - * - * num = numi*2**16 + numf (b16) - * den = deni*2**16 + denf (b16) - * - * Then: - * - * num/den = numi*2**16 / den + numf / den (b0) - * = numi*2**32 / den + numf*2**16 /den (b16) - */ + /* Let: + * + * num = numi*2**16 + numf (b16) + * den = deni*2**16 + denf (b16) + * + * Then: + * + * num/den = numi*2**16 / den + numf / den (b0) + * = numi*2**32 / den + numf*2**16 /den (b16) + */ /* Check for overflow in the first part of the quotient */ diff --git a/libc/libc.csv b/libc/libc.csv index 65dc81da82ec8be3c88d3c6ca6e73a64b44018f8..d93fe22a27d2e33c7ca0525999efa04b7cdb92c6 100644 --- a/libc/libc.csv +++ b/libc/libc.csv @@ -5,13 +5,13 @@ "aio_return","aio.h","defined(CONFIG_FS_AIO)","ssize_t","FAR struct aiocb *" "aio_suspend","aio.h","defined(CONFIG_FS_AIO)","int","FAR struct aiocb *const []|FAR struct aiocb *const *","int","FAR const struct timespec *" "asprintf","stdio.h","","int","FAR char **","const char *","..." -"avsprintf","stdio.h","","int","FAR char **","const char *","va_list" -"b16atan2","fixedmath.h","","b16_t","b16_t","b16_t" +"vasprintf","stdio.h","","int","FAR char **","const char *","va_list" +"b16atan2","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","b16_t","b16_t","b16_t" "b16cos","fixedmath.h","","b16_t","b16_t" -"b16divb16","fixedmath.h","","b16_t","b16_t","b16_t" -"b16mulb16","fixedmath.h","","b16_t","b16_t","b16_t" +"b16divb16","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","b16_t","b16_t","b16_t" +"b16mulb16","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","b16_t","b16_t","b16_t" "b16sin","fixedmath.h","","b16_t","b16_t" -"b16sqr","fixedmath.h","","b16_t","b16_t" +"b16sqr","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","b16_t","b16_t" "basename","libgen.h","","FAR char","FAR char *" "cfgetspeed","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","speed_t","FAR const struct termios *" "cfsetspeed","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","int","FAR struct termios *","speed_t" @@ -117,6 +117,7 @@ "sigemptyset","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR sigset_t *" "sigfillset","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR sigset_t *" "sigismember","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","FAR const sigset_t *","int" +"sleep","unistd.h","!defined(CONFIG_DISABLE_SIGNALS)","unsigned int","unsigned int" "snprintf","stdio.h","","int","FAR char *","size_t","const char *","..." "sprintf","stdio.h","","int","FAR char *","const char *","..." "sq_addafter","queue.h","","void","FAR sq_entry_t *","FAR sq_entry_t *","FAR sq_queue_t *" @@ -162,10 +163,11 @@ "tcsetattr","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","int","int","int","FAR const struct termios *" "telldir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","off_t","FAR DIR *" "time","time.h","","time_t","time_t *" -"ub16divub16","fixedmath.h","","ub16_t","ub16_t","ub16_t" -"ub16mulub16","fixedmath.h","","ub16_t","ub16_t","ub16_t" -"ub16sqr","fixedmath.h","","ub16_t","ub16_t" +"ub16divub16","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","ub16_t","ub16_t","ub16_t" +"ub16mulub16","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","ub16_t","ub16_t","ub16_t" +"ub16sqr","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","ub16_t","ub16_t" "ungetc","stdio.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","int","int","FAR FILE *" +"usleep","unistd.h","!defined(CONFIG_DISABLE_SIGNALS)","int","int","FAR FILE *" "vdbg","debug.h","!defined(CONFIG_CPP_HAVE_VARARGS) && defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE)","int","const char *","..." "vfprintf","stdio.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","int","FAR FILE *","const char *","va_list" "vprintf","stdio.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","int","FAR const char *","va_list" diff --git a/libc/lib_internal.h b/libc/libc.h similarity index 97% rename from libc/lib_internal.h rename to libc/libc.h index c4610dfe624318b350ab2721255a863a8a9fe3a6..9cb1974fa93e8d759e56ca438069507002780da9 100644 --- a/libc/lib_internal.h +++ b/libc/libc.h @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/lib_internal.h + * libc/libc.h * * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __LIBC_LIB_INTERNAL_H -#define __LIBC_LIB_INTERNAL_H +#ifndef __LIBC_LIBC_H +#define __LIBC_LIBC_H /**************************************************************************** * Included Files @@ -155,7 +155,11 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); #endif -/* Defined in lib_libwrite.c */ +/* Defined in lib_fopen.c */ + +int lib_mode2oflags(FAR const char *mode); + +/* Defined in lib_libfwrite.c */ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream); @@ -229,4 +233,4 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host, } #endif -#endif /* __LIBC_LIB_INTERNAL_H */ +#endif /* __LIBC_LIBC_H */ diff --git a/libc/libgen/lib_basename.c b/libc/libgen/lib_basename.c index 68188edbf52d1411a9ac004283852b9574e1c9f4..94df0712005959b0a874447785559cdc22a3a1a7 100644 --- a/libc/libgen/lib_basename.c +++ b/libc/libgen/lib_basename.c @@ -49,7 +49,7 @@ static char g_retchar[2]; /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/libgen/lib_dirname.c b/libc/libgen/lib_dirname.c index 6d076fd610bc0beef79a14a94138fb58cf3ada58..b7760c3a1f5b8eff7ee58eac5ebb0e6324acf9a2 100644 --- a/libc/libgen/lib_dirname.c +++ b/libc/libgen/lib_dirname.c @@ -49,7 +49,7 @@ static char g_retchar[2]; /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/math/lib_acos.c b/libc/math/lib_acos.c index c1da957f92ea6b88fdfdef55a97c24f79fcde381..4903af43bc6ff2893e37e6d65c90036e72c08ca5 100644 --- a/libc/math/lib_acos.c +++ b/libc/math/lib_acos.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acos.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double acos(double x) diff --git a/libc/math/lib_acosf.c b/libc/math/lib_acosf.c index e75325dc014aa0206786f70bf6e51864c456dfb3..6719e54a67df2f3309a3a1b8d708500e0d763859 100644 --- a/libc/math/lib_acosf.c +++ b/libc/math/lib_acosf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acosf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float acosf(float x) { diff --git a/libc/math/lib_acosh.c b/libc/math/lib_acosh.c index cd9fde5598a028c579567e7f5e51be894bf369ac..278c454e9d0138a7187d574e0cfdcd76483f97ea 100644 --- a/libc/math/lib_acosh.c +++ b/libc/math/lib_acosh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acosh.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double acosh(double x) diff --git a/libc/math/lib_acoshf.c b/libc/math/lib_acoshf.c index fa5c9549d84594eda95bf2578a3d134a7fb1151b..a676d6a40e4b28c4efcf5d6e13fdcbd56083c0a7 100644 --- a/libc/math/lib_acoshf.c +++ b/libc/math/lib_acoshf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acoshf.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float acoshf(float x) { diff --git a/libc/math/lib_acoshl.c b/libc/math/lib_acoshl.c index bc2cd31da1114822c9f319c434276fc175fedbe8..34a1dec3612fa8bf6602635aadcb50a07594a946 100644 --- a/libc/math/lib_acoshl.c +++ b/libc/math/lib_acoshl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acoshl.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double acoshl(long double x) diff --git a/libc/math/lib_acosl.c b/libc/math/lib_acosl.c index 588d7ed58e4e15486877370af0ec41c73e451c30..f13cb00a04fc46af0a27127f94c5b8b31828c832 100644 --- a/libc/math/lib_acosl.c +++ b/libc/math/lib_acosl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_acos.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double acosl(long double x) diff --git a/libc/math/lib_asin.c b/libc/math/lib_asin.c index 9518fb69c7ee52c586e7b226b0e95285e63a19ea..08a2dc9573bd9a56b736f89e42d8dcf6704144d2 100644 --- a/libc/math/lib_asin.c +++ b/libc/math/lib_asin.c @@ -1,9 +1,9 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sin.c * * This file is a part of NuttX: * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. * Ported by: Darcy Gong * * It derives from the Rhombs OS math library by Nick Johnson which has @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,14 +35,30 @@ #include #include -/************************************************************************ +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef DBL_EPSILON +#define DBL_EPSILON 1e-12 + +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double asin(double x) { - long double y, y_sin, y_cos; + long double y; + long double y_sin; + long double y_cos; + + /* Verify that the input value is in the domain of the function */ + + if (x < -1.0 || x > 1.0) + { + return NAN; + } y = 0; diff --git a/libc/math/lib_asinf.c b/libc/math/lib_asinf.c index 1da555ab86fdb2aaa54d2d3aec7f20f7aa36a12f..e22d32fe7921c9c409ea51cc1efb92e0d1f8c193 100644 --- a/libc/math/lib_asinf.c +++ b/libc/math/lib_asinf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinf.c * * This file is a part of NuttX: @@ -23,18 +23,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float asinf(float x) { diff --git a/libc/math/lib_asinh.c b/libc/math/lib_asinh.c index 5a30ac1aa2563f67b745032f409fa772f3bf1295..ef52323b976439705721a187805eb6319832ae54 100644 --- a/libc/math/lib_asinh.c +++ b/libc/math/lib_asinh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_asinh.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double asinh(double x) diff --git a/libc/math/lib_asinhf.c b/libc/math/lib_asinhf.c index 37141a65c4e962215dfdf52fb38269da32bde569..ba749a6569f56b1e51e3733bfb62f4a76a7d3e4e 100644 --- a/libc/math/lib_asinhf.c +++ b/libc/math/lib_asinhf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_asinhf.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float asinhf(float x) { diff --git a/libc/math/lib_asinhl.c b/libc/math/lib_asinhl.c index b2fb201a382fb1e6f90187163aaa53247a17ef8e..bbbb3d66f6ff762be2b027dc2840db9556d0f6ac 100644 --- a/libc/math/lib_asinhl.c +++ b/libc/math/lib_asinhl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_asinhl.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double asinhl(long double x) diff --git a/libc/math/lib_asinl.c b/libc/math/lib_asinl.c index f51e7deb3db03b5d83721024bd48343f00d48981..466910daf31318879f53e5c2ad334d005dce50da 100644 --- a/libc/math/lib_asinl.c +++ b/libc/math/lib_asinl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,9 +35,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double asinl(long double x) diff --git a/libc/math/lib_atan.c b/libc/math/lib_atan.c index daf5b260348f6dc8de70b61edea692c741d3203e..91930bf03e2cff670bb461643b9047dd58d46989 100644 --- a/libc/math/lib_atan.c +++ b/libc/math/lib_atan.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atan.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -36,9 +36,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double atan(double x) diff --git a/libc/math/lib_atan2.c b/libc/math/lib_atan2.c index 4255214fea8a357b2454550b0a91a1bb879cb814..5b0f7e2989d134db4287d7360f2d9f88abf43a0b 100644 --- a/libc/math/lib_atan2.c +++ b/libc/math/lib_atan2.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atan2.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double atan2(double y, double x) diff --git a/libc/math/lib_atan2f.c b/libc/math/lib_atan2f.c index 8e7d9cea9372e111f7dbfd317b0db46863a49477..5d766df99dbead8bdea17c5f803f4b59799f6d20 100644 --- a/libc/math/lib_atan2f.c +++ b/libc/math/lib_atan2f.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atan2f.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float atan2f(float y, float x) { diff --git a/libc/math/lib_atan2l.c b/libc/math/lib_atan2l.c index 5ea4616be8bef83858e25731cd80e92626b14f4e..4c384e808929a0e565079dace1433654c95f2ebf 100644 --- a/libc/math/lib_atan2l.c +++ b/libc/math/lib_atan2l.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atan2l.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double atan2l(long double y, long double x) diff --git a/libc/math/lib_atanf.c b/libc/math/lib_atanf.c index 2f3638d172bb168352c44275c6c2dc4003ea787a..c9835c6f24da72593d61b98e471459bb67b78421 100644 --- a/libc/math/lib_atanf.c +++ b/libc/math/lib_atanf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atanf.c * * This file is a part of NuttX: @@ -23,19 +23,19 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float atanf(float x) { diff --git a/libc/math/lib_atanh.c b/libc/math/lib_atanh.c index 396e80852a3a2589174359a82d23348534baeff1..4858f41f5bc0d83a5ea728d48234fcd98f72663c 100644 --- a/libc/math/lib_atanh.c +++ b/libc/math/lib_atanh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atanh.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double atanh(double x) diff --git a/libc/math/lib_atanhf.c b/libc/math/lib_atanhf.c index a49ba995c57da79c673e70ff4d1cd7fcb7f097d4..60a6696f73eccd4d2efa83522e220e2f1ef982ef 100644 --- a/libc/math/lib_atanhf.c +++ b/libc/math/lib_atanhf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atanhf.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float atanhf(float x) { diff --git a/libc/math/lib_atanhl.c b/libc/math/lib_atanhl.c index 77a187e51b868eaf0c3fc494bc5ce23f0ddca083..7b3e8367b3c1c8e20de961eb0e6ef772b01bbb65 100644 --- a/libc/math/lib_atanhl.c +++ b/libc/math/lib_atanhl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atanhl.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE long double atanhl(long double x) diff --git a/libc/math/lib_atanl.c b/libc/math/lib_atanl.c index 48dcb03e21c662cec376adf1d2ddda59e0b3b7c8..50376c26a0031a583753c4512ec9bf171c130070 100644 --- a/libc/math/lib_atanl.c +++ b/libc/math/lib_atanl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_atanl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -36,9 +36,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double atanl(long double x) diff --git a/libc/math/lib_ceil.c b/libc/math/lib_ceil.c index 73e4b8ee4a87b5ac366d1ef88d8368700d3976ad..6d367a51c76ba2c2839049b9cea4ba364059077c 100644 --- a/libc/math/lib_ceil.c +++ b/libc/math/lib_ceil.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ceil.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double ceil(double x) diff --git a/libc/math/lib_ceilf.c b/libc/math/lib_ceilf.c index 850e762f25045d47706f6479de53993a8b8a565d..8378141abdc77e037fcf3ec99024f1d63b784a15 100644 --- a/libc/math/lib_ceilf.c +++ b/libc/math/lib_ceilf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ceilf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float ceilf(float x) { diff --git a/libc/math/lib_ceill.c b/libc/math/lib_ceill.c index 3e15ee302d70c42792789ee6fdcfc5164719f895..ac54c2c3db359d8a9c9954cd6d07a3d8923118e3 100644 --- a/libc/math/lib_ceill.c +++ b/libc/math/lib_ceill.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ceil;.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double ceill(long double x) diff --git a/libc/math/lib_copysign.c b/libc/math/lib_copysign.c index ee62504db135396a8b6bdb4a83eec8acbaa18eac..689457cf5f4e8318711d6fd1344df446b7a3e42c 100644 --- a/libc/math/lib_copysign.c +++ b/libc/math/lib_copysign.c @@ -34,18 +34,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double copysign(double x, double y) diff --git a/libc/math/lib_copysignf.c b/libc/math/lib_copysignf.c index 0d12640cc3ab46be2ea980c6cedb80908d082002..9684f68a746131509aaea2385ad88cae79823284 100644 --- a/libc/math/lib_copysignf.c +++ b/libc/math/lib_copysignf.c @@ -34,18 +34,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float copysignf(float x, float y) { diff --git a/libc/math/lib_copysignl.c b/libc/math/lib_copysignl.c index 3a49713b58ca8427855bc50d8e2afb3ef216bb28..b7f99e7728357f1b98f70edfa1e94610da732c7a 100644 --- a/libc/math/lib_copysignl.c +++ b/libc/math/lib_copysignl.c @@ -34,18 +34,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double copysignl(long double x, long double y) diff --git a/libc/math/lib_cos.c b/libc/math/lib_cos.c index cfa0a9a4b91d0626988b6cdf3175fe0120c4e54b..34d90716af2d188ef8a1d6a006e3853cabb2b3e8 100644 --- a/libc/math/lib_cos.c +++ b/libc/math/lib_cos.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_cos.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double cos(double x) diff --git a/libc/math/lib_cosf.c b/libc/math/lib_cosf.c index 2e23419a1df6a0912d91d743bbbebeeaca6b3dee..55ba93c1c8558eca6d84e9e92b574d1cb0b76ee7 100644 --- a/libc/math/lib_cosf.c +++ b/libc/math/lib_cosf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_cosf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float cosf(float x) { diff --git a/libc/math/lib_cosh.c b/libc/math/lib_cosh.c index 40d9ce0c19b4ba0a6b4affb277089aa96c5b8fe1..73283589b5dead02e0f1dc78e56e5aa3af7aeb1a 100644 --- a/libc/math/lib_cosh.c +++ b/libc/math/lib_cosh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_cosh.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double cosh(double x) diff --git a/libc/math/lib_coshf.c b/libc/math/lib_coshf.c index 9a3f728531512dc703a1402870dbb96148c2af3b..7cb575822f24a2c3cc24934383e227f22910edc3 100644 --- a/libc/math/lib_coshf.c +++ b/libc/math/lib_coshf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_coshf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float coshf(float x) { diff --git a/libc/math/lib_coshl.c b/libc/math/lib_coshl.c index b7e58ec7ef59a50c15d17d3f423fd0b3a2aee3d6..445629c24ec53a7680e8e9641e117749458ef19e 100644 --- a/libc/math/lib_coshl.c +++ b/libc/math/lib_coshl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_coshl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double coshl(long double x) diff --git a/libc/math/lib_cosl.c b/libc/math/lib_cosl.c index f328b994a6e1b9587a12e4666045b7cee0fae0a6..89109db77d9c17fb72c2085b94d63b8225eb1582 100644 --- a/libc/math/lib_cosl.c +++ b/libc/math/lib_cosl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_cosl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double cosl(long double x) diff --git a/libc/math/lib_erf.c b/libc/math/lib_erf.c index a41017016165a9aba8144dac4cfa824859a6065a..1923638dbad1a4311afe95a66e303c72e2637c36 100644 --- a/libc/math/lib_erf.c +++ b/libc/math/lib_erf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_erf.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double erf(double x) @@ -64,7 +64,7 @@ double erf(double x) a4 = -1.453152027; a5 = 1.061405429; p = 0.3275911; - + sign = (x >= 0 ? 1 : -1); t = 1.0/(1.0 + p*x); return sign * (1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * expf(-x * x)); diff --git a/libc/math/lib_erff.c b/libc/math/lib_erff.c index 4e773320a1230567cd2d7b783a67e844175c692b..75199c828c2e9649d17e27de4c8e03dca29203d2 100644 --- a/libc/math/lib_erff.c +++ b/libc/math/lib_erff.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_erff.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float erff(float x) { @@ -63,7 +63,7 @@ float erff(float x) a4 = -1.453152027; a5 = 1.061405429; p = 0.3275911; - + sign = (x >= 0 ? 1 : -1); t = 1.0/(1.0 + p*x); return sign * (1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * expf(-x * x)); diff --git a/libc/math/lib_erfl.c b/libc/math/lib_erfl.c index 594e9183bcfb0a81e881f98c1fa5c29282cc5c8f..44d62389808f4b86d7ef57dd3d8924a104ec86bf 100644 --- a/libc/math/lib_erfl.c +++ b/libc/math/lib_erfl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_erfl.c * * Copyright (C) 2015 Brennan Ashton. All rights reserved. @@ -33,18 +33,18 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double erfl(long double x) @@ -64,7 +64,7 @@ long double erfl(long double x) a4 = -1.453152027; a5 = 1.061405429; p = 0.3275911; - + sign = (x >= 0 ? 1 : -1); t = 1.0/(1.0 + p*x); return sign * (1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * expf(-x * x)); diff --git a/libc/math/lib_exp.c b/libc/math/lib_exp.c index c07e6783c9c27b5b5e5a1e760f58e8a1e1eb9261..211b23bf95231094d49ffbd2e738479f0464d4b7 100644 --- a/libc/math/lib_exp.c +++ b/libc/math/lib_exp.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_exp.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,13 +35,13 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_HAVE_DOUBLE -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static double _dbl_inv_fact[] = { @@ -66,9 +66,9 @@ static double _dbl_inv_fact[] = 1.0 / 6402373705728000.0, /* 1 / 18! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ double exp(double x) { diff --git a/libc/math/lib_expf.c b/libc/math/lib_expf.c index eaa9e0d068fa5e80c72f3896fb2722bee58e726e..4ce5208607bd8d5a772aef5523af558bb684d4fe 100644 --- a/libc/math/lib_expf.c +++ b/libc/math/lib_expf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_expf.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static float _flt_inv_fact[] = { @@ -53,9 +53,9 @@ static float _flt_inv_fact[] = 1.0 / 3628800.0, /* 1/10! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float expf(float x) { diff --git a/libc/math/lib_expl.c b/libc/math/lib_expl.c index e14eb586d7f7376d723cbc8b29988719d620a88f..1021017ca3265a19bdba7858cf36727c2fcaf3a4 100644 --- a/libc/math/lib_expl.c +++ b/libc/math/lib_expl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_expl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,13 +35,13 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_HAVE_LONG_DOUBLE -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static long double _ldbl_inv_fact[] = { @@ -66,9 +66,9 @@ static long double _ldbl_inv_fact[] = 1.0 / 6402373705728000.0, /* 1 / 18! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ long double expl(long double x) { diff --git a/libc/math/lib_fabs.c b/libc/math/lib_fabs.c index 635be443f41e76175ada909e00ea285fcfcfd997..35f98e6818f4852bc04a08083db90a79f2c5e0f2 100644 --- a/libc/math/lib_fabs.c +++ b/libc/math/lib_fabs.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fabs.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double fabs(double x) diff --git a/libc/math/lib_fabsf.c b/libc/math/lib_fabsf.c index 629846af3b6fba7a90e2a22546cec499c05c3a78..2bee12097df69f2d5cf1462fb393e78dcb189cd3 100644 --- a/libc/math/lib_fabsf.c +++ b/libc/math/lib_fabsf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fabsf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float fabsf(float x) { diff --git a/libc/math/lib_fabsl.c b/libc/math/lib_fabsl.c index 0ce73a674463b9d17b42d17f1e514503b2bf5a90..1762f9141685f480ace4eb34a26c49f1a24d3a37 100644 --- a/libc/math/lib_fabsl.c +++ b/libc/math/lib_fabsl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fabsl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double fabsl(long double x) diff --git a/libc/math/lib_floor.c b/libc/math/lib_floor.c index ba6278239c6436c59e040c47a4b247de1a308c81..f583dfa6b72f8f1478a59297957cc7337b117ba5 100644 --- a/libc/math/lib_floor.c +++ b/libc/math/lib_floor.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_floor.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double floor(double x) diff --git a/libc/math/lib_floorf.c b/libc/math/lib_floorf.c index 63a2fa7221f078751db44aa3616b18da8fcc7a09..4a4ef1a4f7a28527964492e619bc0a20ae9baeba 100644 --- a/libc/math/lib_floorf.c +++ b/libc/math/lib_floorf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_floorf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float floorf(float x) { diff --git a/libc/math/lib_floorl.c b/libc/math/lib_floorl.c index 28c7e0029f787e2a7200c3a473232a467e45cda1..214ade8ee28ea0b658b4c3e8b5c97e29d604ffee 100644 --- a/libc/math/lib_floorl.c +++ b/libc/math/lib_floorl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_floorl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double floorl(long double x) diff --git a/libc/math/lib_fmod.c b/libc/math/lib_fmod.c index 1bdf3134d84c1d7107543b0eeac11475b2951398..e096d62988899aa4a9dd00a7bf3965b7e9d75f48 100644 --- a/libc/math/lib_fmod.c +++ b/libc/math/lib_fmod.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fmod.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double fmod(double x, double div) diff --git a/libc/math/lib_fmodf.c b/libc/math/lib_fmodf.c index ee1b9070c85ab6adb3a82e66701a2c915204c69f..ba2d375b8e6dbeca44257be7c39d068adc6f10b3 100644 --- a/libc/math/lib_fmodf.c +++ b/libc/math/lib_fmodf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fmodf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float fmodf(float x, float div) { diff --git a/libc/math/lib_fmodl.c b/libc/math/lib_fmodl.c index c5b14e8596386c8d0a81a36dc9741183419d74ec..f72f2de4d74b2f071db82ef089ae519649b36995 100644 --- a/libc/math/lib_fmodl.c +++ b/libc/math/lib_fmodl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_fmodl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double fmodl(long double x, long double div) diff --git a/libc/math/lib_frexp.c b/libc/math/lib_frexp.c index 3319a6bf37f89b21c211ca4ad08dea2f51ef5c11..12eccadbe74e8bcd254e7eedbf1c0498d009fa7c 100644 --- a/libc/math/lib_frexp.c +++ b/libc/math/lib_frexp.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_frexp.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double frexp(double x, int *exponent) diff --git a/libc/math/lib_frexpf.c b/libc/math/lib_frexpf.c index 9cab980fb3b2df3c546b135fd08132722abea840..6ec5aa74425c9dd2adc2252f8513f923db0b579c 100644 --- a/libc/math/lib_frexpf.c +++ b/libc/math/lib_frexpf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_frexpf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float frexpf(float x, int *exponent) { diff --git a/libc/math/lib_frexpl.c b/libc/math/lib_frexpl.c index 627f0e0b5b0d68af1ba062187c3274acccacc280..ae2ec4eb73db346f8ab7cdc5fbeab6ef6e3d90e1 100644 --- a/libc/math/lib_frexpl.c +++ b/libc/math/lib_frexpl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_frexpl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double frexpl(long double x, int *exponent) diff --git a/libc/math/lib_ldexp.c b/libc/math/lib_ldexp.c index 1d6eded8a5db6803690a332a7afaff1f3d4b5b07..ac4d23dccbcec563e07b7964d13479b03e6c0576 100644 --- a/libc/math/lib_ldexp.c +++ b/libc/math/lib_ldexp.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ldexp.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double ldexp(double x, int n) diff --git a/libc/math/lib_ldexpf.c b/libc/math/lib_ldexpf.c index e1500d77e1b55af7a409fb194daadb09b70a1635..12503438b8a4485491d357c47a050d8cbdf7ffb6 100644 --- a/libc/math/lib_ldexpf.c +++ b/libc/math/lib_ldexpf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ldexpf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float ldexpf(float x, int n) { diff --git a/libc/math/lib_ldexpl.c b/libc/math/lib_ldexpl.c index cf12370e0b7ee1a7299942882b1be54f06e93b9b..da02bf7e606a5d6a920752c1d9de7e5725a88b80 100644 --- a/libc/math/lib_ldexpl.c +++ b/libc/math/lib_ldexpl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_ldexpl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double ldexpl(long double x, int n) diff --git a/libc/math/lib_libexpi.c b/libc/math/lib_libexpi.c index 6c26d6b91879b1038f59ae8220beb5c1e345af7f..c8f5793d390286cab704041f450b022780fcdeab 100644 --- a/libc/math/lib_libexpi.c +++ b/libc/math/lib_libexpi.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_libexpi.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,13 +35,13 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ #define M_E2 (M_E * M_E) #define M_E4 (M_E2 * M_E2) @@ -54,9 +54,9 @@ #define M_E512 (M_E256 * M_E256) #define M_E1024 (M_E512 * M_E512) -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static double _expi_square_tbl[11] = { @@ -73,9 +73,9 @@ static double _expi_square_tbl[11] = M_E1024, /* e^1024 */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ double lib_expi(size_t n) { diff --git a/libc/math/lib_libsqrtapprox.c b/libc/math/lib_libsqrtapprox.c index a153f6ed9d414c0408ba7967dda5b2af64d6a1c6..60db0770ad532c0202cff5c6cffe1b449795b309 100644 --- a/libc/math/lib_libsqrtapprox.c +++ b/libc/math/lib_libsqrtapprox.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_libsqrtapprox.c * * This file is a part of NuttX: @@ -23,18 +23,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float lib_sqrtapprox(float x) { diff --git a/libc/math/lib_log.c b/libc/math/lib_log.c index 764726baec78d6d5262ae9aaee5e8f6e2f211e58..8bcfe75bff63a0cedfe8cc19732f6d4a5370f2e9 100644 --- a/libc/math/lib_log.c +++ b/libc/math/lib_log.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,9 +35,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double log(double x) diff --git a/libc/math/lib_log10.c b/libc/math/lib_log10.c index 321b53f208fc8abd399008587eb031836405b427..0830bd7e66821b1effdadb7ad2ef03fe4c65911b 100644 --- a/libc/math/lib_log10.c +++ b/libc/math/lib_log10.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log10.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double log10(double x) diff --git a/libc/math/lib_log10f.c b/libc/math/lib_log10f.c index 3f4ba132817161188ed1b1838b07b52b4439f5de..f0ec9b0589ae92120935124405051f11f9000ada 100644 --- a/libc/math/lib_log10f.c +++ b/libc/math/lib_log10f.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log10f.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float log10f(float x) { diff --git a/libc/math/lib_log10l.c b/libc/math/lib_log10l.c index 713e007de6b7d2aea21398bdb16fed91c612e42f..69e3e7e9784024e7fef22b467fcf2634be140e94 100644 --- a/libc/math/lib_log10l.c +++ b/libc/math/lib_log10l.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log10l.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double log10l(long double x) diff --git a/libc/math/lib_log2.c b/libc/math/lib_log2.c index e929b70cc7d202bb13825403bace3f4bece49d49..2e2007796b30729aa7096f2e8db0ca816baa0d70 100644 --- a/libc/math/lib_log2.c +++ b/libc/math/lib_log2.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log2.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double log2(double x) diff --git a/libc/math/lib_log2f.c b/libc/math/lib_log2f.c index 58d291f6c4c187535f52cb6350a4a3b80ebddc20..a2d351bb1203ae7c36170cd019b83e8857c2b5d8 100644 --- a/libc/math/lib_log2f.c +++ b/libc/math/lib_log2f.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log2f.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float log2f(float x) { diff --git a/libc/math/lib_log2l.c b/libc/math/lib_log2l.c index e130fe6c8fa12d938c1e5901044189b08a1d86a3..0b4450a8090a0064f8d20938dca9c62bd2e25e12 100644 --- a/libc/math/lib_log2l.c +++ b/libc/math/lib_log2l.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_log2l.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double log2l(long double x) diff --git a/libc/math/lib_logf.c b/libc/math/lib_logf.c index cc4f850d0d5ab5647e31c4c496cbffd55c913b11..80eff85c3c7454f3e81bdfb2d22c67e84b8fb2b4 100644 --- a/libc/math/lib_logf.c +++ b/libc/math/lib_logf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_logf.c * * This file is a part of NuttX: @@ -23,18 +23,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float logf(float x) { diff --git a/libc/math/lib_logl.c b/libc/math/lib_logl.c index 9426a506abbd75c26a2a4c799dbc1aebc4fb2b8c..c8babc17a8641ac256457b1eeaec0ac5ec8814b1 100644 --- a/libc/math/lib_logl.c +++ b/libc/math/lib_logl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_lol.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,9 +35,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double logl(long double x) diff --git a/libc/math/lib_modf.c b/libc/math/lib_modf.c index eb56e9c0e66a5121cf3d4db3900cfd515dd2d742..5c0921997cfb3aa6ba4c4e3239fa28b4c33732d9 100644 --- a/libc/math/lib_modf.c +++ b/libc/math/lib_modf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_modf.c * * This file is a part of NuttX: @@ -23,18 +23,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double modf(double x, double *iptr) diff --git a/libc/math/lib_modff.c b/libc/math/lib_modff.c index 81b799253ea800019aa0e8bb15e9f537f1968903..ad07a4f70c93c24f25af43261a8de7a27e8fabe0 100644 --- a/libc/math/lib_modff.c +++ b/libc/math/lib_modff.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_modff.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float modff(float x, float *iptr) { diff --git a/libc/math/lib_modfl.c b/libc/math/lib_modfl.c index f4c30ae051a2d215951cd0c7a0390cae3c12b5d1..45f5f4f8fed936ffd1fbae282cdf22201fd63eb7 100644 --- a/libc/math/lib_modfl.c +++ b/libc/math/lib_modfl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_modfl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,9 +35,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double modfl(long double x, long double *iptr) diff --git a/libc/math/lib_pow.c b/libc/math/lib_pow.c index f8fe18b5ecf38e7549d8f4a537110f67f7971fc0..47eb8d1248960da15b88849c416405934b9498ad 100644 --- a/libc/math/lib_pow.c +++ b/libc/math/lib_pow.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_pow.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double pow(double b, double e) diff --git a/libc/math/lib_powf.c b/libc/math/lib_powf.c index 1797324d4f2a02d4cfb6157a7507df2d3d9b739b..b1614a250098ec50b83c6e394a241bab042efdcf 100644 --- a/libc/math/lib_powf.c +++ b/libc/math/lib_powf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_powf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float powf(float b, float e) { diff --git a/libc/math/lib_powl.c b/libc/math/lib_powl.c index 7d943c58a8815051a2df9a4877b6a783416a8258..2efb84801535f392850a07f82f58951ba803ffc2 100644 --- a/libc/math/lib_powl.c +++ b/libc/math/lib_powl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_powl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double powl(long double b, long double e) diff --git a/libc/math/lib_rint.c b/libc/math/lib_rint.c index 48a2d762f50bbc2b378d5a9a69b0081a712693ad..2e6af43a8776b3124b0a1933d5b53c94e3507050 100644 --- a/libc/math/lib_rint.c +++ b/libc/math/lib_rint.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/fixedmath/lib_rint.c * * Copyright (C) 2007, 2011, 2014 Gregory Nutt. All rights reserved. @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Compilation Switches - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include @@ -47,33 +47,33 @@ #include #include -/************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Function Prototypes - ************************************************************/ + ****************************************************************************/ -/********************************************************** - * Global Constant Data - **********************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ -/************************************************************ - * Global Variables - ************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/********************************************************** +/**************************************************************************** * Private Constant Data - **********************************************************/ + ****************************************************************************/ -/************************************************************ - * Private Variables - ************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ double rint(double x) { @@ -111,7 +111,7 @@ double rint(double x) if (fremainder == -0.5) { - linteger = ((linteger+1)&~1); + linteger = ((linteger + 1) & ~1); } else if (fremainder < -0.5) { @@ -124,7 +124,7 @@ double rint(double x) if (fremainder == 0.5) { - linteger = ((linteger+1)&~1); + linteger = ((linteger + 1) & ~1); } else if (fremainder > 0.5) { diff --git a/libc/math/lib_rintf.c b/libc/math/lib_rintf.c index 83147d82b12f4c8cc249d36417bf0f5511c3a690..ca733e3d7926faf5546c48ff4260607d530a1c32 100644 --- a/libc/math/lib_rintf.c +++ b/libc/math/lib_rintf.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/fixedmath/lib_rintf.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Compilation Switches - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include @@ -47,33 +47,33 @@ #include #include -/************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Function Prototypes - ************************************************************/ + ****************************************************************************/ -/********************************************************** - * Global Constant Data - **********************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ -/************************************************************ - * Global Variables - ************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/********************************************************** +/**************************************************************************** * Private Constant Data - **********************************************************/ + ****************************************************************************/ -/************************************************************ - * Private Variables - ************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ float rintf(float x) { @@ -111,7 +111,7 @@ float rintf(float x) if (fremainder == -0.5) { - linteger = ((linteger+1)&~1); + linteger = ((linteger + 1) & ~1); } else if (fremainder < -0.5) { @@ -124,7 +124,7 @@ float rintf(float x) if (fremainder == 0.5) { - linteger = ((linteger+1)&~1); + linteger = ((linteger + 1) & ~1); } else if (fremainder > 0.5) { diff --git a/libc/math/lib_rintl.c b/libc/math/lib_rintl.c index 5bc6cadbd7c8d9a1f138c645a10ee194cee0e909..03d5de044262a305141d0e8a35b516e121542488 100644 --- a/libc/math/lib_rintl.c +++ b/libc/math/lib_rintl.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/fixedmath/lib_rint.c * * Copyright (C) 2007, 2011, 2014 Gregory Nutt. All rights reserved. @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Compilation Switches - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include @@ -47,33 +47,33 @@ #include #include -/************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Private Function Prototypes - ************************************************************/ + ****************************************************************************/ -/********************************************************** - * Global Constant Data - **********************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ -/************************************************************ - * Global Variables - ************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/********************************************************** +/**************************************************************************** * Private Constant Data - **********************************************************/ + ****************************************************************************/ -/************************************************************ - * Private Variables - ************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ long double rintl(long double x) { @@ -111,7 +111,7 @@ long double rintl(long double x) if (fremainder == -0.5) { - llinteger = ((llinteger+1)&~1); + llinteger = ((llinteger + 1) & ~1); } else if (fremainder < -0.5) { @@ -124,7 +124,7 @@ long double rintl(long double x) if (fremainder == 0.5) { - llinteger = ((llinteger+1)&~1); + llinteger = ((llinteger + 1) & ~1); } else if (fremainder > 0.5) { diff --git a/libc/math/lib_round.c b/libc/math/lib_round.c index 1cf8ba43b8468055ea16ab360b595f6894abb6b5..bc3b332fcc5442ad1af82d12f0ce6f1f3dcf95ac 100644 --- a/libc/math/lib_round.c +++ b/libc/math/lib_round.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * lib/math/lib_round.c * * This file is a part of NuttX: @@ -6,20 +6,20 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * (C) 2012 Petteri Aimonen * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double round(double x) diff --git a/libc/math/lib_roundf.c b/libc/math/lib_roundf.c index b4c0050c0c184f52cb35a6e78375a6716bfb43f0..d85322ddcf3a59224ddaaafb4cdf89630bb9d583 100644 --- a/libc/math/lib_roundf.c +++ b/libc/math/lib_roundf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * lib/math/lib_roundf.c * * This file is a part of NuttX: @@ -6,20 +6,20 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * (C) 2012 Petteri Aimonen * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float roundf(float x) { diff --git a/libc/math/lib_roundl.c b/libc/math/lib_roundl.c index b75bb61f5bfc9aa1d4972a6ca183e0f887beb269..d35c38bf094b2ac970f2c5fb4ae2627284fe18a8 100644 --- a/libc/math/lib_roundl.c +++ b/libc/math/lib_roundl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * lib/math/lib_round.c * * This file is a part of NuttX: @@ -6,20 +6,20 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * (C) 2012 Petteri Aimonen * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double roundl(long double x) diff --git a/libc/math/lib_sin.c b/libc/math/lib_sin.c index 46d8992f89a918a066a0eba54135472d35f64fc6..7ff716b059ce4cb18d0121e50219a95f1bf0a3d1 100644 --- a/libc/math/lib_sin.c +++ b/libc/math/lib_sin.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sin.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -37,9 +37,9 @@ #ifdef CONFIG_HAVE_DOUBLE -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static double _dbl_inv_fact[] = { @@ -55,9 +55,9 @@ static double _dbl_inv_fact[] = 1.0 / 121645100408832000.0, /* 1 / 19! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ double sin(double x) { diff --git a/libc/math/lib_sinf.c b/libc/math/lib_sinf.c index ba2a553ebaf227fd61a7addc6e16083c1c29f453..5f17eb212b2a624c5ba040bbbdc89871a08ed808 100644 --- a/libc/math/lib_sinf.c +++ b/libc/math/lib_sinf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinf.c * * This file is a part of NuttX: @@ -23,18 +23,18 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static float _flt_inv_fact[] = { @@ -46,9 +46,9 @@ static float _flt_inv_fact[] = 1.0 / 39916800.0, /* 1 / 11! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float sinf(float x) { diff --git a/libc/math/lib_sinh.c b/libc/math/lib_sinh.c index 714a52816b7a2949a71de2da8c056dccfc8b7f05..81e84807b9ba05726593cc251a5742d3920fd294 100644 --- a/libc/math/lib_sinh.c +++ b/libc/math/lib_sinh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinh.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double sinh(double x) diff --git a/libc/math/lib_sinhf.c b/libc/math/lib_sinhf.c index b7fc5af13ac0a824137d83beb28a4a1e98e994b9..6b27f59508e958f1da0db38c5b04f283b5210d09 100644 --- a/libc/math/lib_sinhf.c +++ b/libc/math/lib_sinhf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinhf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float sinhf(float x) { diff --git a/libc/math/lib_sinhl.c b/libc/math/lib_sinhl.c index b6ee9764e77200bc3f0886432db070f1f8fff328..ff3aaedb7dead69aaf0dcf5314d3dc07252ee9ef 100644 --- a/libc/math/lib_sinhl.c +++ b/libc/math/lib_sinhl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinhl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double sinhl(long double x) diff --git a/libc/math/lib_sinl.c b/libc/math/lib_sinl.c index b288316b14c5a1d59c62cff2209c8e32f33e8238..dc3df8a4bac2d57bf8870e8cbd921bd9a1269e12 100644 --- a/libc/math/lib_sinl.c +++ b/libc/math/lib_sinl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sinl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -37,9 +37,9 @@ #ifdef CONFIG_HAVE_LONG_DOUBLE -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ static long double _ldbl_inv_fact[] = { @@ -55,9 +55,9 @@ static long double _ldbl_inv_fact[] = 1.0 / 121645100408832000.0, /* 1 / 19! */ }; -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ long double sinl(long double x) { diff --git a/libc/math/lib_sqrt.c b/libc/math/lib_sqrt.c index 9190ac42bba987adff4469580c3c99a590bb4cc5..8540744d21d60a83280d4dfdf01e34a683490029 100644 --- a/libc/math/lib_sqrt.c +++ b/libc/math/lib_sqrt.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sqrt.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,11 +35,11 @@ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double sqrt(double x) diff --git a/libc/math/lib_sqrtf.c b/libc/math/lib_sqrtf.c index a2089c13f102c60dab03fe486170bf5fae68e0dc..e1a107eb8b918dea41a8eb5bd2c66844a5012afe 100644 --- a/libc/math/lib_sqrtf.c +++ b/libc/math/lib_sqrtf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sqrtf.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,11 +35,11 @@ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float sqrtf(float x) { diff --git a/libc/math/lib_sqrtl.c b/libc/math/lib_sqrtl.c index 010d36489caf85d0306454987cd338597e854b07..03a564f72d928b7da44ae6ab53d5c72ea103271b 100644 --- a/libc/math/lib_sqrtl.c +++ b/libc/math/lib_sqrtl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_sqrtl.c * * This file is a part of NuttX: @@ -23,11 +23,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -35,11 +35,11 @@ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double sqrtl(long double x) diff --git a/libc/math/lib_tan.c b/libc/math/lib_tan.c index 02f4d6b8e8894bd55451a486b8c0a29d08e112ed..31cde4cddef512df9132f773bbe83b4e09178417 100644 --- a/libc/math/lib_tan.c +++ b/libc/math/lib_tan.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tan.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double tan(double x) diff --git a/libc/math/lib_tanf.c b/libc/math/lib_tanf.c index 4e0e502d5fa86a51fddf5165286ea907c568406d..97ffae017d3e0109d91b379a007be2349fd07b07 100644 --- a/libc/math/lib_tanf.c +++ b/libc/math/lib_tanf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tanf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float tanf(float x) { diff --git a/libc/math/lib_tanh.c b/libc/math/lib_tanh.c index 6bed476e2010b7f657d52699b3c45312d8784222..e68fcd528c941b5e64f3b083ccb2a9b02e875d87 100644 --- a/libc/math/lib_tanh.c +++ b/libc/math/lib_tanh.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tanh.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double tanh(double x) diff --git a/libc/math/lib_tanhf.c b/libc/math/lib_tanhf.c index 15a57bd8b50f6ac5d4a0901e026809fb4b4b080e..70edb57ec4e176c1c521091701a64ac8ec458c25 100644 --- a/libc/math/lib_tanhf.c +++ b/libc/math/lib_tanhf.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tanhf.c * * This file is a part of NuttX: @@ -23,17 +23,17 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float tanhf(float x) { diff --git a/libc/math/lib_tanhl.c b/libc/math/lib_tanhl.c index c74ec27caf541b6433cb4ecf3e6510214a26a144..ef2250941c1f40c096bd1663a4a36e1ec7ba317c 100644 --- a/libc/math/lib_tanhl.c +++ b/libc/math/lib_tanhl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tanhl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double tanhl(long double x) diff --git a/libc/math/lib_tanl.c b/libc/math/lib_tanl.c index bc32b9b494544846a8f8a0c7e31a213e3b0da26b..16ebce8a7a9c5095d3c1dfb90827cb9f1b1a706d 100644 --- a/libc/math/lib_tanl.c +++ b/libc/math/lib_tanl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/math/lib_tanl.c * * This file is a part of NuttX: @@ -23,20 +23,20 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE long double tanl(long double x) diff --git a/libc/math/lib_trunc.c b/libc/math/lib_trunc.c index 1de0f4b5207a76a7a3fadad093ba644c6eeabc35..3f32577402a00c49bfb7e5c7be551eba4a46cab4 100644 --- a/libc/math/lib_trunc.c +++ b/libc/math/lib_trunc.c @@ -26,9 +26,9 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -36,14 +36,22 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_DOUBLE double trunc(double x) { - union {double f; uint64_t i;} u = {x}; + union + { + double f; + uint64_t i; + } u = + { + x + }; + int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12; uint64_t m; volatile float __x; diff --git a/libc/math/lib_truncf.c b/libc/math/lib_truncf.c index 6093de7334d4aa3a49f1a5c216b1a7d4558fd5d3..97b1f707bd8cf450d4e1229c8f580dea0f0f6069 100644 --- a/libc/math/lib_truncf.c +++ b/libc/math/lib_truncf.c @@ -26,9 +26,9 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -36,13 +36,21 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ float truncf(float x) { - union {float f; uint32_t i;} u = {x}; + union + { + float f; + uint32_t i; + } u = + { + x + }; + int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; uint32_t m; volatile float __x; diff --git a/libc/math/lib_truncl.c b/libc/math/lib_truncl.c index 29f940206360808d5e4a7fd82afe4bdfafcf4caa..8fc87f8a554044ed778cebda187abe372c29aa5b 100644 --- a/libc/math/lib_truncl.c +++ b/libc/math/lib_truncl.c @@ -26,9 +26,9 @@ * ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -37,9 +37,9 @@ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_DOUBLE static const long double toint = 1 / LDBL_EPSILON; @@ -58,7 +58,10 @@ union ldshape long double truncl(long double x) { - union ldshape u = {x}; + union ldshape u = + { + x + }; int e = u.i.se & 0x7fff; int s = u.i.se >> 15; long double y; diff --git a/libc/misc/Make.defs b/libc/misc/Make.defs index b1260b29e3bf0b52b129d02341978b90371caaf0..1a9f7911c18a53b62a79100897bd33b50bfee628 100644 --- a/libc/misc/Make.defs +++ b/libc/misc/Make.defs @@ -36,6 +36,12 @@ # Add the internal C files to the build CSRCS += lib_stream.c lib_filesem.c lib_utsname.c +CSRCS += lib_tea_encrypt.c lib_tea_decrypt.c + +# Support for platforms that do not have long long types + +CSRCS += lib_umul32.c lib_umul64.c lib_umul32x64.c +CSRCS += lib_uadd32x64.c lib_uadd64.c lib_usub64x32.c lib_usub64.c # Add C files that depend on file OR socket descriptors diff --git a/libc/misc/lib_crc32.c b/libc/misc/lib_crc32.c index 0c111a8824a95871774180d339015ab09c85074b..40e7c014a03b600dfe501423bb58caf7e79de925 100644 --- a/libc/misc/lib_crc32.c +++ b/libc/misc/lib_crc32.c @@ -37,7 +37,7 @@ * - The values must be right-shifted by eight bits by the updcrc logic; the shift must * be u_(bring in zeroes). On some hardware you could probably optimize the shift in * assembler by using byte-swap instructions polynomial $edb88320 - ************************************************************************************************/ + ************************************************************************************************/ /************************************************************************************************ * Included Files diff --git a/libc/misc/lib_crc8.c b/libc/misc/lib_crc8.c index 8bd10995f00994e339ede1d5e7f730c98b051791..ae3e01d5d75954b18f2c71e9cee35fd172d601d9 100644 --- a/libc/misc/lib_crc8.c +++ b/libc/misc/lib_crc8.c @@ -47,20 +47,27 @@ /************************************************************************************************ * Private Data - * + ************************************************************************************************/ + +/************************************************************************************************ * CRC8 table generated with: * * #define POLY 0xB2 // ((uint8_t) 0x14D) ^ 0xFF * * printf(" "); - * for (y=0; y<256; y++) - * { - * crc = y; - * for (x=0; x<8; x++) - * crc = (crc & 1) ? POLY ^ (crc >> 1) : crc >> 1; + * for (y = 0; y < 256; y++) + * { + * crc = y; + * for (x = 0; x < 8; x++) + * { + * crc = (crc & 1) ? POLY ^ (crc >> 1) : crc >> 1; + * } + * * printf("0x%02X, ", crc); * if ((y & 0x07) == 0x7) - * printf("\n "); + * { + * printf("\n "); + * } * } * ************************************************************************************************/ @@ -104,6 +111,7 @@ static const uint8_t crc8_tab[256] = /************************************************************************************************ * Public Functions ************************************************************************************************/ + /************************************************************************************************ * Name: crc8part * @@ -138,4 +146,3 @@ uint8_t crc8(FAR const uint8_t *src, size_t len) { return crc8part(src, len, 0); } - diff --git a/libc/misc/lib_dbg.c b/libc/misc/lib_dbg.c index aa0b857bb1816b49946210a7cf96f577e95cd634..14044175b79c494de7441bf7fc4e56daa9856d68 100644 --- a/libc/misc/lib_dbg.c +++ b/libc/misc/lib_dbg.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #ifndef CONFIG_CPP_HAVE_VARARGS diff --git a/libc/misc/lib_filesem.c b/libc/misc/lib_filesem.c index f38ff5f238c7f3247edd3a5c19712a78ce87bbdc..2fd5d1c9ebfa55ab0aaa197d9fa82e5ac243ca10 100644 --- a/libc/misc/lib_filesem.c +++ b/libc/misc/lib_filesem.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/misc/lib_filesem.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,25 +45,25 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if CONFIG_STDIO_BUFFER_SIZE > 0 -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * lib_sem_initialize - ************************************************************************/ + ****************************************************************************/ void lib_sem_initialize(FAR struct file_struct *stream) { @@ -77,9 +77,9 @@ void lib_sem_initialize(FAR struct file_struct *stream) stream->fs_counts = 0; } -/************************************************************************ +/**************************************************************************** * lib_take_semaphore - ************************************************************************/ + ****************************************************************************/ void lib_take_semaphore(FAR struct file_struct *stream) { @@ -113,9 +113,9 @@ void lib_take_semaphore(FAR struct file_struct *stream) } } -/************************************************************************ +/**************************************************************************** * lib_give_semaphore - ************************************************************************/ + ****************************************************************************/ void lib_give_semaphore(FAR struct file_struct *stream) { diff --git a/libc/misc/lib_ioctl.c b/libc/misc/lib_ioctl.c index fa0d908042f10320c4630ce2feb38eb296aa9098..0e7ca015d33755ab16b2a2e5db30e2f9dd860e22 100644 --- a/libc/misc/lib_ioctl.c +++ b/libc/misc/lib_ioctl.c @@ -46,7 +46,7 @@ #include -#include "lib_internal.h" +#include "libc.h" #if defined(CONFIG_LIBC_IOCTL_VARIADIC) && CONFIG_NFILE_DESCRIPTORS > 0 diff --git a/libc/misc/lib_match.c b/libc/misc/lib_match.c index 3bebb1a94632ed44407194a5c31b3bb2f9e86804..690d111a5c7ab6b9be5f6e574fbb82949dfd9a1e 100644 --- a/libc/misc/lib_match.c +++ b/libc/misc/lib_match.c @@ -191,7 +191,7 @@ int match(const char *pattern, const char *string) { const char *or; - for (;;) + for (; ; ) { or = strchr(pattern, '|'); if (or == (char *)0) diff --git a/libc/misc/lib_sendfile.c b/libc/misc/lib_sendfile.c index 56651674f401fa4ec730dfb41ce1b422591a55c2..c5c9b5536b613ba9eb117e872dbf8a29a5825224 100644 --- a/libc/misc/lib_sendfile.c +++ b/libc/misc/lib_sendfile.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/misc/lib_sendfile.c * * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,31 +45,31 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0 -/************************************************************************ +/**************************************************************************** * Private types - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sendfile / lib_sendfile * * Description: @@ -111,7 +111,7 @@ * EINVAL - Bad input parameters. * ENOMEM - Could not allocated an I/O buffer * - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_NET_SENDFILE ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count) diff --git a/libc/misc/lib_stream.c b/libc/misc/lib_stream.c index 2ad3cd740e6c1d2c8cb3fb9003a7ea2072a1eb18..bcf78389b092d7c012ee06208dbb0757fe387927 100644 --- a/libc/misc/lib_stream.c +++ b/libc/misc/lib_stream.c @@ -48,7 +48,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if (!defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_BUILD_KERNEL)) || \ defined(__KERNEL__) @@ -58,7 +58,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/misc/lib_streamsem.c b/libc/misc/lib_streamsem.c index 3397f9907431e3682b2d5ec7875b9562e8803ec0..ae6c2e082930728cf0617667813b2462a59bf0ee 100644 --- a/libc/misc/lib_streamsem.c +++ b/libc/misc/lib_streamsem.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/misc/lib_streamsem.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,27 +46,27 @@ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ +/**************************************************************************** * Private types - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ void stream_semtake(FAR struct streamlist *list) { diff --git a/libc/misc/lib_tea_decrypt.c b/libc/misc/lib_tea_decrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..378407879e45a344ff3749b64432dd9f64cabd42 --- /dev/null +++ b/libc/misc/lib_tea_decrypt.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * libc/misc/lib_tea_decrypt.c + * Tiny Encryption Algorithm - Decryption support + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm: "Following is + * an adaptation of the reference encryption and decryption routines in C, + * released into the public domain by David Wheeler and Roger Needham." + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TEA_KEY_SCHEDULE_CONSTANT 0x9e3779b9 +#define TEA_SUM_SETUP_CONSTANT 0xc6ef3720 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tea_decrypt + * + * Input Parameters: + * value = 2 x 32-bit value (input/output) + * key = 4 x 32-bit Cache key (input) + * + ****************************************************************************/ + +void tea_decrypt(FAR uint32_t *value, FAR const uint32_t *key) +{ + uint32_t v0 = value[0]; + uint32_t v1 = value[1]; + uint32_t sum = TEA_SUM_SETUP_CONSTANT; + int i; + + /* Basic cycle start */ + + for (i = 0; i < 32; i++) + { + v1 -= ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]); + v0 -= ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]); + sum -= TEA_KEY_SCHEDULE_CONSTANT; + } + + /* End cycle */ + + value[0] = v0; + value[1] = v1; +} diff --git a/libc/misc/lib_tea_encrypt.c b/libc/misc/lib_tea_encrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..7ea5e545f74bde8b34d9e0ec9e4642322cfc688d --- /dev/null +++ b/libc/misc/lib_tea_encrypt.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * libc/misc/lib_tea_encrypt.c + * Tiny Encryption Algorithm - Encryption support + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm: "Following is + * an adaptation of the reference encryption and decryption routines in C, + * released into the public domain by David Wheeler and Roger Needham." + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TEA_KEY_SCHEDULE_CONSTANT 0x9e3779b9 +#define TEA_SUM_SETUP_CONSTANT 0xc6ef3720 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tea_encrypt + * + * Input Parameters: + * value = 2 x 32-bit value (input/output) + * key = 4 x 32-bit Cache key (input) + * + ****************************************************************************/ + +void tea_encrypt(FAR uint32_t *value, FAR const uint32_t *key) +{ + uint32_t v0 = value[0]; + uint32_t v1 = value[1]; + uint32_t sum = 0; + int i; + + /* Basic cycle start */ + + for (i = 0; i < 32; i++) + { + sum += TEA_KEY_SCHEDULE_CONSTANT; + v0 += ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]); + v1 += ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]); + } + + /* End cycle */ + + value[0] = v0; + value[1] = v1; +} diff --git a/libc/misc/lib_uadd32x64.c b/libc/misc/lib_uadd32x64.c new file mode 100644 index 0000000000000000000000000000000000000000..68800e55295ada34f6cdc042347d83a61a710ac9 --- /dev/null +++ b/libc/misc/lib_uadd32x64.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * libc/fixedmath/lib_uadd32x64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uadd32x64 + * + * Description: + * Add a 32-bit value to a 64-bit values and return the truncated 64-bit + * sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd32x64(uint32_t term1, FAR const struct uint64_s *term2, + FAR struct uint64_s *sum) +{ + /* Get the MS part of the sum */ + + sum->ms = term2->ms; + + /* Check for carry, i.e., that is when: + * + * term1 + term2->ls > UINT32_MAX + */ + + if ((UINT32_MAX - term1) > term2->ls) + { + sum->ms++; + } + + /* Get the LS part of the sum */ + + sum->ls = term1 + term2->ls; +} diff --git a/libc/misc/lib_uadd64.c b/libc/misc/lib_uadd64.c new file mode 100644 index 0000000000000000000000000000000000000000..c9e634d1eefe778c73b6b8b9a0a93dd95dd83b0c --- /dev/null +++ b/libc/misc/lib_uadd64.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * libc/fixedmath/lib_uadd64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uadd64 + * + * Description: + * Add two 64-bit values and return a 64-bit sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd64(FAR const struct uint64_s *term1, + FAR const struct uint64_s *term2, + FAR struct uint64_s *sum) +{ + /* Get the MS part of the sum */ + + sum->ms = term1->ms + term2->ms; + + /* Check for carry, i.e., that is when: + * + * term1->ls + term2->ls > UINT32_MAX + */ + + if ((UINT32_MAX - term1->ls) > term2->ls) + { + sum->ms++; + } + + /* Get the LS part of the sum */ + + sum->ls = term1->ls + term2->ls; +} diff --git a/libc/misc/lib_umul32.c b/libc/misc/lib_umul32.c new file mode 100644 index 0000000000000000000000000000000000000000..b245e10ee05ebbe9efed9b8db39b509da94d983e --- /dev/null +++ b/libc/misc/lib_umul32.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * libc/fixedmath/lib_umul32.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: umul32 + * + * Description: + * Multiply two 32-bit values, factor1 and factor2, and return the + * full 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul32(uint32_t factor1, uint32_t factor2, FAR struct uint64_s *product) +{ + struct uint64_s part2; + uint32_t ms1; + uint32_t ls1; + uint32_t ms2; + uint32_t ls2; + uint32_t tmp; + + /* factor1 = ms1 << 16 + ls1 + * factor2 = ms2 << 16 + ls2 + */ + + ms1 = factor1 >> 16; + ls1 = factor1 & 0x0000ffff; + ms2 = factor2 >> 16; + ls2 = factor2 & 0x0000ffff; + + /* factor1 * factor2 = (ms1 * ms2 << 32) + + * ls1 * (ms2 << 16) + ls2 * (ms1 << 16) + + * ls1 * ls2 + * part1 = (ms1 * ms2 << 32) + ls1 * ls2 + * part2 = ls1 * (ms2 << 16) + ls2 * (ms1 << 16) + * factor1 * factor2 = part1 + part2 + */ + + product->ms = ms1 * ms2; + product->ls = ls1 * ls2; + + tmp = ls1 * ms2 + ls2 * ms1; + part2.ms = tmp >> 16; + part2.ls = tmp << 16; + + uadd64(product, &part2, product); +} diff --git a/libc/misc/lib_umul32x64.c b/libc/misc/lib_umul32x64.c new file mode 100644 index 0000000000000000000000000000000000000000..ca37fa2ea8d0612e29c786fe2026ea016c02aaca --- /dev/null +++ b/libc/misc/lib_umul32x64.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * libc/fixedmath/lib_umul32x64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: umul32x64 + * + * Description: + * Multiply one 32-bit and one 64-bit values, factor1 and factor2, + * respectively, and return the truncated 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul32x64(uint32_t factor1, FAR const struct uint64_s *factor2, + FAR struct uint64_s *product) +{ + struct uint64_s part1; + struct uint64_s part2; + + /* factor2 = factor2->ms << 32 + factor2->ls + * + * Full 128-bit product: + * factor1 * factor2 = factor1 * (factor2->ms << 32) + + * factor1 * factor2->ls + */ + + /* Get part1 = factor1 * factor2->ms, shifting left by 32-bits + * (truncating to 64-bits) + */ + + part1.ms = factor1 * factor2->ms; + part1.ls = 0; + + /* Get the full 64-bit part2 = factor1 * factor2->ls */ + + umul32(factor1, factor2->ls, &part2); + + /* The product is then the sum */ + + uadd64(&part1, &part2, product); +} diff --git a/libc/misc/lib_umul64.c b/libc/misc/lib_umul64.c new file mode 100644 index 0000000000000000000000000000000000000000..d20612638ef737b9bef027757075512318bf501e --- /dev/null +++ b/libc/misc/lib_umul64.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * libc/fixedmath/lib_umul64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: umul64 + * + * Description: + * Multiply two 64-bit values, factor1 and factor2, and return the + * truncated 64-bit product. + * + * Input Parameters: + * factor1 and factor2 - The values to be multiplied + * product - The location to return the product of the two values. + * + ****************************************************************************/ + +void umul64(FAR const struct uint64_s *factor1, + FAR const struct uint64_s *factor2, + FAR struct uint64_s *product) +{ + struct uint64_s part1; + struct uint64_s part2; + + /* factor1 = factor1->ms << 32 + factor1->ls + * factor2 = factor2->ms << 32 + factor2->ls + * + * Full 128-bit product: + * factor1 * factor2 = (factor1->ms * factor2->ms << 64) + + * factor1->ls * (factor2->ms << 32) + + * factor2->ls * (factor1->ms << 32) + + * factor1->ls * factor2->ls + * + * Truncated, 64-bit product: + * factor1 * factor2 = (factor1->ls * factor2->ms + + * factor2->ls * factor1->ms) << 32) + + * factor1->ls * factor2->ls + * + * part1 = (factor1->ls * factor2->ms + + * factor2->ls * factor1->ms) << 32) + * part2 = factor1->ls * factor2->ls + * factor1 * factor2 = part1 + part2 + */ + + /* Get part1 = factor1->ls * factor2->ms + factor2->ls * factor1->ms, + * shifting left by 32-bits (truncating to 64-bits) + */ + + part1.ms = factor1->ls * factor2->ms + + factor2->ls * factor2->ms; + part1.ls = 0; + + /* Get the full 64-bit part2 = factor1->ls * factor2->ls */ + + umul32(factor1->ls, factor2->ls, &part2); + + /* The product is then the sum */ + + uadd64(&part1, &part2, product); +} diff --git a/libc/misc/lib_usub64.c b/libc/misc/lib_usub64.c new file mode 100644 index 0000000000000000000000000000000000000000..2a327245ece2f047763ebca14e55cee95f5ba3e7 --- /dev/null +++ b/libc/misc/lib_usub64.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * libc/fixedmath/lib_usub64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usub64 + * + * Description: + * Subtract two 64-bit values and return the 64-bit difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64(FAR const struct uint64_s *minuend, + FAR const struct uint64_s *subtrahend, + FAR struct uint64_s *difference) +{ + /* Get the MS part of the difference */ + + difference->ms = minuend->ms - subtrahend->ms; + + /* Check for a borrow, i.e., that is when: + * + * subtrahend->ls > minuend->ls + */ + + if (subtrahend->ls > minuend->ls) + { + difference->ms--; + } + + /* Get the LS part of the difference */ + + difference->ls = minuend->ls - subtrahend->ls; +} diff --git a/libc/misc/lib_usub64x32.c b/libc/misc/lib_usub64x32.c new file mode 100644 index 0000000000000000000000000000000000000000..b691e5105fbdea1096753797887f97ffd4981e24 --- /dev/null +++ b/libc/misc/lib_usub64x32.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * libc/fixedmath/lib_usub64x32.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usub64x32 + * + * Description: + * Subtract a 32-bit value from a 64-bit value and return the 64-bit + * difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64x32(FAR const struct uint64_s *minuend, uint32_t subtrahend, + FAR struct uint64_s *difference) +{ + /* Get the MS part of the difference */ + + difference->ms = minuend->ms; + + /* Check for a borrow, i.e., that is when: + * + * subtrahend->ls > minuend->ls + */ + + if (subtrahend > minuend->ls) + { + difference->ms--; + } + + /* Get the LS part of the difference */ + + difference->ls = minuend->ls - subtrahend; +} diff --git a/libc/misc/lib_utsname.c b/libc/misc/lib_utsname.c index f61584e963a2dc2eef92cfbe38f26812f3fcc246..ff69aa1af4812542c2453d1c6820ff924f86df9c 100644 --- a/libc/misc/lib_utsname.c +++ b/libc/misc/lib_utsname.c @@ -121,6 +121,6 @@ int uname(FAR struct utsname *name) name->machine[SYS_NAMELEN-1] = '\0'; return ret; - } +} #endif /* (!CONFIG_BUILD_PROTECTED) && !CONFIG_BUILD_KERNEL) || __KERNEL__ */ diff --git a/libc/net/Make.defs b/libc/net/Make.defs index 6fe3cce9c2e83110493ba5b689b704dcdfec3183..0d2a7fb4d42a3af7870caf6aa0f7d44b96d655bd 100644 --- a/libc/net/Make.defs +++ b/libc/net/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libc/net/Make.defs # -# Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -38,6 +38,10 @@ CSRCS += lib_addrconfig.c lib_etherntoa.c lib_htons.c lib_htonl.c CSRCS += lib_inetaddr.c lib_inetntoa.c lib_inetntop.c lib_inetpton.c +ifeq ($(CONFIG_NET),y) +CSRCS += lib_shutdown.c +endif + # Routing table support ifeq ($(CONFIG_NET_ROUTE),y) diff --git a/libc/net/lib_addroute.c b/libc/net/lib_addroute.c index b588b4754f376e732e918dbe7c1045850ff37f0b..33a8dd0aadfad7cfaee05ca6fd7546771dd7968e 100644 --- a/libc/net/lib_addroute.c +++ b/libc/net/lib_addroute.c @@ -1,4 +1,4 @@ -/*************************************************************************** +/**************************************************************************** * libc/net/lib_addroute.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Compilation Switches - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Included Files - ***************************************************************************/ + ****************************************************************************/ #include @@ -48,9 +48,9 @@ #include #include -/*************************************************************************** - * Global Functions - ***************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ /**************************************************************************** * Function: net_addroute diff --git a/libc/net/lib_delroute.c b/libc/net/lib_delroute.c index fecec3a834f20f04442318dda0950fe87babaead..862e8ebcbf7f25efa3ca99e6dc7972b5d2eb9a90 100644 --- a/libc/net/lib_delroute.c +++ b/libc/net/lib_delroute.c @@ -1,4 +1,4 @@ -/*************************************************************************** +/**************************************************************************** * libc/net/lib_delroute.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Compilation Switches - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Included Files - ***************************************************************************/ + ****************************************************************************/ #include @@ -49,9 +49,9 @@ #include #include -/*************************************************************************** - * Global Functions - ***************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ /**************************************************************************** * Function: net_delroute diff --git a/libc/net/lib_etherntoa.c b/libc/net/lib_etherntoa.c index 91fb01c570d0af048c337de701f1c99aa6cbd0b4..728b48ae896df6bb16126211162cc2feb3d2e3fe 100644 --- a/libc/net/lib_etherntoa.c +++ b/libc/net/lib_etherntoa.c @@ -44,7 +44,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/net/lib_htonl.c b/libc/net/lib_htonl.c index a10f54f3790a47f920dff07215cd423f95103fe5..dba465583f9a7476927ccefac6636338874c6377 100644 --- a/libc/net/lib_htonl.c +++ b/libc/net/lib_htonl.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/net/lib_ntohl.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,20 +31,20 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************ - * Global Functions - ************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ uint32_t htonl(uint32_t hl) { @@ -54,7 +54,7 @@ uint32_t htonl(uint32_t hl) return (( (hl) >> 24) | (((hl) >> 8) & 0x0000ff00) | (((hl) << 8) & 0x00ff0000) | - ( (hl) << 24)); + ( (hl) << 24)); #endif } diff --git a/libc/net/lib_htons.c b/libc/net/lib_htons.c index 13addd9136eb61b460a4c03e6fcecc33d1701044..ce33b879ea3fbff5c6f309deac7ef4d1b45f5603 100644 --- a/libc/net/lib_htons.c +++ b/libc/net/lib_htons.c @@ -1,4 +1,4 @@ -/*************************************************************************** +/**************************************************************************** * libc/net/lib_htons.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. @@ -31,24 +31,24 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Compilation Switches - ***************************************************************************/ + ****************************************************************************/ -/*************************************************************************** +/**************************************************************************** * Included Files - ***************************************************************************/ + ****************************************************************************/ #include #include #include -/*************************************************************************** - * Global Functions - ***************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ uint16_t htons(uint16_t hs) { diff --git a/libc/net/lib_inetaddr.c b/libc/net/lib_inetaddr.c index c05b5969749a2525c970f5efcda65fa786f5a064..5a2d9a97b237dbc15fe92c370f8273151cf98a25 100644 --- a/libc/net/lib_inetaddr.c +++ b/libc/net/lib_inetaddr.c @@ -55,7 +55,7 @@ * The inet_addr() function converts the string pointed to by cp, in the * standard IPv4 dotted decimal notation, to an integer value suitable for * use as an Internet address. - + * ****************************************************************************/ in_addr_t inet_addr(FAR const char *cp) diff --git a/libc/net/lib_inetntoa.c b/libc/net/lib_inetntoa.c index 9e763de6b47684758e8118c5165fbcf8581d6bd5..a25364ce2d23d7227b6a6f4c9d535659cf4a846c 100644 --- a/libc/net/lib_inetntoa.c +++ b/libc/net/lib_inetntoa.c @@ -47,14 +47,14 @@ #ifdef CONFIG_NET_IPv4 /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** * Name: inet_ntoa * * Description: - * The inet_ntoa() function converts the Internet host address in given in + * The inet_ntoa() function converts the Internet host address given in * network byte order to a string in standard numbers-and-dots notation. * The string is returned in a statically allocated buffer, which subsequent * calls will overwrite. @@ -65,7 +65,7 @@ FAR char *inet_ntoa(struct in_addr in) { static char buffer[INET_ADDRSTRLEN+2]; - FAR unsigned char *ptr = (FAR unsigned char*)&in.s_addr; + FAR unsigned char *ptr = (FAR unsigned char *)&in.s_addr; sprintf(buffer, "%u.%u.%u.%u", ptr[0], ptr[1], ptr[2], ptr[3]); return buffer; } @@ -73,7 +73,7 @@ FAR char *inet_ntoa(struct in_addr in) FAR char *_inet_ntoa(in_addr_t in) { static char buffer[INET_ADDRSTRLEN+2]; - FAR unsigned char *ptr = (FAR unsigned char*)∈ + FAR unsigned char *ptr = (FAR unsigned char *)∈ sprintf(buffer, "%u.%u.%u.%u", ptr[0], ptr[1], ptr[2], ptr[3]); return buffer; } diff --git a/libc/net/lib_inetntop.c b/libc/net/lib_inetntop.c index 460ec31b10b0b7e55c4dbab7a6d96eed6c9f6af7..2a6037f97c421d800145fb0de27fb92e8b9950f1 100644 --- a/libc/net/lib_inetntop.c +++ b/libc/net/lib_inetntop.c @@ -107,7 +107,7 @@ static int inet_ipv4_ntop(FAR const void *src, FAR char *dest, socklen_t size) return -ENOSPC; } - ptr = (FAR char*)src; + ptr = (FAR char *)src; sprintf(dest, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]); return OK; } diff --git a/libc/net/lib_inetpton.c b/libc/net/lib_inetpton.c index c69af48bc15987f8305c2a5390482cb61c5e5b01..8b5eb77dd1fbbec789b87fc3d0eddcb57c47f7e0 100644 --- a/libc/net/lib_inetpton.c +++ b/libc/net/lib_inetpton.c @@ -111,7 +111,7 @@ static int inet_ipv4_pton(FAR const char *src, FAR void *dest) numoffset = 0; ndots = 0; - for (;;) + for (; ; ) { ch = (uint8_t)src[srcoffset++]; @@ -225,7 +225,7 @@ static int inet_ipv6_pton(FAR const char *src, FAR void *dest) nrsep = 0; rtime = false; - for (;;) + for (; ; ) { ch = (uint8_t)src[srcoffset++]; @@ -372,7 +372,7 @@ static int inet_ipv6_pton(FAR const char *src, FAR void *dest) * af - The af argument specifies the family of the address. This can be * AF_INET or AF_INET6. * src - The src argument points to the string being passed in. - * dest - The dest argument points to a numstr into which the function stores + * dest - The dest argument points to memory into which the function stores * the numeric address; this must be large enough to hold the numeric * address (32 bits for AF_INET, 128 bits for AF_INET6). * diff --git a/libc/net/lib_shutdown.c b/libc/net/lib_shutdown.c new file mode 100644 index 0000000000000000000000000000000000000000..028fb96eeb89c0804d9e08513d97cc057b5eaf18 --- /dev/null +++ b/libc/net/lib_shutdown.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * libc/net/lib_shutdown.c + * + * Copyright (c) 2015, Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_NET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: shutdown + * + * Description: + * The shutdown() function will cause all or part of a full-duplex + * connection on the socket associated with the file descriptor socket to + * be shut down. + * + * The shutdown() function disables subsequent send and/or receive + * operations on a socket, depending on the value of the how argument. + * + * Input Paramteers: + * sockfd - Specifies the file descriptor of the socket. + * how - Specifies the type of shutdown. The values are as follows: + * + * SHUT_RD - Disables further receive operations. + * SHUT_WR - Disables further send operations. + * SHUT_RDWR - Disables further send and receive operations. + * + * Returned Value: + * Upon successful completion, shutdown() will return 0; otherwise, -1 will + * be returned and errno set to indicate the error. + * + * EBADF - The socket argument is not a valid file descriptor. + * EINVAL - The how argument is invalid. + * ENOTCONN - The socket is not connected. + * ENOTSOCK - The socket argument does not refer to a socket. + * ENOBUFS - Insufficient resources were available in the system to + * perform the operation. + * + ****************************************************************************/ + +int shutdown(int sockfd, int how) +{ + /* REVISIT: Not implemented. */ + + return OK; +} + +#endif /* CONFIG_NET */ diff --git a/libc/netdb/Make.defs b/libc/netdb/Make.defs index dbddf836d531ba9655bf3c188fe6b9311c19c16a..68b87a288f7363fec0f3b6898ebbf833b8258387 100644 --- a/libc/netdb/Make.defs +++ b/libc/netdb/Make.defs @@ -48,7 +48,12 @@ endif # Add DNS lookup support ifeq ($(CONFIG_NETDB_DNSCLIENT),y) -CSRCS += lib_dnsclient.c +CSRCS += lib_dnsinit.c lib_dnsbind.c lib_dnsquery.c lib_dnsaddserver.c +CSRCS += lib_dnsforeach.c + +ifneq ($(CONFIG_NETDB_DNSCLIENT_ENTRIES),0) +CSRCS += lib_dnscache.c +endif endif # Add the net directory to the build diff --git a/libc/netdb/lib_dns.h b/libc/netdb/lib_dns.h index dee8985f9958d0fdfb47675d87cd0d7b7ae3d11b..9a6f25b7e6395ba8825191fe6acbad98d45bc13b 100644 --- a/libc/netdb/lib_dns.h +++ b/libc/netdb/lib_dns.h @@ -45,6 +45,8 @@ #include +#include + #include #include @@ -57,11 +59,11 @@ /* DNS client configuration **************************************************/ #ifndef CONFIG_NETDB_DNSCLIENT_ENTRIES -# define RESOLV_ENTRIES 4 -#else -# define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES +# define CONFIG_NETDB_DNSCLIENT_ENTRIES 4 #endif +#define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES + #ifndef CONFIG_NETDB_DNSCLIENT_MAXRESPONSE # define CONFIG_NETDB_DNSCLIENT_MAXRESPONSE 96 #endif @@ -74,8 +76,34 @@ # define CONFIG_NETDB_DNSCLIENT_LIFESEC 3600 #endif +#ifndef CONFIG_NETDB_RESOLVCONF_PATH +# define CONFIG_NETDB_RESOLVCONF_PATH "/etc/resolv.conf" +#endif + +#define DNS_MAX_ADDRSTR 48 +#define DNS_MAX_LINE 64 +#define NETDB_DNS_KEYWORD "nameserver" + /**************************************************************************** - * Public Function Prototypes + * Public Types + ****************************************************************************/ +/* This describes either an IPv4 or IPv6 address. It is essentially a named + * alternative to sockaddr_storage. + */ + +union dns_server_u +{ + struct sockaddr addr; /* Common address representation */ +#ifdef CONFIG_NET_IPv4 + struct sockaddr_in ipv4; /* IPv4 address */ +#endif +#ifdef CONFIG_NET_IPv6 + struct sockaddr_in6 ipv6; /* IPv6 address */ +#endif +}; + +/**************************************************************************** + * Public Data ****************************************************************************/ #undef EXTERN @@ -87,6 +115,47 @@ extern "C" #define EXTERN extern #endif +#ifndef CONFIG_NETDB_RESOLVCONF +/* The DNS server address */ + +EXTERN union dns_server_u g_dns_server; +EXTERN bool g_dns_address; /* true: We have the address of the DNS server */ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_initialize + * + * Description: + * Make sure that the DNS client has been properly initialized for use. + * + ****************************************************************************/ + +bool dns_initialize(void); + +/**************************************************************************** + * Name: dns_semtake + * + * Description: + * Take the DNS semaphore, ignoring errors do to the receipt of signals. + * + ****************************************************************************/ + +void dns_semtake(void); + +/**************************************************************************** + * Name: dns_semgive + * + * Description: + * Release the DNS semaphore + * + ****************************************************************************/ + +void dns_semgive(void); + /**************************************************************************** * Name: dns_bind * @@ -129,6 +198,27 @@ int dns_bind(void); int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr, FAR socklen_t *addrlen); +/**************************************************************************** + * Name: dns_save_answer + * + * Description: + * Same the last resolved hostname in the DNS cache + * + * Input Parameters: + * hostname - The hostname string to be cached. + * addr - The IP address associated with the hostname + * addrlen - The size of the of the IP address. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 +void dns_save_answer(FAR const char *hostname, + FAR const struct sockaddr *addr, socklen_t addrlen); +#endif + /**************************************************************************** * Name: dns_find_answer * diff --git a/libc/netdb/lib_dnsaddserver.c b/libc/netdb/lib_dnsaddserver.c new file mode 100644 index 0000000000000000000000000000000000000000..ff2436985a886c5211d46e1ff98b0d30b3e8db45 --- /dev/null +++ b/libc/netdb/lib_dnsaddserver.c @@ -0,0 +1,274 @@ +/**************************************************************************** + * libc/netdb/lib_dnsaddserver.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "netdb/lib_dns.h" + +#ifdef CONFIG_NETDB_DNSCLIENT + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef CONFIG_NETDB_RESOLVCONF +/* The DNS server address */ + +union dns_server_u g_dns_server; +bool g_dns_address; /* true: We have the address of the DNS server */ +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_add_nameserver + * + * Description: + * Configure which DNS server to use for queries + * + ****************************************************************************/ + +#ifdef CONFIG_NETDB_RESOLVCONF +int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) +{ + FAR FILE *stream; + char addrstr[DNS_MAX_ADDRSTR]; +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + uint16_t port; +#endif + int status; + int ret; + + stream = fopen(CONFIG_NETDB_RESOLVCONF_PATH, "at"); + if (stream == NULL) + { + int errcode = errno; + ndbg("ERROR: Failed to open %s: %d\n", + CONFIG_NETDB_RESOLVCONF_PATH, errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + +#ifdef CONFIG_NET_IPv4 + /* Check for an IPv4 address */ + + if (addr->sa_family == AF_INET) + { + if (addrlen < sizeof(struct sockaddr_in)) + { + ret = -EINVAL; + goto errout; + } + else + { + FAR struct sockaddr_in *in4 = (FAR struct sockaddr_in *)addr; + + if (inet_ntop(AF_INET, &in4->sin_addr, addrstr, DNS_MAX_ADDRSTR) == NULL) + { + ret = -errno; + ndbg("ERROR: inet_ntop failed: %d\n", errcode); + DEBUGASSERT(errcode < 0); + goto errout; + } + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* Get the port number */ + + port = ntohs(in4->sin_port); +#endif + } + } + else +#endif + +#ifdef CONFIG_NET_IPv6 + /* Check for an IPv6 address */ + + if (addr->sa_family == AF_INET6) + { + if (addrlen < sizeof(struct sockaddr_in6)) + { + ret = -EINVAL; + goto errout; + } + else + { + FAR struct sockaddr_in6 *in6 = (FAR struct sockaddr_in6 *)addr; + + if (inet_ntop(AF_INET6, &in6->sin6_addr, addrstr, DNS_MAX_ADDRSTR) == NULL) + { + ret = -errno; + ndbg("ERROR: inet_ntop failed: %d\n", errcode); + DEBUGASSERT(errcode < 0); + goto errout; + } + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* Get the port number */ + + port = ntohs(in6->sin6_port); +#endif + } + } + else +#endif + { + nvdbg("ERROR: Unsupported family: %d\n", + g_dns_server.addr.sa_family); + ret = -ENOSYS; + goto errout; + } + + /* Write the new record to the end of the resolv.conf file. */ + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* The OpenBSD version supports a [host]:port syntax. When a non-standard + * port is specified the host address must be enclosed in square brackets. + * For example: + * + * nameserver [10.0.0.1]:5353 + * nameserver [::1]:5353 + */ + + if (port != 0 && port != DNS_DEFAULT_PORT) + { + status = fprintf(stream, "%s [%s]:%u\n", + NETDB_DNS_KEYWORD, addrstr, port); + } + else +#endif + { + status = fprintf(stream, "%s %s\n", + NETDB_DNS_KEYWORD, addrstr); + } + + if (status < 0) + { + ret = -errno; + ndbg("ERROR: fprintf failed: %d\n", errcode); + DEBUGASSERT(errcode < 0); + goto errout; + } + + ret = OK; + +errout: + fclose(stream); + return ret; +} + +#else /* CONFIG_NETDB_RESOLVCONF */ + +int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) +{ + FAR uint16_t *pport; + size_t copylen; + + DEBUGASSERT(addr != NULL); + + /* Copy the new server IP address into our private global data structure */ + +#ifdef CONFIG_NET_IPv4 + /* Check for an IPv4 address */ + + if (addr->sa_family == AF_INET) + { + /* Set up for the IPv4 address copy */ + + copylen = sizeof(struct sockaddr_in); + pport = &g_dns_server.ipv4.sin_port; + } + else +#endif + +#ifdef CONFIG_NET_IPv6 + /* Check for an IPv6 address */ + + if (addr->sa_family == AF_INET6) + { + /* Set up for the IPv6 address copy */ + + copylen = sizeof(struct sockaddr_in6); + pport = &g_dns_server.ipv6.sin6_port; + } + else +#endif + { + nvdbg("ERROR: Unsupported family: %d\n", addr->sa_family); + return -ENOSYS; + } + + /* Copy the IP address */ + + if (addrlen < copylen) + { + nvdbg("ERROR: Invalid addrlen %ld for family %d\n", + (long)addrlen, addr->sa_family); + return -EINVAL; + } + + memcpy(&g_dns_server.addr, addr, copylen); + + /* A port number of zero means to use the default DNS server port number */ + + if (*pport == 0) + { + *pport = HTONS(DNS_DEFAULT_PORT); + } + + /* We now have a valid DNS address */ + + g_dns_address = true; + return OK; +} + +#endif /* CONFIG_NETDB_RESOLVCONF */ +#endif /* CONFIG_NETDB_DNSCLIENT */ diff --git a/libc/netdb/lib_dnsbind.c b/libc/netdb/lib_dnsbind.c new file mode 100644 index 0000000000000000000000000000000000000000..c7eae42953ade19336821dc9426287c48b602894 --- /dev/null +++ b/libc/netdb/lib_dnsbind.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * libc/netdb/lib_dnsclien.c + * + * Copyright (C) 2007, 2009, 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "netdb/lib_dns.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if CONFIG_NSOCKET_DESCRIPTORS < 1 +# error CONFIG_NSOCKET_DESCRIPTORS must be greater than zero +#endif + +#if CONFIG_NET_SOCKOPTS < 1 +# error CONFIG_NET_SOCKOPTS required by this logic +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_bind + * + * Description: + * Initialize the DNS resolver and return a socket bound to the DNS name + * server. The name server was previously selected via dns_server(). + * + * Input Parameters: + * None + * + * Returned Value: + * On success, the bound, non-negative socket descriptor is returned. A + * negated errno value is returned on any failure. + * + ****************************************************************************/ + +int dns_bind(void) +{ + struct timeval tv; + int errcode; + int sd; + int ret; + + /* Has the DNS client been properly initialized? */ + + if (!dns_initialize()) + { + ndbg("ERROR: DNS client has not been initialized\n"); + return -EDESTADDRREQ; + } + + /* Create a new socket */ + + sd = socket(PF_INET, SOCK_DGRAM, 0); + if (sd < 0) + { + errcode = get_errno(); + ndbg("ERROR: socket() failed: %d\n", errcode); + return -errcode; + } + + /* Set up a receive timeout */ + + tv.tv_sec = 30; + tv.tv_usec = 0; + + ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); + if (ret < 0) + { + errcode = get_errno(); + ndbg("ERROR: setsockopt() failed: %d\n", errcode); + close(sd); + return -errcode; + } + + return sd; +} diff --git a/libc/netdb/lib_dnscache.c b/libc/netdb/lib_dnscache.c new file mode 100644 index 0000000000000000000000000000000000000000..72979e4066f4a42d3b3ba603169a2dc13ee93549 --- /dev/null +++ b/libc/netdb/lib_dnscache.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * libc/netdb/lib_dnscache.c + * + * Copyright (C) 2007, 2009, 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "netdb/lib_dns.h" + +#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Use clock monotonic, if possible */ + +#ifdef CONFIG_CLOCK_MONOTONIC +# define DNS_CLOCK CLOCK_MONOTONIC +#else +# define DNS_CLOCK CLOCK_REALTIME +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This described one entry in the cache of resolved hostnames */ + +struct dns_cache_s +{ +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + time_t ctime; /* Creation time */ +#endif + char name[CONFIG_NETDB_DNSCLIENT_NAMESIZE]; + union dns_server_u addr; /* Resolved address */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_dns_head; /* Head of the circular, DNS resolver cache */ +static uint8_t g_dns_tail; /* Tail of the circular, DNS resolver cache */ + +/* This is the DNS resolver cache */ + +static struct dns_cache_s g_dns_cache[CONFIG_NETDB_DNSCLIENT_ENTRIES]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_save_answer + * + * Description: + * Same the last resolved hostname in the DNS cache + * + * Input Parameters: + * hostname - The hostname string to be cached. + * addr - The IP address associated with the hostname + * addrlen - The size of the of the IP address. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void dns_save_answer(FAR const char *hostname, + FAR const struct sockaddr *addr, socklen_t addrlen) +{ + FAR struct dns_cache_s *entry; +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + struct timespec now; +#endif + int next; + int ndx; + + /* Get exclusive access to the DNS cache */ + + dns_semtake(); + + /* Get the index to the new head of the list */ + + ndx = g_dns_head; + next = ndx + 1; + if (next >= CONFIG_NETDB_DNSCLIENT_ENTRIES) + { + next = 0; + } + + /* If the next head pointer would match the tail index, then increment + * the tail index, discarding the oldest mapping in the cache. + */ + + if (next == g_dns_tail) + { + int tmp = g_dns_tail + 1; + if (tmp >= CONFIG_NETDB_DNSCLIENT_ENTRIES) + { + tmp = 0; + } + + g_dns_tail = tmp; + } + + /* Save the answer in the cache */ + + entry = &g_dns_cache[ndx]; + +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + /* Get the current time, using CLOCK_MONOTONIC if possible */ + + (void)clock_settime(DNS_CLOCK, &now); + entry->ctime = (time_t)now.tv_sec; +#endif + + strncpy(entry->name, hostname, CONFIG_NETDB_DNSCLIENT_NAMESIZE); + memcpy(&entry->addr.addr, addr, addrlen); + + /* Save the updated head index */ + + g_dns_head = next; + dns_semgive(); +} + +/**************************************************************************** + * Name: dns_find_answer + * + * Description: + * Check if we already have the resolved hostname address in the cache. + * + * Input Parameters: + * hostname - The hostname string to be resolved. + * addr - The location to return the IP address associated with the + * hostname + * addrlen - On entry, the size of the buffer backing up the 'addr' + * pointer. On return, this location will hold the actual size of + * the returned address. + * + * Returned Value: + * If the host name was successfully found in the DNS name resolution + * cache, zero (OK) will be returned. Otherwise, some negated errno + * value will be returned, typically -ENOENT meaning that the hostname + * was not found in the cache. + * + ****************************************************************************/ + +int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ + FAR struct dns_cache_s *entry; +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + struct timespec now; + uint32_t elapsed; + int ret; +#endif + int next; + int ndx; + + /* If DNS not initialized, no need to proceed */ + + if (!dns_initialize()) + { + ndbg("ERROR: DNS failed to initialize\n"); + return -EAGAIN; + } + + /* Get exclusive access to the DNS cache */ + + dns_semtake(); + +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + /* Get the current time, using CLOCK_MONOTONIC if possible */ + + ret = clock_settime(DNS_CLOCK, &now); +#endif + + /* REVISIT: This is not thread safe */ + + for (ndx = g_dns_tail; ndx != g_dns_head; ndx = next) + { + entry = &g_dns_cache[ndx]; + + /* Advance the index for the next time through the loop, handling + * wrapping to the beginning of the circular buffer. + */ + + next = ndx + 1; + if (next >= CONFIG_NETDB_DNSCLIENT_ENTRIES) + { + next = 0; + } + +#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 + /* Check if this entry has expired + * REVISIT: Does not this calculation assume that the sizeof(time_t) + * is equal to the sizeof(uint32_t)? + */ + + elapsed = (uint32_t)now.tv_sec - (uint32_t)entry->ctime; + if (ret >= 0 && elapsed > CONFIG_NETDB_DNSCLIENT_LIFESEC) + { + /* This entry has expired. Increment the tail index to exclude + * this entry on future traversals. + */ + + g_dns_tail = next; + } + else +#endif + { + /* The entry has not expired, check for a name match. Notice that + * because the names are truncated to CONFIG_NETDB_DNSCLIENT_NAMESIZE, + * this has the possibility of aliasing two names and returning + * the wrong entry from the cache. + */ + + if (strncmp(hostname, entry->name, CONFIG_NETDB_DNSCLIENT_NAMESIZE) == 0) + { + socklen_t inlen; + + /* We have a match. Return the resolved host address */ + +#ifdef CONFIG_NET_IPv4 + if (entry->addr.addr.sa_family == AF_INET) +#ifdef CONFIG_NET_IPv6 +#endif + { + inlen = sizeof(struct sockaddr_in); + } +#endif + +#ifdef CONFIG_NET_IPv6 + else +#ifdef CONFIG_NET_IPv4 +#endif + { + inlen = sizeof(struct sockaddr_in6); + } +#endif + /* Make sure that the address will fit in the caller-provided + * buffer. + */ + + if (*addrlen < inlen) + { + ret = -ERANGE; + goto errout_with_sem; + } + + /* Return the address information */ + + memcpy(addr, &entry->addr.addr, inlen); + *addrlen = inlen; + + dns_semgive(); + return OK; + } + } + } + + ret = -ENOENT; + +errout_with_sem: + dns_semgive(); + return ret; +} + +#endif /* CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 */ + diff --git a/libc/netdb/lib_dnsclient.c b/libc/netdb/lib_dnsclient.c deleted file mode 100644 index a959005f53830446796db82ed0aa3f45a6907571..0000000000000000000000000000000000000000 --- a/libc/netdb/lib_dnsclient.c +++ /dev/null @@ -1,1140 +0,0 @@ -/**************************************************************************** - * libc/netdb/lib_dnsclient.c - * DNS host name to IP address resolver. - * - * The uIP DNS resolver functions are used to lookup a hostname and - * map it to a numerical IP address. - * - * Copyright (C) 2007, 2009, 2012, 2014-2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Based heavily on portions of uIP: - * - * Author: Adam Dunkels - * Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * 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. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "netdb/lib_dns.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* The maximum number of retries when asking for a name */ - -#define MAX_RETRIES 8 - -/* Buffer sizes */ - -#define SEND_BUFFER_SIZE 64 -#define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE - -/* Use clock monotonic, if possible */ - -#ifdef CONFIG_CLOCK_MONOTONIC -# define DNS_CLOCK CLOCK_MONOTONIC -#else -# define DNS_CLOCK CLOCK_REALTIME -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ -/* This describes either an IPv4 or IPv6 address. It is essentially a named - * alternative to sockaddr_storage. - */ - -union dns_server_u -{ - struct sockaddr addr; /* Common address representation */ -#ifdef CONFIG_NET_IPv4 - struct sockaddr_in ipv4; /* IPv4 address */ -#endif -#ifdef CONFIG_NET_IPv6 - struct sockaddr_in6 ipv6; /* IPv6 address */ -#endif -}; - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 -/* This described one entry in the cache of resolved hostnames */ - -struct dns_cache_s -{ -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - time_t ctime; /* Creation time */ -#endif - char name[CONFIG_NETDB_DNSCLIENT_NAMESIZE]; - union dns_server_u addr; /* Resolved address */ -}; -#endif - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static sem_t g_dns_sem; /* Protects g_seqno and DNS cache */ -static bool g_dns_initialized; /* DNS data structures initialized */ -static bool g_dns_address; /* We have the address of the DNS server */ -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 -static uint8_t g_dns_head; /* Head of the circular, DNS resolver cache */ -static uint8_t g_dns_tail; /* Tail of the circular, DNS resolver cache */ -#endif -static uint8_t g_seqno; /* Sequence number of the next request */ - -/* The DNS server address */ - -static union dns_server_u g_dns_server; - -#ifdef CONFIG_NETDB_DNSSERVER_IPv6 -/* This is the default IPv6 DNS server address */ - -static const uint16_t g_ipv6_hostaddr[8] = -{ - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_1), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_2), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_3), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_4), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_5), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_6), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_7), - HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_8) -}; -#endif - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 -/* This is the DNS resolver cache */ - -static struct dns_cache_s g_dns_cache[CONFIG_NETDB_DNSCLIENT_ENTRIES]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: dns_semtake - * - * Description: - * Take the DNS semaphore, ignoring errors do to the receipt of signals. - * - ****************************************************************************/ - -static void dns_semtake(void) -{ - int errcode = 0; - int ret; - - do - { - ret = sem_wait(&g_dns_sem); - if (ret < 0) - { - errcode = get_errno(); - DEBUGASSERT(errcode == EINTR); - } - } - while (ret < 0 && errcode == EINTR); -} - -/**************************************************************************** - * Name: dns_semgive - * - * Description: - * Release the DNS semaphore - * - ****************************************************************************/ - -#define dns_semgive() sem_post(&g_dns_sem) - -/**************************************************************************** - * Name: dns_initialize - * - * Description: - * Make sure that the DNS client has been properly initialized for use. - * - ****************************************************************************/ - -static bool dns_initialize(void) -{ - /* Have DNS data structures been initialized? */ - - if (!g_dns_initialized) - { - sem_init(&g_dns_sem, 0, 1); - g_dns_initialized = true; - } - - /* Has the DNS server IP address been assigned? */ - - if (!g_dns_address) - { -#if defined(CONFIG_NETDB_DNSSERVER_IPv4) - struct sockaddr_in addr4; - int ret; - - /* No, configure the default IPv4 DNS server address */ - - addr4.sin_family = AF_INET; - addr4.sin_port = DNS_DEFAULT_PORT; - addr4.sin_addr.s_addr = HTONL(CONFIG_NETDB_DNSSERVER_IPv4ADDR); - - ret = dns_setserver((FAR struct sockaddr *)&addr4, - sizeof(struct sockaddr_in)); - if (ret < 0) - { - return false; - } - -#elif defined(CONFIG_NETDB_DNSSERVER_IPv6) - struct sockaddr_in6 addr6; - int ret; - - /* No, configure the default IPv6 DNS server address */ - - addr6.sin6_family = AF_INET6; - addr6.sin6_port = DNS_DEFAULT_PORT; - memcpy(addr6.sin6_addr.s6_addr, g_ipv6_hostaddr, 16); - - ret = dns_setserver((FAR struct sockaddr *)&addr6, - sizeof(struct sockaddr_in6)); - if (ret < 0) - { - return false; - } - -#else - /* No, then we are not ready to perform DNS queries */ - - return false; -#endif - } - - return true; -} - -/**************************************************************************** - * Name: dns_save_answer - * - * Description: - * Same the last resolved hostname in the DNS cache - * - * Input Parameters: - * hostname - The hostname string to be cached. - * addr - The IP address associated with the hostname - * addrlen - The size of the of the IP address. - * - * Returned Value: - * None - * - ****************************************************************************/ - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 -static void dns_save_answer(FAR const char *hostname, - FAR const struct sockaddr *addr, - socklen_t addrlen) -{ - FAR struct dns_cache_s *entry; -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - struct timespec now; -#endif - int next; - int ndx; - - /* Get exclusive access to the DNS cache */ - - dns_semtake(); - - /* Get the index to the new head of the list */ - - ndx = g_dns_head; - next = ndx + 1; - if (next >= CONFIG_NETDB_DNSCLIENT_ENTRIES) - { - next = 0; - } - - /* If the next head pointer would match the tail index, then increment - * the tail index, discarding the oldest mapping in the cache. - */ - - if (next == g_dns_tail) - { - int tmp = g_dns_tail + 1; - if (tmp >= CONFIG_NETDB_DNSCLIENT_ENTRIES) - { - tmp = 0; - } - - g_dns_tail = tmp; - } - - /* Save the answer in the cache */ - - entry = &g_dns_cache[ndx]; - -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - /* Get the current time, using CLOCK_MONOTONIC if possible */ - - (void)clock_settime(DNS_CLOCK, &now); - entry->ctime = (time_t)now.tv_sec; -#endif - - strncpy(entry->name, hostname, CONFIG_NETDB_DNSCLIENT_NAMESIZE); - memcpy(&entry->addr.addr, addr, addrlen); - - /* Save the updated head index */ - - g_dns_head = next; - dns_semgive(); -} -#endif - -/**************************************************************************** - * Name: dns_parse_name - * - * Description: - * Walk through a compact encoded DNS name and return the end of it. - * - ****************************************************************************/ - -static FAR uint8_t *dns_parse_name(FAR uint8_t *query) -{ - uint8_t n; - - do - { - n = *query++; - - while (n > 0) - { - ++query; - --n; - } - } - while (*query != 0); - - return query + 1; -} - -/**************************************************************************** - * Name: dns_send_query - * - * Description: - * Runs through the list of names to see if there are any that have - * not yet been queried and, if so, sends out a query. - * - ****************************************************************************/ - -static int dns_send_query(int sd, FAR const char *name, - FAR union dns_server_u *uaddr, uint16_t rectype) -{ - register FAR struct dns_header_s *hdr; - FAR uint8_t *dest; - FAR uint8_t *nptr; - FAR const char *src; - uint8_t buffer[SEND_BUFFER_SIZE]; - uint8_t seqno; - socklen_t addrlen; - int errcode; - int ret; - int n; - - /* Increment the sequence number */ - - dns_semtake(); - seqno = g_seqno++; - dns_semgive(); - - /* Initialize the request header */ - - hdr = (FAR struct dns_header_s *)buffer; - memset(hdr, 0, sizeof(struct dns_header_s)); - hdr->id = htons(seqno); - hdr->flags1 = DNS_FLAG1_RD; - hdr->numquestions = HTONS(1); - dest = buffer + 12; - - /* Convert hostname into suitable query format. */ - - src = name - 1; - do - { - /* Copy the name string */ - - src++; - nptr = dest++; - for (n = 0; *src != '.' && *src != 0; src++) - { - *dest++ = *(uint8_t *)src; - n++; - } - - /* Pre-pend the name length */ - - *nptr = n; - } - while (*src != '\0'); - - /* Add NUL termination, DNS record type, and DNS class */ - - *dest++ = '\0'; /* NUL termination */ - *dest++ = (rectype >> 8); /* DNS record type (big endian) */ - *dest++ = (rectype & 0xff); - *dest++ = (DNS_CLASS_IN >> 8); /* DNS record class (big endian) */ - *dest++ = (DNS_CLASS_IN & 0xff); - - /* Send the request */ - -#ifdef CONFIG_NET_IPv4 -#ifdef CONFIG_NET_IPv6 - if (uaddr->addr.sa_family == AF_INET) -#endif - { - addrlen = sizeof(struct sockaddr_in); - } -#endif - -#ifdef CONFIG_NET_IPv6 -#ifdef CONFIG_NET_IPv4 - else -#endif - { - addrlen = sizeof(struct sockaddr_in6); - } -#endif - - ret = sendto(sd, buffer, dest - buffer, 0, &uaddr->addr, addrlen); - - /* Return the negated errno value on sendto failure */ - - if (ret < 0) - { - errcode = get_errno(); - ndbg("ERROR: sendto failed: %d\n", errcode); - return -errcode; - } - - return OK; -} - -/**************************************************************************** - * Name: dns_recv_response - * - * Description: - * Called when new UDP data arrives - * - ****************************************************************************/ - -static int dns_recv_response(int sd, FAR struct sockaddr *addr, - FAR socklen_t *addrlen) -{ - FAR uint8_t *nameptr; - char buffer[RECV_BUFFER_SIZE]; - FAR struct dns_answer_s *ans; - FAR struct dns_header_s *hdr; -#if 0 /* Not used */ - uint8_t nquestions; -#endif - uint8_t nanswers; - int errcode; - int ret; - - /* Receive the response */ - - ret = recv(sd, buffer, RECV_BUFFER_SIZE, 0); - if (ret < 0) - { - errcode = get_errno(); - ndbg("ERROR: recv failed: %d\n", errcode); - return -errcode; - } - - hdr = (FAR struct dns_header_s *)buffer; - - nvdbg("ID %d\n", htons(hdr->id)); - nvdbg("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); - nvdbg("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); - nvdbg("Num questions %d, answers %d, authrr %d, extrarr %d\n", - htons(hdr->numquestions), htons(hdr->numanswers), - htons(hdr->numauthrr), htons(hdr->numextrarr)); - - /* Check for error */ - - if ((hdr->flags2 & DNS_FLAG2_ERR_MASK) != 0) - { - ndbg("ERROR: DNS reported error: flags2=%02x\n", hdr->flags2); - return -EPROTO; - } - - /* We only care about the question(s) and the answers. The authrr - * and the extrarr are simply discarded. - */ - -#if 0 /* Not used */ - nquestions = htons(hdr->numquestions); -#endif - nanswers = htons(hdr->numanswers); - - /* Skip the name in the question. TODO: This should really be - * checked against the name in the question, to be sure that they - * match. - */ - -#ifdef CONFIG_DEBUG_NET - { - int d = 64; - nameptr = dns_parse_name((uint8_t *)buffer + 12) + 4; - - for (;;) - { - ndbg("%02X %02X %02X %02X %02X %02X %02X %02X \n", - nameptr[0],nameptr[1],nameptr[2],nameptr[3], - nameptr[4],nameptr[5],nameptr[6],nameptr[7]); - - nameptr += 8; - d -= 8; - if (d < 0) - { - break; - } - } - } -#endif - - nameptr = dns_parse_name((uint8_t *)buffer + 12) + 4; - - for (; nanswers > 0; nanswers--) - { - /* The first byte in the answer resource record determines if it - * is a compressed record or a normal one. - */ - - if (*nameptr & 0xc0) - { - /* Compressed name. */ - - nameptr += 2; - nvdbg("Compressed answer\n"); - } - else - { - /* Not compressed name. */ - - nameptr = dns_parse_name(nameptr); - } - - ans = (FAR struct dns_answer_s *)nameptr; - - nvdbg("Answer: type=%04x, class=%04x, ttl=%06x, length=%04x \n", - htons(ans->type), htons(ans->class), - (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]), - htons(ans->len)); - - /* Check for IPv4/6 address type and Internet class. Others are discarded. */ - -#ifdef CONFIG_NET_IPv4 - if (ans->type == HTONS(DNS_RECTYPE_A) && - ans->class == HTONS(DNS_CLASS_IN) && - ans->len == HTONS(4)) - { - ans->u.ipv4.s_addr = *(FAR uint32_t *)(nameptr + 10); - - nvdbg("IPv4 address: %d.%d.%d.%d\n", - (ans->u.ipv4.s_addr ) & 0xff, - (ans->u.ipv4.s_addr >> 8 ) & 0xff, - (ans->u.ipv4.s_addr >> 16 ) & 0xff, - (ans->u.ipv4.s_addr >> 24 ) & 0xff); - - if (*addrlen >= sizeof(struct sockaddr_in)) - { - FAR struct sockaddr_in *inaddr; - - inaddr = (FAR struct sockaddr_in *)addr; - inaddr->sin_family = AF_INET; - inaddr->sin_port = 0; - inaddr->sin_addr.s_addr = ans->u.ipv4.s_addr; - - *addrlen = sizeof(struct sockaddr_in); - return OK; - } - else - { - return -ERANGE; - } - } - else -#endif -#ifdef CONFIG_NET_IPv6 - if (ans->type == HTONS(DNS_RECTYPE_AAAA) && - ans->class == HTONS(DNS_CLASS_IN) && - ans->len == HTONS(16)) - { - memcpy(&ans->u.ipv6.s6_addr, nameptr + 10, 16); - - nvdbg("IPv6 address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - htons(ans->u.ipv6.s6_addr[7]), htons(ans->u.ipv6.s6_addr[6]), - htons(ans->u.ipv6.s6_addr[5]), htons(ans->u.ipv6.s6_addr[4]), - htons(ans->u.ipv6.s6_addr[3]), htons(ans->u.ipv6.s6_addr[2]), - htons(ans->u.ipv6.s6_addr[1]), htons(ans->u.ipv6.s6_addr[0])); - - if (*addrlen >= sizeof(struct sockaddr_in6)) - { - FAR struct sockaddr_in6 *inaddr; - - inaddr = (FAR struct sockaddr_in6 *)addr; - inaddr->sin6_family = AF_INET; - inaddr->sin6_port = 0; - memcpy(inaddr->sin6_addr.s6_addr, ans->u.ipv6.s6_addr, 16); - - *addrlen = sizeof(struct sockaddr_in6); - return OK; - } - else - { - return -ERANGE; - } - } - else -#endif - { - nameptr = nameptr + 10 + htons(ans->len); - } - } - - return -EADDRNOTAVAIL; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: dns_bind - * - * Description: - * Initialize the DNS resolver and return a socket bound to the DNS name - * server. The name server was previously selected via dns_server(). - * - * Input Parameters: - * None - * - * Returned Value: - * On success, the bound, non-negative socket descriptor is returned. A - * negated errno value is returned on any failure. - * - ****************************************************************************/ - -int dns_bind(void) -{ - struct timeval tv; - int errcode; - int sd; - int ret; - - /* Has the DNS client been properly initialized? */ - - if (!dns_initialize()) - { - ndbg("ERROR: DNS client has not been initialized\n"); - return -EDESTADDRREQ; - } - - /* Create a new socket */ - - sd = socket(PF_INET, SOCK_DGRAM, 0); - if (sd < 0) - { - errcode = get_errno(); - ndbg("ERROR: socket() failed: %d\n", errcode); - return -errcode; - } - - /* Set up a receive timeout */ - - tv.tv_sec = 30; - tv.tv_usec = 0; - - ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); - if (ret < 0) - { - errcode = get_errno(); - ndbg("ERROR: setsockopt() failed: %d\n", errcode); - close(sd); - return -errcode; - } - - return sd; -} - -/**************************************************************************** - * Name: dns_query - * - * Description: - * Using the DNS resolver socket (sd), look up the the 'hostname', and - * return its IP address in 'ipaddr' - * - * Input Parameters: - * sd - The socket descriptor previously initialized by dsn_bind(). - * hostname - The hostname string to be resolved. - * addr - The location to return the IP address associated with the - * hostname - * addrlen - On entry, the size of the buffer backing up the 'addr' - * pointer. On return, this location will hold the actual size of - * the returned address. - * - * Returned Value: - * Returns zero (OK) if the query was successful. - * - ****************************************************************************/ - -int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr, - FAR socklen_t *addrlen) -{ -#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) - int noipv4 = false; - int noipv6 = false; -#endif - int retries; - int ret; - - /* Loop while receive timeout errors occur and there are remaining retries */ - - for (retries = 0; retries < 3; retries++) - { -#ifdef CONFIG_NET_IPv4 -#ifdef CONFIG_NET_IPv6 - /* If we know that the IPv4 address is not available, then don't try - * again. - */ - - if (!noipv4) -#endif - { - /* Send the IPv4 query */ - - ret = dns_send_query(sd, hostname, &g_dns_server, DNS_RECTYPE_A); - if (ret < 0) - { - ndbg("ERROR: IPv4 dns_send_query failed: %d\n", ret); - return ret; - } - - /* Obtain the IPv4 response */ - - ret = dns_recv_response(sd, addr, addrlen); - if (ret >= 0) - { - /* IPv4 response received successfully */ - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 - /* Save the answer in the DNS cache */ - - dns_save_answer(hostname, addr, *addrlen); -#endif - return OK; - } - - /* Handle errors */ - - ndbg("ERROR: IPv4 dns_recv_response failed: %d\n", ret); - -#ifdef CONFIG_NET_IPv6 - if (ret != -EADDRNOTAVAIL) - { - /* The IPv4 address is not available. */ - - noipv4 = true; - if (noipv6) - { - /* Neither address is available */ - - return ret; - } - } - else -#endif - if (ret != -EAGAIN) - { - /* Some failure other than receive timeout occurred */ - - return ret; - } - } -#endif - -#ifdef CONFIG_NET_IPv6 -#ifdef CONFIG_NET_IPv4 - /* If we know that the IPv4 address is not available, then don't try - * again. - */ - - if (!noipv6) -#endif - { - /* Send the IPv6 query */ - - ret = dns_send_query(sd, hostname, &g_dns_server, - DNS_RECTYPE_AAAA); - if (ret < 0) - { - ndbg("ERROR: IPv6 dns_send_query failed: %d\n", ret); - return ret; - } - - /* Obtain the IPv6 response */ - - ret = dns_recv_response(sd, addr, addrlen); - if (ret >= 0) - { - /* IPv6 response received successfully */ - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 - /* Save the answer in the DNS cache */ - - dns_save_answer(hostname, addr, *addrlen); -#endif - return OK; - } - - /* Handle errors */ - - ndbg("ERROR: IPv6 dns_recv_response failed: %d\n", ret); - -#ifdef CONFIG_NET_IPv4 - if (ret != -EADDRNOTAVAIL) - { - /* The IPv6 address is not available. */ - - noipv6 = true; - if (noipv4) - { - /* Neither address is available */ - - return ret; - } - } - else -#endif - if (ret != -EAGAIN) - { - /* Some failure other than receive timeout occurred */ - - return ret; - } - } -#endif - } - - return -ETIMEDOUT; -} - -/**************************************************************************** - * Name: dns_setserver - * - * Description: - * Configure which DNS server to use for queries - * - ****************************************************************************/ - -int dns_setserver(FAR const struct sockaddr *addr, socklen_t addrlen) -{ - FAR uint16_t *pport; - size_t copylen; - - DEBUGASSERT(addr != NULL); - - /* Copy the new server IP address into our private global data structure */ - -#ifdef CONFIG_NET_IPv4 - /* Check for an IPv4 address */ - - if (addr->sa_family == AF_INET) - { - /* Set up for the IPv4 address copy */ - - copylen = sizeof(struct sockaddr_in); - pport = &g_dns_server.ipv4.sin_port; - } - else -#endif - -#ifdef CONFIG_NET_IPv6 - /* Check for an IPv6 address */ - - if (addr->sa_family == AF_INET6) - { - /* Set up for the IPv6 address copy */ - - copylen = sizeof(struct sockaddr_in6); - pport = &g_dns_server.ipv6.sin6_port; - } - else -#endif - { - nvdbg("ERROR: Unsupported family: %d\n", addr->sa_family); - return -ENOSYS; - } - - /* Copy the IP address */ - - if (addrlen < copylen) - { - nvdbg("ERROR: Invalid addrlen %ld for family %d\n", - (long)addrlen, addr->sa_family); - return -EINVAL; - } - - memcpy(&g_dns_server.addr, addr, copylen); - - /* A port number of zero means to use the default DNS server port number */ - - if (*pport == 0) - { - *pport = HTONS(DNS_DEFAULT_PORT); - } - - /* We now have a valid DNS address */ - - g_dns_address = true; - return OK; -} - -/**************************************************************************** - * Name: dns_getserver - * - * Description: - * Obtain the currently configured DNS server. - * - ****************************************************************************/ - -int dns_getserver(FAR struct sockaddr *addr, FAR socklen_t *addrlen) -{ - socklen_t copylen; - - DEBUGASSERT(addr != NULL && addrlen != NULL); - -#ifdef CONFIG_NET_IPv4 -#ifdef CONFIG_NET_IPv6 - if (g_dns_server.addr.sa_family == AF_INET) -#endif - { - copylen = sizeof(struct sockaddr_in); - } -#endif - -#ifdef CONFIG_NET_IPv6 -#ifdef CONFIG_NET_IPv4 - else -#endif - { - copylen = sizeof(struct sockaddr_in6); - } -#endif - - /* Copy the DNS server address to the caller-provided buffer */ - - if (copylen > *addrlen) - { - nvdbg("ERROR: addrlen %ld too small for address family %d\n", - (long)addrlen, g_dns_server.addr.sa_family); - return -EINVAL; - } - - memcpy(addr, &g_dns_server.addr, copylen); - *addrlen = copylen; - return OK; -} - -/**************************************************************************** - * Name: dns_find_answer - * - * Description: - * Check if we already have the resolved hostname address in the cache. - * - * Input Parameters: - * hostname - The hostname string to be resolved. - * addr - The location to return the IP address associated with the - * hostname - * addrlen - On entry, the size of the buffer backing up the 'addr' - * pointer. On return, this location will hold the actual size of - * the returned address. - * - * Returned Value: - * If the host name was successfully found in the DNS name resolution - * cache, zero (OK) will be returned. Otherwise, some negated errno - * value will be returned, typically -ENOENT meaning that the hostname - * was not found in the cache. - * - ****************************************************************************/ - -#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 -int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr, - FAR socklen_t *addrlen) -{ - FAR struct dns_cache_s *entry; -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - struct timespec now; - uint32_t elapsed; - int ret; -#endif - int next; - int ndx; - - /* If DNS not initialized, no need to proceed */ - - if (!g_dns_initialized) - { - ndbg("ERROR: DNS not initialized yet\n"); - return -EAGAIN; - } - - /* Get exclusive access to the DNS cache */ - - dns_semtake(); - -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - /* Get the current time, using CLOCK_MONOTONIC if possible */ - - ret = clock_settime(DNS_CLOCK, &now); -#endif - - /* REVISIT: This is not thread safe */ - - for (ndx = g_dns_tail; ndx != g_dns_head; ndx = next) - { - entry = &g_dns_cache[ndx]; - - /* Advance the index for the next time through the loop, handling - * wrapping to the beginning of the circular buffer. - */ - - next = ndx + 1; - if (next >= CONFIG_NETDB_DNSCLIENT_ENTRIES) - { - next = 0; - } - -#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0 - /* Check if this entry has expired - * REVISIT: Does not this calculation assume that the sizeof(time_t) - * is equal to the sizeof(uint32_t)? - */ - - elapsed = (uint32_t)now.tv_sec - (uint32_t)entry->ctime; - if (ret >= 0 && elapsed > CONFIG_NETDB_DNSCLIENT_LIFESEC) - { - /* This entry has expired. Increment the tail index to exclude - * this entry on future traversals. - */ - - g_dns_tail = next; - } - else -#endif - { - /* The entry has not expired, check for a name match. Notice that - * because the names are truncated to CONFIG_NETDB_DNSCLIENT_NAMESIZE, - * this has the possibility of aliasing two names and returning - * the wrong entry from the cache. - */ - - if (strncmp(hostname, entry->name, CONFIG_NETDB_DNSCLIENT_NAMESIZE) == 0) - { - socklen_t inlen; - - /* We have a match. Return the resolved host address */ - -#ifdef CONFIG_NET_IPv4 - if (entry->addr.addr.sa_family == AF_INET) -#ifdef CONFIG_NET_IPv6 -#endif - { - inlen = sizeof(struct sockaddr_in); - } -#endif - -#ifdef CONFIG_NET_IPv6 - else -#ifdef CONFIG_NET_IPv4 -#endif - { - inlen = sizeof(struct sockaddr_in6); - } -#endif - /* Make sure that the address will fit in the caller-provided - * buffer. - */ - - if (*addrlen < inlen) - { - ret = -ERANGE; - goto errout_with_sem; - } - - /* Return the address information */ - - memcpy(addr, &entry->addr.addr, inlen); - *addrlen = inlen; - - dns_semgive(); - return OK; - } - } - } - - ret = -ENOENT; - -errout_with_sem: - dns_semgive(); - return ret; -} -#endif diff --git a/libc/netdb/lib_dnsforeach.c b/libc/netdb/lib_dnsforeach.c new file mode 100644 index 0000000000000000000000000000000000000000..761cc441f38fbe5f8cfe1303a7a5a8d065ee7b23 --- /dev/null +++ b/libc/netdb/lib_dnsforeach.c @@ -0,0 +1,289 @@ +/**************************************************************************** + * libc/netdb/lib_dnsforeach.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "netdb/lib_dns.h" + +#ifdef CONFIG_NETDB_DNSCLIENT + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_NETDB_RESOLVCONF +static FAR char *skip_spaces(FAR char *ptr) +{ + while (isspace(*ptr)) ptr++; + return ptr; +} + +static FAR char *find_spaces(FAR char *ptr) +{ + while (*ptr && !isspace(*ptr)) ptr++; + return ptr; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_foreach_nameserver + * + * Description: + * Traverse each nameserver entry in the resolv.conf file and perform the + * the provided callback. + * + ****************************************************************************/ + +#ifdef CONFIG_NETDB_RESOLVCONF + +int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) +{ + union dns_server_u u; + FAR FILE *stream; + char line[DNS_MAX_LINE]; + FAR char *addrstr; + FAR char *ptr; + uint16_t port; + int keylen; + int ret; + + /* Open the resolver configuration file */ + + stream = fopen(CONFIG_NETDB_RESOLVCONF_PATH, "rb"); + if (stream == NULL) + { + int errcode = errno; + ndbg("ERROR: Failed to open %s: %d\n", + CONFIG_NETDB_RESOLVCONF_PATH, errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + keylen = strlen(NETDB_DNS_KEYWORD); + while (fgets(line, DNS_MAX_LINE, stream) != NULL) + { + ptr = skip_spaces(line); + if (strncmp(ptr, NETDB_DNS_KEYWORD, keylen) == 0) + { + /* Skip over the 'nameserver' keyword */ + + ptr = find_spaces(ptr); + addrstr = skip_spaces(ptr); + if (*addrstr == '\0') + { + ndbg("ERROR: Missing address in %s record\n", + CONFIG_NETDB_RESOLVCONF_PATH); + continue; + } + + /* Make sure that the address string is NUL terminated and + * not followed by garbage. + */ + + ptr = find_spaces(addrstr); + *ptr = '\0'; + + /* Convert the address string to a binary representation. */ + + port = HTONS(DNS_DEFAULT_PORT); + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* The OpenBSD version supports a [host]:port syntax. When a + * non-standard port is specified the host address must be + * enclosed in square brackets. For example: + * + * nameserver [10.0.0.1]:5353 + * nameserver [::1]:5353 + */ + + if (*addrstr == '[') + { + /* Make sure that ther is a right bracket */ + + ptr = strchr(addrstr, ']'); + if (ptr == NULL) + { + ndbg("ERROR: Missing right bracket after %s\n", line); + continue; + } + + /* Replace the right bracket with a NULL terminator */ + + addrstr++; + *ptr++ = '\0'; + + /* Get the port number following the right bracket */ + + if (*ptr == ':') + { + FAR char *portstr; + int tmp; + + /* Isolate the port string */ + + portstr = ptr; + ptr = find_spaces(addrstr); + *ptr = '\0'; + + /* Get the port number */ + + tmp = atoi(portstr); + if (tmp != 0) + { + port = htons(tmp); + } + } + } +#endif /* CONFIG_NETDB_RESOLVCONF_NONSTDPORT */ + +#ifdef CONFIG_NET_IPv4 + /* Try to convert the IPv4 address */ + + ret = inet_pton(AF_INET, addrstr, &u.ipv4.sin_addr); + + /* The inet_pton() function returns 1 if the conversion succeeds */ + + if (ret == 1) + { + u.ipv4.sin_family = AF_INET; + u.ipv4.sin_port = port; + ret = callback(arg, (FAR struct sockaddr *)&u.ipv4, + sizeof(struct sockaddr_in)); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + /* Try to convert the IPv6 address */ + + ret = inet_pton(AF_INET6, addrstr, &u.ipv6.sin6_addr); + + /* The inet_pton() function returns 1 if the conversion + * succeeds. + */ + + if (ret == 1) + { + u.ipv6.sin6_family = AF_INET6; + u.ipv6.sin6_port = port; + ret = callback(arg, (FAR struct sockaddr *)&u.ipv6, + sizeof(struct sockaddr_in6)); + } + else +#endif + { + ndbg("ERROR: Unrecognized address: %s\n", addrstr) + ret = OK; + } +#ifdef CONFIG_NET_IPv6 + } +#endif + if (ret != OK) + { + fclose(stream); + return ret; + } + } + } + + fclose(stream); + return OK; +} + +#else /* CONFIG_NETDB_RESOLVCONF */ + +int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) +{ + int ret = OK; + + if (g_dns_address) + { +#ifdef CONFIG_NET_IPv4 + /* Check for an IPv4 address */ + + if (g_dns_server.addr.sa_family == AF_INET) + { + /* Perform the callback */ + + ret = callback(arg, (FAR struct sockaddr *)&g_dns_server.ipv4, + sizeof(struct sockaddr_in)); + } + else +#endif + +#ifdef CONFIG_NET_IPv6 + /* Check for an IPv6 address */ + + if (g_dns_server.addr.sa_family == AF_INET6) + { + /* Perform the callback */ + + ret = callback(arg, (FAR struct sockaddr *)&g_dns_server.ipv6, + sizeof(struct sockaddr_in6)); + } + else +#endif + { + nvdbg("ERROR: Unsupported family: %d\n", + g_dns_server.addr.sa_family); + ret = -ENOSYS; + } + } + + return ret; +} + +#endif /* CONFIG_NETDB_RESOLVCONF */ +#endif /* CONFIG_NETDB_DNSCLIENT */ diff --git a/libc/netdb/lib_dnsinit.c b/libc/netdb/lib_dnsinit.c new file mode 100644 index 0000000000000000000000000000000000000000..04b490a16752ce70b163a084bf3d87261449d6d4 --- /dev/null +++ b/libc/netdb/lib_dnsinit.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * libc/netdb/lib_dnscache.c + * + * Copyright (C) 2007, 2009, 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "netdb/lib_dns.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_dns_sem; /* Protects g_seqno and DNS cache */ +static bool g_dns_initialized; /* DNS data structures initialized */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#if defined(CONFIG_NETDB_DNSSERVER_IPv6) && !defined(CONFIG_NETDB_RESOLVCONF) + +/* This is the default IPv6 DNS server address */ + +static const uint16_t g_ipv6_hostaddr[8] = +{ + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_1), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_2), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_3), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_4), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_5), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_6), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_7), + HTONS(CONFIG_NETDB_DNSSERVER_IPv6ADDR_8) +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_initialize + * + * Description: + * Make sure that the DNS client has been properly initialized for use. + * + ****************************************************************************/ + +bool dns_initialize(void) +{ + /* Have DNS data structures been initialized? */ + + if (!g_dns_initialized) + { + sem_init(&g_dns_sem, 0, 1); + g_dns_initialized = true; + } + +#ifndef CONFIG_NETDB_RESOLVCONF + /* Has the DNS server IP address been assigned? */ + + if (!g_dns_address) + { +#if defined(CONFIG_NETDB_DNSSERVER_IPv4) + struct sockaddr_in addr4; + int ret; + + /* No, configure the default IPv4 DNS server address */ + + addr4.sin_family = AF_INET; + addr4.sin_port = HTONS(DNS_DEFAULT_PORT); + addr4.sin_addr.s_addr = HTONL(CONFIG_NETDB_DNSSERVER_IPv4ADDR); + + ret = dns_add_nameserver((FAR struct sockaddr *)&addr4, + sizeof(struct sockaddr_in)); + if (ret < 0) + { + return false; + } + +#elif defined(CONFIG_NETDB_DNSSERVER_IPv6) + struct sockaddr_in6 addr6; + int ret; + + /* No, configure the default IPv6 DNS server address */ + + addr6.sin6_family = AF_INET6; + addr6.sin6_port = HTONS(DNS_DEFAULT_PORT); + memcpy(addr6.sin6_addr.s6_addr, g_ipv6_hostaddr, 16); + + ret = dns_add_nameserver((FAR struct sockaddr *)&addr6, + sizeof(struct sockaddr_in6)); + if (ret < 0) + { + return false; + } + +#else + /* Then we are not ready to perform DNS queries */ + + return false; +#endif + } +#endif /* !CONFIG_NETDB_RESOLVCONF */ + + return true; +} + +/**************************************************************************** + * Name: dns_semtake + * + * Description: + * Take the DNS semaphore, ignoring errors do to the receipt of signals. + * + ****************************************************************************/ + +void dns_semtake(void) +{ + int errcode = 0; + int ret; + + do + { + ret = sem_wait(&g_dns_sem); + if (ret < 0) + { + errcode = get_errno(); + DEBUGASSERT(errcode == EINTR); + } + } + while (ret < 0 && errcode == EINTR); +} + +/**************************************************************************** + * Name: dns_semgive + * + * Description: + * Release the DNS semaphore + * + ****************************************************************************/ + +void dns_semgive(void) +{ + DEBUGVERIFY(sem_post(&g_dns_sem)); +} diff --git a/libc/netdb/lib_dnsquery.c b/libc/netdb/lib_dnsquery.c new file mode 100644 index 0000000000000000000000000000000000000000..54a5046fabea960ea2b7ece5971b5526c7facde6 --- /dev/null +++ b/libc/netdb/lib_dnsquery.c @@ -0,0 +1,678 @@ +/**************************************************************************** + * libc/netdb/lib_dnsquery.c + * DNS host name to IP address resolver. + * + * The uIP DNS resolver functions are used to lookup a hostname and + * map it to a numerical IP address. + * + * Copyright (C) 2007, 2009, 2012, 2014-2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based heavily on portions of uIP: + * + * Author: Adam Dunkels + * Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include + +#include "netdb/lib_dns.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The maximum number of retries when asking for a name */ + +#define MAX_RETRIES 8 + +/* Buffer sizes */ + +#define SEND_BUFFER_SIZE 64 +#define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct dns_query_s +{ + int sd; /* DNS server socket */ + int result; /* Explanation of the failure */ + FAR const char *hostname; /* Hostname to lookup */ + FAR struct sockaddr *addr; /* Location to return host address */ + FAR socklen_t *addrlen; /* Length of the address */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_seqno; /* Sequence number of the next request */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_parse_name + * + * Description: + * Walk through a compact encoded DNS name and return the end of it. + * + ****************************************************************************/ + +static FAR uint8_t *dns_parse_name(FAR uint8_t *query) +{ + uint8_t n; + + do + { + n = *query++; + + while (n > 0) + { + ++query; + --n; + } + } + while (*query != 0); + + return query + 1; +} + +/**************************************************************************** + * Name: dns_send_query + * + * Description: + * Runs through the list of names to see if there are any that have + * not yet been queried and, if so, sends out a query. + * + ****************************************************************************/ + +static int dns_send_query(int sd, FAR const char *name, + FAR union dns_server_u *uaddr, uint16_t rectype) +{ + register FAR struct dns_header_s *hdr; + FAR uint8_t *dest; + FAR uint8_t *nptr; + FAR const char *src; + uint8_t buffer[SEND_BUFFER_SIZE]; + uint8_t seqno; + socklen_t addrlen; + int errcode; + int ret; + int n; + + /* Increment the sequence number */ + + dns_semtake(); + seqno = g_seqno++; + dns_semgive(); + + /* Initialize the request header */ + + hdr = (FAR struct dns_header_s *)buffer; + memset(hdr, 0, sizeof(struct dns_header_s)); + hdr->id = htons(seqno); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = HTONS(1); + dest = buffer + 12; + + /* Convert hostname into suitable query format. */ + + src = name - 1; + do + { + /* Copy the name string */ + + src++; + nptr = dest++; + for (n = 0; *src != '.' && *src != 0; src++) + { + *dest++ = *(uint8_t *)src; + n++; + } + + /* Pre-pend the name length */ + + *nptr = n; + } + while (*src != '\0'); + + /* Add NUL termination, DNS record type, and DNS class */ + + *dest++ = '\0'; /* NUL termination */ + *dest++ = (rectype >> 8); /* DNS record type (big endian) */ + *dest++ = (rectype & 0xff); + *dest++ = (DNS_CLASS_IN >> 8); /* DNS record class (big endian) */ + *dest++ = (DNS_CLASS_IN & 0xff); + + /* Send the request */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (uaddr->ipv4.sin_family == AF_INET) +#endif + { + addrlen = sizeof(struct sockaddr_in); + } +#endif + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + addrlen = sizeof(struct sockaddr_in6); + } +#endif + + ret = sendto(sd, buffer, dest - buffer, 0, &uaddr->addr, addrlen); + + /* Return the negated errno value on sendto failure */ + + if (ret < 0) + { + errcode = get_errno(); + ndbg("ERROR: sendto failed: %d\n", errcode); + return -errcode; + } + + return OK; +} + +/**************************************************************************** + * Name: dns_recv_response + * + * Description: + * Called when new UDP data arrives + * + ****************************************************************************/ + +static int dns_recv_response(int sd, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ + FAR uint8_t *nameptr; + char buffer[RECV_BUFFER_SIZE]; + FAR struct dns_answer_s *ans; + FAR struct dns_header_s *hdr; +#if 0 /* Not used */ + uint8_t nquestions; +#endif + uint8_t nanswers; + int errcode; + int ret; + + /* Receive the response */ + + ret = recv(sd, buffer, RECV_BUFFER_SIZE, 0); + if (ret < 0) + { + errcode = get_errno(); + ndbg("ERROR: recv failed: %d\n", errcode); + return -errcode; + } + + hdr = (FAR struct dns_header_s *)buffer; + + nvdbg("ID %d\n", htons(hdr->id)); + nvdbg("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); + nvdbg("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); + nvdbg("Num questions %d, answers %d, authrr %d, extrarr %d\n", + htons(hdr->numquestions), htons(hdr->numanswers), + htons(hdr->numauthrr), htons(hdr->numextrarr)); + + /* Check for error */ + + if ((hdr->flags2 & DNS_FLAG2_ERR_MASK) != 0) + { + ndbg("ERROR: DNS reported error: flags2=%02x\n", hdr->flags2); + return -EPROTO; + } + + /* We only care about the question(s) and the answers. The authrr + * and the extrarr are simply discarded. + */ + +#if 0 /* Not used */ + nquestions = htons(hdr->numquestions); +#endif + nanswers = htons(hdr->numanswers); + + /* Skip the name in the question. TODO: This should really be + * checked against the name in the question, to be sure that they + * match. + */ + +#ifdef CONFIG_DEBUG_NET + { + int d = 64; + nameptr = dns_parse_name((uint8_t *)buffer + 12) + 4; + + for (; ; ) + { + ndbg("%02X %02X %02X %02X %02X %02X %02X %02X \n", + nameptr[0], nameptr[1], nameptr[2], nameptr[3], + nameptr[4], nameptr[5], nameptr[6], nameptr[7]); + + nameptr += 8; + d -= 8; + if (d < 0) + { + break; + } + } + } +#endif + + nameptr = dns_parse_name((uint8_t *)buffer + 12) + 4; + + for (; nanswers > 0; nanswers--) + { + /* The first byte in the answer resource record determines if it + * is a compressed record or a normal one. + */ + + if (*nameptr & 0xc0) + { + /* Compressed name. */ + + nameptr += 2; + nvdbg("Compressed answer\n"); + } + else + { + /* Not compressed name. */ + + nameptr = dns_parse_name(nameptr); + } + + ans = (FAR struct dns_answer_s *)nameptr; + + nvdbg("Answer: type=%04x, class=%04x, ttl=%06x, length=%04x \n", + htons(ans->type), htons(ans->class), + (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]), + htons(ans->len)); + + /* Check for IPv4/6 address type and Internet class. Others are discarded. */ + +#ifdef CONFIG_NET_IPv4 + if (ans->type == HTONS(DNS_RECTYPE_A) && + ans->class == HTONS(DNS_CLASS_IN) && + ans->len == HTONS(4)) + { + ans->u.ipv4.s_addr = *(FAR uint32_t *)(nameptr + 10); + + nvdbg("IPv4 address: %d.%d.%d.%d\n", + (ans->u.ipv4.s_addr ) & 0xff, + (ans->u.ipv4.s_addr >> 8 ) & 0xff, + (ans->u.ipv4.s_addr >> 16) & 0xff, + (ans->u.ipv4.s_addr >> 24) & 0xff); + + if (*addrlen >= sizeof(struct sockaddr_in)) + { + FAR struct sockaddr_in *inaddr; + + inaddr = (FAR struct sockaddr_in *)addr; + inaddr->sin_family = AF_INET; + inaddr->sin_port = 0; + inaddr->sin_addr.s_addr = ans->u.ipv4.s_addr; + + *addrlen = sizeof(struct sockaddr_in); + return OK; + } + else + { + return -ERANGE; + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (ans->type == HTONS(DNS_RECTYPE_AAAA) && + ans->class == HTONS(DNS_CLASS_IN) && + ans->len == HTONS(16)) + { + memcpy(&ans->u.ipv6.s6_addr, nameptr + 10, 16); + + nvdbg("IPv6 address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + htons(ans->u.ipv6.s6_addr[7]), htons(ans->u.ipv6.s6_addr[6]), + htons(ans->u.ipv6.s6_addr[5]), htons(ans->u.ipv6.s6_addr[4]), + htons(ans->u.ipv6.s6_addr[3]), htons(ans->u.ipv6.s6_addr[2]), + htons(ans->u.ipv6.s6_addr[1]), htons(ans->u.ipv6.s6_addr[0])); + + if (*addrlen >= sizeof(struct sockaddr_in6)) + { + FAR struct sockaddr_in6 *inaddr; + + inaddr = (FAR struct sockaddr_in6 *)addr; + inaddr->sin6_family = AF_INET; + inaddr->sin6_port = 0; + memcpy(inaddr->sin6_addr.s6_addr, ans->u.ipv6.s6_addr, 16); + + *addrlen = sizeof(struct sockaddr_in6); + return OK; + } + else + { + return -ERANGE; + } + } + else +#endif + { + nameptr = nameptr + 10 + htons(ans->len); + } + } + + return -EADDRNOTAVAIL; +} + +/**************************************************************************** + * Name: dns_query_callback + * + * Description: + * Using the DNS information and this DNS server address, look up the the + * hostname. + * + * Input Parameters: + * arg - Query arguements + * addr - DNS name server address + * addrlen - Length of the DNS name server address. + * + * Returned Value: + * Returns one (1) if the query was successful. Zero is returned in all + * other cases. The result field of the query structure is set to a + * negated errno value indicate the reason for the last failure (only). + * + ****************************************************************************/ + +static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr, + FAR socklen_t addrlen) +{ + FAR struct dns_query_s *query = (FAR struct dns_query_s *)arg; + int retries; + int ret; + + /* Loop while receive timeout errors occur and there are remaining retries */ + + for (retries = 0; retries < 3; retries++) + { +#ifdef CONFIG_NET_IPv4 + /* Is this an IPv4 address? */ + + if (addr->sa_family == AF_INET) + { + /* Yes.. verify the address size */ + + if (addrlen < sizeof(struct sockaddr_in)) + { + /* Return zero to skip this address and try the next + * namserver address in resolv.conf. + */ + + ndbg("ERROR: Invalid IPv4 address size: %d\n", addrlen); + query->result = -EINVAL; + return 0; + } + + /* Send the IPv4 query */ + + ret = dns_send_query(query->sd, query->hostname, + (FAR union dns_server_u *)addr, + DNS_RECTYPE_A); + if (ret < 0) + { + /* Return zero to skip this address and try the next + * namserver address in resolv.conf. + */ + + ndbg("ERROR: IPv4 dns_send_query failed: %d\n", ret); + query->result = ret; + return 0; + } + + /* Obtain the IPv4 response */ + + ret = dns_recv_response(query->sd, query->addr, query->addrlen); + if (ret >= 0) + { + /* IPv4 response received successfully */ + +#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 + /* Save the answer in the DNS cache */ + + dns_save_answer(query->hostname, query->addr, *query->addrlen); +#endif + /* Return 1 to indicate to (1) stop the traversal, and (2) + * indicate that the address was found. + */ + + return 1; + } + + /* Handle errors */ + + ndbg("ERROR: IPv4 dns_recv_response failed: %d\n", ret); + + if (ret != -EADDRNOTAVAIL) + { + /* The IPv4 address is not available. Return zero to + * continue the tranversal with the next nameserver + * address in resolv.conf. + */ + + query->result = -EADDRNOTAVAIL; + return 0; + } + else if (ret != -EAGAIN) + { + /* Some failure other than receive timeout occurred. Return + * zero to skip this address and try the next namserver + * address in resolv.conf. + */ + + query->result = ret; + return 0; + } + } + else +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 + /* Is this an IPv4 address? */ + + if (query->addr->sa_family == AF_INET6) + { + /* Yes.. verify the address size */ + + if (addrlen < sizeof(struct sockaddr_in6)) + { + /* Return zero to skip this address and try the next + * namserver address in resolv.conf. + */ + + ndbg("ERROR: Invalid IPv6 address size: %d\n", addrlen); + query->result = -EINVAL; + return 0; + } + + /* Send the IPv6 query */ + + ret = dns_send_query(query->sd, query->hostname, + (FAR union dns_server_u *)addr, + DNS_RECTYPE_AAAA); + if (ret < 0) + { + /* Return zero to skip this address and try the next + * namserver address in resolv.conf. + */ + + ndbg("ERROR: IPv6 dns_send_query failed: %d\n", ret); + query->result = ret; + return 0; + } + + /* Obtain the IPv6 response */ + + ret = dns_recv_response(query->sd, query->addr, query->addrlen); + if (ret >= 0) + { + /* IPv6 response received successfully */ + +#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 + /* Save the answer in the DNS cache */ + + dns_save_answer(query->hostname, query->addr, *query->addrlen); +#endif + /* Return 1 to indicate to (1) stop the traversal, and (2) + * indicate that the address was found. + */ + + return 1; + } + + /* Handle errors */ + + ndbg("ERROR: IPv6 dns_recv_response failed: %d\n", ret); + + if (ret != -EADDRNOTAVAIL) + { + /* The IPv6 address is not available. Return zero to + * continue the tranversal with the next nameserver + * address in resolv.conf. + */ + + query->result = -EADDRNOTAVAIL; + return 0; + } + else if (ret != -EAGAIN) + { + /* Some failure other than receive timeout occurred. Return + * zero to skip this address and try the next namserver + * address in resolv.conf. + */ + + query->result = ret; + return 0; + } + } + else +#endif + { + /* Unsupported address family. Return zero to continue the + * tranversal with the next nameserver address in resolv.conf. + */ + + return 0; + } + } + + /* We tried three times and could not communicate with this nameserver. + * Perhaps it is down? Return zero to continue with the next address + * in the resolv.conf file. + */ + + query->result = -ETIMEDOUT; + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_query + * + * Description: + * Using the DNS resolver socket (sd), look up the the 'hostname', and + * return its IP address in 'ipaddr' + * + * Input Parameters: + * sd - The socket descriptor previously initialized by dsn_bind(). + * hostname - The hostname string to be resolved. + * addr - The location to return the IP address associated with the + * hostname + * addrlen - On entry, the size of the buffer backing up the 'addr' + * pointer. On return, this location will hold the actual size of + * the returned address. + * + * Returned Value: + * Returns zero (OK) if the query was successful. + * + ****************************************************************************/ + +int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ + FAR struct dns_query_s query; + int ret; + + /* Set up the query info structure */ + + query.sd = sd; + query.result = -EADDRNOTAVAIL; + query.hostname = hostname; + query.addr = addr; + query.addrlen = addrlen; + + /* Perform the query. dns_foreach_nameserver() will return: + * + * 1 - The query was successful. + * 0 - Look up failed + * <0 - Some other failure (?, shouldn't happen) + */ + + ret = dns_foreach_nameserver(dns_query_callback, &query); + if (ret > 0) + { + /* The lookup was successful */ + + ret = OK; + } + else if (ret == 0) + { + ret = query.result; + } + + return ret; +} diff --git a/libc/netdb/lib_gethostbyaddr.c b/libc/netdb/lib_gethostbyaddr.c index 46c4d6dd56c706d8166db1c164683183b7b8ae2c..c06f165404708aa1159da484661c3721735716b3 100644 --- a/libc/netdb/lib_gethostbyaddr.c +++ b/libc/netdb/lib_gethostbyaddr.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #include "netdb/lib_netdb.h" #ifdef CONFIG_NETDB_HOSTFILE diff --git a/libc/netdb/lib_gethostbyaddrr.c b/libc/netdb/lib_gethostbyaddrr.c index d88527570c599f5400ee83fdb654dc07c66720b0..6dcb8e8ab1d22e8d4a5b3ba5bf22d705249e8f22 100644 --- a/libc/netdb/lib_gethostbyaddrr.c +++ b/libc/netdb/lib_gethostbyaddrr.c @@ -46,28 +46,89 @@ #include #include +#include -#include "lib_internal.h" +#include "libc.h" #include "netdb/lib_netdb.h" #ifdef CONFIG_NETDB_HOSTFILE /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: gethostbyaddr_r + * Name: lib_lo_ipv4match * * Description: - * The gethostbyaddr_r() function returns a structure of type hostent for - * the given host address addr of length len and address type type. Valid - * address types are AF_INET and AF_INET6. The host address argument is a - * pointer to a struct of a type depending on the address type, for example - * a struct in_addr * for address type AF_INET. - * - * gethostbyaddr_r() is *not* POSIX but is similar to a Glibc extension and is - * used internally by NuttX to implement the POSIX gethostbyaddr(). + * Check if the address is the reserved IPv4 address for the local + * loopback device. + * + * Input Parameters: + * addr - The address of the host to find. + * len - The length of the address + * type - The type of the address + * + * Returned Value: + * True if the address is the IPv4 local loopback address. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOOPBACK +static bool lib_lo_ipv4match(FAR const void *addr, socklen_t len, int type) +{ + FAR struct in_addr *ipv4addr; + + if (type == AF_INET && len >= sizeof(struct in_addr)) + { + ipv4addr = (FAR struct in_addr *)addr; + return net_ipv4addr_maskcmp(ipv4addr->sin_addr.s_addr, + g_lo_ipv4addr->s_addr, + g_lo_ipv4addr->s_addr); + } + + return false; +} +#endif + +/**************************************************************************** + * Name: lib_lo_ipv6match + * + * Description: + * Check if the address is the reserved IPv6 address for the local + * loopback device. + * + * Input Parameters: + * addr - The address of the host to find. + * len - The length of the address + * type - The type of the address + * + * Returned Value: + * True if the address is the IPv4 local loopback address. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOOPBACK +static bool lib_lo_ipv6match(FAR const void *addr, socklen_t len, int type) +{ + FAR struct in_addr6 *ipv6addr; + + if (type == AF_INE6T && len >= sizeof(struct in_addr6)) + { + ipv6addr = (FAR struct in_addr6 *)addr; + return net_ipv6addr_cmp(ipv6addr->sin6_addr.s6_addr16, g_lo_ipv6addr); + } + + return false; +} +#endif + +/**************************************************************************** + * Name: lib_localhost + * + * Description: + * Check if the address is the reserved address for the local loopback + * device. * * Input Parameters: * addr - The address of the host to find. @@ -85,24 +146,118 @@ * ****************************************************************************/ -int gethostbyaddr_r(FAR const void *addr, socklen_t len, int type, - FAR struct hostent *host, FAR char *buf, - size_t buflen, int *h_errnop) +#ifdef CONFIG_NET_LOOPBACK +static int lib_localhost(FAR const void *addr, socklen_t len, int type, + FAR struct hostent *host, FAR char *buf, + size_t buflen, int *h_errnop) { - FAR FILE *stream; + FAR struct hostent_info_s *info; + socklen_t addrlen; + FAR const uint8_t *src; + FAR char *dest; + bool match; int herrnocode; - int nread; + int namelen; - DEBUGASSERT(addr != NULL && host != NULL && buf != NULL); - DEBUGASSERT(type == AF_INET || type == AF_INET6); + if (lib_lo_ipv4match(addr, len, type)) + { + /* Setup to transfer the IPv4 address */ - /* Make sure that the h_errno has a non-error code */ + addrlen = sizeof(struct in_addr); + src = (FAR uint8_t *)&g_lo_ipv4addr; + host->h_addrtype = AF_INET; + } + else if (lib_lo_ipv4match(addr, len, type)) + { + /* Setup to transfer the IPv6 address */ + + addrlen = sizeof(struct in6_addr); + src = (FAR uint8_t *)&g_lo_ipv6addr; + host->h_addrtype = AF_INET6; + } + else + { + /* Return 1 meaning that we have no errors but no match either */ + + return 1; + } + /* Make sure that space remains to hold the hostent structure and + * the IP address. + */ + + if (buflen <= (sizeof(struct hostent_info_s) + addrlen)) + { + return -ERANGE; + } + + info = (FAR struct hostent_info_s *)buf; + dest = info->hi_data; + buflen -= (sizeof(struct hostent_info_s) - 1); + + memset(host, 0, sizeof(struct hostent)); + memset(info, 0, sizeof(struct hostent_info_s)); + memcpy(dest, src, addrlen); + + info->hi_addrlist[0] = dest; + host->h_addr_list = info->hi_addrlist; + host->h_length = addrlen; + + dest += addrlen; + buflen -= addrlen; + + /* And copy localhost host name */ + + namelen = strlen(g_lo_hostname); + if (addrlen + namelen + 1 > buflen) + { + herrnocode = ERANGE; + goto errorout_with_herrnocode; + } + + strncpy(dest, g_lo_hostname, buflen); + return 0; + +errorout_with_herrnocode: if (h_errnop) { - *h_errnop = 0; + *h_errnop = herrnocode; } + return ERROR; +} +#endif + +/**************************************************************************** + * Name: lib_hostfile_lookup + * + * Description: + * Try to look-up the host name from the network host file + * + * Input Parameters: + * addr - The address of the host to find. + * len - The length of the address + * type - The type of the address + * host - Caller provided location to return the host data. + * buf - Caller provided buffer to hold string data associated with the + * host data. + * buflen - The size of the caller-provided buffer + * h_errnop - There h_errno value returned in the event of a failure. + * + * Returned Value: + * Zero (OK) is returned on success, -1 (ERROR) is returned on a failure + * with the returned h_errno value provided the reason for the failure. + * + ****************************************************************************/ + +int lib_hostfile_lookup(FAR const void *addr, socklen_t len, int type, + FAR struct hostent *host, FAR char *buf, + size_t buflen, int *h_errnop) +{ + FAR FILE *stream; + int herrnocode; + int nread; + /* Search the hosts file for a match */ stream = fopen(CONFIG_NETDB_HOSTCONF_PATH, "r"); @@ -182,7 +337,83 @@ errorout_with_herrnocode: *h_errnop = herrnocode; } - return ERROR; + return ERROR; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gethostbyaddr_r + * + * Description: + * The gethostbyaddr_r() function returns a structure of type hostent for + * the given host address addr of length len and address type type. Valid + * address types are AF_INET and AF_INET6. The host address argument is a + * pointer to a struct of a type depending on the address type, for example + * a struct in_addr * for address type AF_INET. + * + * gethostbyaddr_r() is *not* POSIX but is similar to a Glibc extension and is + * used internally by NuttX to implement the POSIX gethostbyaddr(). + * + * Input Parameters: + * addr - The address of the host to find. + * len - The length of the address + * type - The type of the address + * host - Caller provided location to return the host data. + * buf - Caller provided buffer to hold string data associated with the + * host data. + * buflen - The size of the caller-provided buffer + * h_errnop - There h_errno value returned in the event of a failure. + * + * Returned Value: + * Zero (OK) is returned on success, -1 (ERROR) is returned on a failure + * with the returned h_errno value provided the reason for the failure. + * + ****************************************************************************/ + +int gethostbyaddr_r(FAR const void *addr, socklen_t len, int type, + FAR struct hostent *host, FAR char *buf, + size_t buflen, int *h_errnop) +{ + FAR FILE *stream; + int herrnocode; + int nread; + + DEBUGASSERT(addr != NULL && host != NULL && buf != NULL); + DEBUGASSERT(type == AF_INET || type == AF_INET6); + + /* Make sure that the h_errno has a non-error code */ + + if (h_errnop) + { + *h_errnop = 0; + } + +#ifdef CONFIG_NET_LOOPBACK + /* Check for the local loopback address */ + + if (lib_localhost(addr, len, type, host, buf, buflen, h_errnop) == 0) + { + /* Yes.. we are done */ + + return OK; + } +#endif + + /* TODO: + * + * 1. Look in the DNS cache to see if we have the address mapping already + * in place. If not, + * 2. Perform a reverse DNS lookup. And if that fails as well, then + * finally + * 3. Search the hosts file for a match. + */ + + /* Search the hosts file for a match */ + + return lib_hostfile_lookup(addr, len, type, host, buf, buflen, h_errnop); } #endif /* CONFIG_NETDB_HOSTFILE */ diff --git a/libc/netdb/lib_gethostbyname.c b/libc/netdb/lib_gethostbyname.c index 4aae74a204e9523415f7ea34d96d01a83824f118..aa492db779218e42dc0e440c8f76d24cc57c4bc4 100644 --- a/libc/netdb/lib_gethostbyname.c +++ b/libc/netdb/lib_gethostbyname.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #include "netdb/lib_netdb.h" #ifdef CONFIG_LIBC_NETDB diff --git a/libc/netdb/lib_gethostbynamer.c b/libc/netdb/lib_gethostbynamer.c index f9bd4af9f0001f6a9c5c85c8688bc5d075d59552..80109dfe7798ac288d7c7e9a900a8f5fc2850353 100644 --- a/libc/netdb/lib_gethostbynamer.c +++ b/libc/netdb/lib_gethostbynamer.c @@ -51,8 +51,9 @@ #include #include +#include -#include "lib_internal.h" +#include "libc.h" #include "netdb/lib_dns.h" #ifdef CONFIG_LIBC_NETDB @@ -85,7 +86,7 @@ struct hostent_info_s * name into the h_name field and its struct in_addr equivalent into the * h_addr_list[0] field of the returned hostent structure. * - * Input paramters: + * Input Parameters: * stream - File stream of the opened hosts file with the file pointer * positioned at the beginning of the next host entry. * host - Caller provided location to return the host data. @@ -111,7 +112,7 @@ static int lib_numeric_address(FAR const char *name, FAR struct hostent *host, * be big enough). */ - if (buflen <= sizeof(struct hostent_info_s)) + if (buflen <= sizeof(struct hostent_info_s)) { return -ERANGE; } @@ -211,6 +212,94 @@ static int lib_numeric_address(FAR const char *name, FAR struct hostent *host, return 0; } +/**************************************************************************** + * Name: lib_localhost + * + * Description: + * Check if the name is the reserved name for the local loopback device. + * + * Input Parameters: + * stream - File stream of the opened hosts file with the file pointer + * positioned at the beginning of the next host entry. + * host - Caller provided location to return the host data. + * buf - Caller provided buffer to hold string data associated with the + * host data. + * buflen - The size of the caller-provided buffer + * + * Returned Value: + * Zero (0) is returned if the name is an numeric IP address. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_LOOPBACK +static int lib_localhost(FAR const char *name, FAR struct hostent *host, + FAR char *buf, size_t buflen) +{ + FAR struct hostent_info_s *info; + socklen_t addrlen; + FAR const char *src; + FAR char *dest; + int namelen; + + if (strcmp(name, "localhost") == 0) + { + /* Yes.. it is the localhost */ + +#ifdef CONFIG_NET_IPv4 + /* Setup to transfer the IPv4 address */ + + addrlen = sizeof(struct in_addr); + src = (FAR const char *)&g_lo_ipv4addr; + host->h_addrtype = AF_INET; + +#else /* CONFIG_NET_IPv6 */ + /* Setup to transfer the IPv6 address */ + + addrlen = sizeof(struct in6_addr); + src = (FAR const char *)&g_lo_ipv6addr; + host->h_addrtype = AF_INET6; +#endif + + /* Make sure that space remains to hold the hostent structure and + * the IP address. + */ + + if (buflen <= (sizeof(struct hostent_info_s) + addrlen)) + { + return -ERANGE; + } + + info = (FAR struct hostent_info_s *)buf; + dest = info->hi_data; + buflen -= (sizeof(struct hostent_info_s) - 1); + + memset(host, 0, sizeof(struct hostent)); + memset(info, 0, sizeof(struct hostent_info_s)); + memcpy(dest, src, addrlen); + + info->hi_addrlist[0] = dest; + host->h_addr_list = info->hi_addrlist; + host->h_length = addrlen; + + dest += addrlen; + buflen -= addrlen; + + /* And copy name */ + + namelen = strlen(name); + if (addrlen + namelen + 1 > buflen) + { + return -ERANGE; + } + + strncpy(dest, name, buflen); + return 0; + } + + return 1; +} +#endif + /**************************************************************************** * Name: lib_find_answer * @@ -236,6 +325,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host, { FAR struct hostent_info_s *info; FAR char *ptr; + FAR void *addrdata; socklen_t addrlen; int addrtype; int namelen; @@ -245,7 +335,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host, * be big enough). */ - if (buflen <= sizeof(struct hostent_info_s)) + if (buflen <= sizeof(struct hostent_info_s)) { return -ERANGE; } @@ -270,7 +360,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host, return ret; } - /* Get the address type; verify the address size. */ + /* Get the address type; verify the address size. */ #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 @@ -280,6 +370,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host, DEBUGASSERT(addrlen == sizeof(struct sockaddr_in)); addrlen = sizeof(struct sockaddr_in); addrtype = AF_INET; + addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr; } #endif @@ -291,12 +382,13 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host, DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6)); addrlen = sizeof(struct sockaddr_in6); addrtype = AF_INET6; + addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr; } #endif /* Yes.. Return the address that we obtained from the DNS cache. */ - info->hi_addrlist[0] = ptr; + info->hi_addrlist[0] = addrdata; host->h_addr_list = info->hi_addrlist; host->h_addrtype = addrtype; host->h_length = addrlen; @@ -377,6 +469,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, { FAR struct hostent_info_s *info; FAR char *ptr; + FAR void *addrdata; socklen_t addrlen; int addrtype; int namelen; @@ -386,7 +479,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, * be big enough). */ - if (buflen <= sizeof(struct hostent_info_s)) + if (buflen <= sizeof(struct hostent_info_s)) { return -ERANGE; } @@ -419,6 +512,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, DEBUGASSERT(addrlen == sizeof(struct sockaddr_in)); addrlen = sizeof(struct sockaddr_in); addrtype = AF_INET; + addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr; } #endif @@ -430,12 +524,13 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6)); addrlen = sizeof(struct sockaddr_in6); addrtype = AF_INET6; + addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr; } #endif /* Yes.. Return the address that we obtained from the DNS name server. */ - info->hi_addrlist[0] = ptr; + info->hi_addrlist[0] = addrdata; host->h_addr_list = info->hi_addrlist; host->h_addrtype = addrtype; host->h_length = addrlen; @@ -465,7 +560,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, * Description: * Try to look-up the host name from the network host file * - * Input paramters: + * Input Parameters: * name - The name of the host to find. * host - Caller provided location to return the host data. * buf - Caller provided buffer to hold string data associated with the @@ -581,7 +676,7 @@ errorout_with_herrnocode: *h_errnop = herrnocode; } - return ERROR; + return ERROR; } #endif /* CONFIG_NETDB_HOSTFILE */ @@ -645,6 +740,17 @@ int gethostbyname_r(FAR const char *name, FAR struct hostent *host, return OK; } +#ifdef CONFIG_NET_LOOPBACK + /* Check for the local loopback host name */ + + if (lib_localhost(name, host, buf, buflen) == 0) + { + /* Yes.. we are done */ + + return OK; + } +#endif + /* Try to find the name in the HOSTALIASES environment variable */ /* REVISIT: Not implemented */ @@ -687,7 +793,7 @@ int gethostbyname_r(FAR const char *name, FAR struct hostent *host, *h_errnop = HOST_NOT_FOUND; } - return ERROR; + return ERROR; #endif } diff --git a/libc/netdb/lib_parsehostfile.c b/libc/netdb/lib_parsehostfile.c index f09c5b85c3c789f76326dab37dd78f4e48666b78..0e2c5bdeff389b1b30312fac5aeb197b6afd757a 100644 --- a/libc/netdb/lib_parsehostfile.c +++ b/libc/netdb/lib_parsehostfile.c @@ -50,7 +50,7 @@ #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_NETDB_HOSTFILE @@ -61,7 +61,7 @@ /* Check if character is any kind of white space (except for newline) */ #define lib_isspace(c) \ - ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\f' || c== '\v') + ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\f' || c == '\v') /**************************************************************************** * Private Type Definitions @@ -279,7 +279,7 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host, * be big enough). */ - if (buflen <= sizeof(struct hostent_info_s)) + if (buflen <= sizeof(struct hostent_info_s)) { return -ERANGE; } diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index a443a699698bb8726dfd49fc3e9029dfbe00927c..44a2d8b2d6342582d94ced94ebfa4a66eb198238 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -46,6 +46,10 @@ CSRCS += pthread_attrinit.c pthread_attrdestroy.c \ pthread_mutexattrinit.c pthread_mutexattrdestroy.c \ pthread_mutexattrgetpshared.c pthread_mutexattrsetpshared.c +ifeq ($(CONFIG_SMP),y) +CSRCS += pthread_attrgetaffinity.c pthread_attrsetaffinity.c +endif + ifeq ($(CONFIG_MUTEX_TYPES),y) CSRCS += pthread_mutexattrsettype.c pthread_mutexattrgettype.c endif diff --git a/libc/pthread/pthread_attrdestroy.c b/libc/pthread/pthread_attrdestroy.c index 0e2091808a608dc47de1b67608ae5fc5fd12a795..04223f0e047d93b5b3b20f5bb15545519326e8f3 100644 --- a/libc/pthread/pthread_attrdestroy.c +++ b/libc/pthread/pthread_attrdestroy.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetaffinity.c b/libc/pthread/pthread_attrgetaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..c13ee71d0b5d7bee64bcdfd38c5a64864a413afc --- /dev/null +++ b/libc/pthread/pthread_attrgetaffinity.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * libc/pthread/pthread_attrgetaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_attr_getaffinity + * + * Description: + * + * Parameters: + * attr + * cpuset + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ****************************************************************************/ + +int pthread_attr_getaffinity_np(FAR const pthread_attr_t *attr, + size_t cpusetsize, cpu_set_t *cpuset) +{ + sdbg("attr=0x%p cpusetsize=%d cpuset=0x%p\n", attr, (int)cpusetsize, cpuset); + + DEBUGASSERT(attr != NULL && cpusetsize == sizeof(cpu_set_t) && cpuset != NULL); + + *cpuset = attr->affinity; + return OK; +} diff --git a/libc/pthread/pthread_attrgetinheritsched.c b/libc/pthread/pthread_attrgetinheritsched.c index 4471c98e597df9c4f353f30f68a59826b295db26..c4c2838dae495544c3a2de062b8947167241e999 100644 --- a/libc/pthread/pthread_attrgetinheritsched.c +++ b/libc/pthread/pthread_attrgetinheritsched.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetschedpolicy.c b/libc/pthread/pthread_attrgetschedpolicy.c index 1c3b47ba67d3842cc07f3237c8205bd8440e1b99..52a48a9504aadd34532f0c9cb8f3ce9dc13ca315 100644 --- a/libc/pthread/pthread_attrgetschedpolicy.c +++ b/libc/pthread/pthread_attrgetschedpolicy.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrgetstacksize.c b/libc/pthread/pthread_attrgetstacksize.c index 4b3cd4b9148d9d7a37e8be49d9d063a6ab17b1b6..ea95ec7328ab30e4b26560019a39120a4f99ce85 100644 --- a/libc/pthread/pthread_attrgetstacksize.c +++ b/libc/pthread/pthread_attrgetstacksize.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrinit.c b/libc/pthread/pthread_attrinit.c index 3a304629f2843eccf2d5ab58a612b34d41d2675d..e073fcd89fb925511b6cfba33f098109b49a456d 100644 --- a/libc/pthread/pthread_attrinit.c +++ b/libc/pthread/pthread_attrinit.c @@ -47,15 +47,7 @@ #include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /* Default pthread attributes (see include/nuttx/pthread.h). When configured @@ -69,14 +61,6 @@ const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER; #endif -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrsetaffinity.c b/libc/pthread/pthread_attrsetaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..0222dfdd7db0d538091773621ff26d61d13c56a1 --- /dev/null +++ b/libc/pthread/pthread_attrsetaffinity.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * libc/pthread/pthread_attrsetaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_attr_setaffinity + * + * Description: + * + * Parameters: + * attr + * stacksize + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ****************************************************************************/ + +int pthread_attr_setaffinity_np(FAR pthread_attr_t *attr, + size_t cpusetsize, + FAR const cpu_set_t *cpuset) +{ + sdbg("attr=0x%p cpusetsize=%d cpuset=0x%p\n", attr, (int)cpusetsize, cpuset); + + DEBUGASSERT(attr != NULL && cpusetsize == sizeof(cpu_set_t) && + cpuset != NULL && *cpuset != 0); + + attr->affinity = *cpuset; + return OK; +} diff --git a/libc/pthread/pthread_attrsetinheritsched.c b/libc/pthread/pthread_attrsetinheritsched.c index ccbe81626de9d69641a343c3c5b040569d47ec66..07506773ad02e6005172ea64a67f4204df54a897 100644 --- a/libc/pthread/pthread_attrsetinheritsched.c +++ b/libc/pthread/pthread_attrsetinheritsched.c @@ -45,26 +45,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_attrsetstacksize.c b/libc/pthread/pthread_attrsetstacksize.c index 8a19105981a5b32681da6b1fa13cd416a7571f90..97769acd259bbc8d2fcecd6d24cbf94e002bb369 100644 --- a/libc/pthread/pthread_attrsetstacksize.c +++ b/libc/pthread/pthread_attrsetstacksize.c @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrdestroy.c b/libc/pthread/pthread_barrierattrdestroy.c index 7699ecdfda682319061e7b89dda7cef983d3298d..98342e28c151fc7c25622752dd7e28e37c97e085 100644 --- a/libc/pthread/pthread_barrierattrdestroy.c +++ b/libc/pthread/pthread_barrierattrdestroy.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrgetpshared.c b/libc/pthread/pthread_barrierattrgetpshared.c index ebd2ef81e9b09e7a534f02f8306515b8abd73d64..ce186f230ab403a86e99feb2513cfb1d154a5dee 100644 --- a/libc/pthread/pthread_barrierattrgetpshared.c +++ b/libc/pthread/pthread_barrierattrgetpshared.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrinit.c b/libc/pthread/pthread_barrierattrinit.c index c1fc8f95d0bf51648e49980b961f7dad780ec0ab..16c31922d79c61f3095c2db325cb528d6594feb8 100644 --- a/libc/pthread/pthread_barrierattrinit.c +++ b/libc/pthread/pthread_barrierattrinit.c @@ -43,26 +43,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/libc/pthread/pthread_barrierattrsetpshared.c b/libc/pthread/pthread_barrierattrsetpshared.c index da08de538449fdb5d6a384e0e309d092aba89a5a..6839511df56d4a7461593565c127038b44104170 100644 --- a/libc/pthread/pthread_barrierattrsetpshared.c +++ b/libc/pthread/pthread_barrierattrsetpshared.c @@ -52,11 +52,11 @@ ********************************************************************************/ /******************************************************************************** - * Global Variables + * Public Data ********************************************************************************/ /******************************************************************************** - * Private Variables + * Private Data ********************************************************************************/ /******************************************************************************** diff --git a/libc/pthread/pthread_condattrdestroy.c b/libc/pthread/pthread_condattrdestroy.c index 30a0c4db1b74fd26e370c6f7c023844564894363..5e25a7d421f79bbfabd5fb20a48bbc646d249cea 100644 --- a/libc/pthread/pthread_condattrdestroy.c +++ b/libc/pthread/pthread_condattrdestroy.c @@ -44,7 +44,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/pthread/pthread_condattrinit.c b/libc/pthread/pthread_condattrinit.c index 1cc0a93e7370b3591bf1800b149253b22b8dc1df..220d972e1001c26fb48fb157236555f69ea21614 100644 --- a/libc/pthread/pthread_condattrinit.c +++ b/libc/pthread/pthread_condattrinit.c @@ -44,7 +44,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/pthread/pthread_mutexattrdestroy.c b/libc/pthread/pthread_mutexattrdestroy.c index ad92c4c15640c114122f58da7a836dc5b408a859..60b50718c1538f000d882113fbfaf4505bd203fd 100644 --- a/libc/pthread/pthread_mutexattrdestroy.c +++ b/libc/pthread/pthread_mutexattrdestroy.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrgetpshared.c b/libc/pthread/pthread_mutexattrgetpshared.c index e930a38a57779e3bc8732f4a92de6874ba59bc76..586a1b203ea121d6abef703a14fba15afc3e90bb 100644 --- a/libc/pthread/pthread_mutexattrgetpshared.c +++ b/libc/pthread/pthread_mutexattrgetpshared.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrgettype.c b/libc/pthread/pthread_mutexattrgettype.c index f5d662f7b1f80e2e2b76cead1c3aa9c398cc86f3..cc553c83509d10a90bf4c939a10af98f5867ddad 100644 --- a/libc/pthread/pthread_mutexattrgettype.c +++ b/libc/pthread/pthread_mutexattrgettype.c @@ -43,26 +43,6 @@ #ifdef CONFIG_MUTEX_TYPES -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrinit.c b/libc/pthread/pthread_mutexattrinit.c index cbb2f29ead611d0f67ed33a495a825ed3484c91c..b12b8a29940515c8c49ba48f3cc452f036326caa 100644 --- a/libc/pthread/pthread_mutexattrinit.c +++ b/libc/pthread/pthread_mutexattrinit.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrsetpshared.c b/libc/pthread/pthread_mutexattrsetpshared.c index 94a07dda05504b44e038056f332416f66a94b103..82f20092bd34251f561045c1e8624203ef75ff9b 100644 --- a/libc/pthread/pthread_mutexattrsetpshared.c +++ b/libc/pthread/pthread_mutexattrsetpshared.c @@ -43,26 +43,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_mutexattrsettype.c b/libc/pthread/pthread_mutexattrsettype.c index b0641b384af3ae3d4a46327ac6fa0581efd06c8c..ef8b2636865300c2db2a173d7b2972a243391911 100644 --- a/libc/pthread/pthread_mutexattrsettype.c +++ b/libc/pthread/pthread_mutexattrsettype.c @@ -43,26 +43,6 @@ #ifdef CONFIG_MUTEX_TYPES -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/pthread/pthread_startup.c b/libc/pthread/pthread_startup.c index 6dea37c4eb94487c0839fd4920d5cda4cbc3823d..3d2b76ce8f95318d8070cc390c1112226bec5a5f 100644 --- a/libc/pthread/pthread_startup.c +++ b/libc/pthread/pthread_startup.c @@ -56,11 +56,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/queue/sq_rem.c b/libc/queue/sq_rem.c index 2abf6d34e301382c4bbc830b4357f6a645139fc8..dd513908591fee35d14b91189250799062645a72 100644 --- a/libc/queue/sq_rem.c +++ b/libc/queue/sq_rem.c @@ -66,7 +66,7 @@ void sq_rem(FAR sq_entry_t *node, sq_queue_t *queue) else { FAR sq_entry_t *prev; - for (prev = (FAR sq_entry_t*)queue->head; + for (prev = (FAR sq_entry_t *)queue->head; prev && prev->flink != node; prev = prev->flink); diff --git a/libc/sched/Make.defs b/libc/sched/Make.defs index f1e69aff8ba46939397b5dc2e001d42f214d5656..eeb4be1c1bb834acea697f32782d02546cf2644b 100644 --- a/libc/sched/Make.defs +++ b/libc/sched/Make.defs @@ -37,6 +37,10 @@ CSRCS += sched_getprioritymax.c sched_getprioritymin.c +ifeq ($(CONFIG_SMP),y) +CSRCS += sched_cpucount.c +endif + ifeq ($(CONFIG_BUILD_PROTECTED),y) CSRCS += task_startup.c endif diff --git a/libc/sched/sched_cpucount.c b/libc/sched/sched_cpucount.c new file mode 100644 index 0000000000000000000000000000000000000000..6bdac1111763ac7fb1bcd12b6cb1d151ddd1c85f --- /dev/null +++ b/libc/sched/sched_cpucount.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * libc/sched/sched_cpucount.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_cpu_count + * + * Description: + * Return the number of bits set in the 'set'. This could be improved by + * using CPU-specific bit counting instructions. + * + * Inputs: + * set - The set of CPUs to be counted. + * + * Return Value: + * The number of CPUs in 'set' + * + ****************************************************************************/ + +int sched_cpu_count(FAR const cpu_set_t *set) +{ + int count; + int cpu; + + for (cpu = 0, count = 0; cpu < CONFIG_SMP_NCPUS; cpu++) + { + if ((*set & (1 << cpu)) != 0) + { + count++; + } + } + + return count; +} + +#endif /* CONFIG_SMP */ diff --git a/libc/sched/sched_getprioritymax.c b/libc/sched/sched_getprioritymax.c index e65c25d603abb2cd62c4406fa49c8d054c50031a..03660cbb8d49dde907fa34b17de444922dd672f6 100644 --- a/libc/sched/sched_getprioritymax.c +++ b/libc/sched/sched_getprioritymax.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/sched/sched_getprioritymax.c * * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,11 +43,11 @@ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: ched_get_priority_max * * Description: @@ -63,7 +63,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int sched_get_priority_max(int policy) { diff --git a/libc/sched/sched_getprioritymin.c b/libc/sched/sched_getprioritymin.c index 23a06f5d3b6ccd7db82e8ab3e169ea1f4bfd1383..660677f8ca458dd29cc536dcde1d8e8703d7c42a 100644 --- a/libc/sched/sched_getprioritymin.c +++ b/libc/sched/sched_getprioritymin.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/sched/sched_getprioritymin.c * * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,11 +43,11 @@ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_get_priority_min * * Description: @@ -63,7 +63,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int sched_get_priority_min(int policy) { diff --git a/libc/sched/task_startup.c b/libc/sched/task_startup.c index 8c81c0b50f6b571756e46633586159c2a22c9a54..6012e626750cd57c178262814213caed58220e50 100644 --- a/libc/sched/task_startup.c +++ b/libc/sched/task_startup.c @@ -55,11 +55,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/semaphore/sem_getvalue.c b/libc/semaphore/sem_getvalue.c index 3c92aa266343c1b824f3f5d49b7c1a5c48830d9e..16fcc7be0ac96bb9de10d08288b699bdade6f8fe 100644 --- a/libc/semaphore/sem_getvalue.c +++ b/libc/semaphore/sem_getvalue.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -103,6 +103,6 @@ int sem_getvalue(FAR sem_t *sem, FAR int *sval) else { set_errno(EINVAL); - return ERROR; + return ERROR; } } diff --git a/libc/semaphore/sem_init.c b/libc/semaphore/sem_init.c index c0554ef51b7a975d8b72fa086f7a3bc655133884..861acb6cde5ba153d8eeba99bfb1903b65611ebb 100644 --- a/libc/semaphore/sem_init.c +++ b/libc/semaphore/sem_init.c @@ -53,11 +53,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/signal/sig_fillset.c b/libc/signal/sig_fillset.c index ceeafdd31341bdadcbaa20cfcb50b6286aa70ec6..92f55edf4095f73d39b60ffbb79e39ef8f1c7efe 100644 --- a/libc/signal/sig_fillset.c +++ b/libc/signal/sig_fillset.c @@ -48,11 +48,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/signal/sig_ismember.c b/libc/signal/sig_ismember.c index 1a8590e003d87e85994f7f527f4c73923c0ac75a..c16ecd3d15c2d019a7c208091c54cd7f8fc17606 100644 --- a/libc/signal/sig_ismember.c +++ b/libc/signal/sig_ismember.c @@ -48,11 +48,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/signal/sig_set.c b/libc/signal/sig_set.c index a98d7b7ebd0e23edae25530ad395a8aa57beac3a..bbf42a587b0301612bbf35349952b365ceaf6ec9 100644 --- a/libc/signal/sig_set.c +++ b/libc/signal/sig_set.c @@ -118,7 +118,7 @@ void (*sigset(int signo, void (*disp)(int)))(int) * indicate the error. */ - if (ret == OK) + if (ret == OK) { return oact.sa_handler; } diff --git a/libc/spawn/lib_psa_dump.c b/libc/spawn/lib_psa_dump.c index b949d230a2c80e92f45e7c7f0068f31d685c1e50..935de174ed2c06691c8daad7cc9de40da9bccff3 100644 --- a/libc/spawn/lib_psa_dump.c +++ b/libc/spawn/lib_psa_dump.c @@ -45,7 +45,7 @@ #ifdef CONFIG_DEBUG /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_getflags.c b/libc/spawn/lib_psa_getflags.c index f0e07f0c22fe8a099d67f56214fd2cbffa6a965f..d365030cafc5e95caefb9c76f8c754999fedb2d1 100644 --- a/libc/spawn/lib_psa_getflags.c +++ b/libc/spawn/lib_psa_getflags.c @@ -43,7 +43,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_getschedparam.c b/libc/spawn/lib_psa_getschedparam.c index 3a4e48d921cf1c0c0339dd4c0366e25a2aee5486..8de95a27c12725279817206d7601a88cf1ce7508 100644 --- a/libc/spawn/lib_psa_getschedparam.c +++ b/libc/spawn/lib_psa_getschedparam.c @@ -44,7 +44,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_getschedpolicy.c b/libc/spawn/lib_psa_getschedpolicy.c index 8f36456664d013d98ba088fbf51e129e03f3cfdb..52cabb265bc855899eae9d2420c81265a28db689 100644 --- a/libc/spawn/lib_psa_getschedpolicy.c +++ b/libc/spawn/lib_psa_getschedpolicy.c @@ -43,7 +43,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_getsigmask.c b/libc/spawn/lib_psa_getsigmask.c index dd3495b4d021622a44de8075ea0d44327bafad96..db25257ead13f4f49043efac3ab772525e5e8def 100644 --- a/libc/spawn/lib_psa_getsigmask.c +++ b/libc/spawn/lib_psa_getsigmask.c @@ -46,7 +46,7 @@ #ifndef CONFIG_DISABLE_SIGNALS /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_setflags.c b/libc/spawn/lib_psa_setflags.c index 34b71d841c7349eddeabbf35eac28f370d8cc0be..d0362c81d8538874c53cc5c799f9b901181750cd 100644 --- a/libc/spawn/lib_psa_setflags.c +++ b/libc/spawn/lib_psa_setflags.c @@ -43,7 +43,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_setschedpolicy.c b/libc/spawn/lib_psa_setschedpolicy.c index 136a6f0fdb53c4bf61bcc6c5d2e83d559110dce5..d123db25dd6656cd30b86428fc3a0e5bceae6e4d 100644 --- a/libc/spawn/lib_psa_setschedpolicy.c +++ b/libc/spawn/lib_psa_setschedpolicy.c @@ -43,7 +43,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psa_setsigmask.c b/libc/spawn/lib_psa_setsigmask.c index 28b7daf77910ae531fb68cc51c0332079a88269f..038efa6905cc77fb66b8c7044e877ff30f15af11 100644 --- a/libc/spawn/lib_psa_setsigmask.c +++ b/libc/spawn/lib_psa_setsigmask.c @@ -46,7 +46,7 @@ #ifndef CONFIG_DISABLE_SIGNALS /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_addaction.c b/libc/spawn/lib_psfa_addaction.c index 8700efc2a59dc190c64380ba9867d26ab5017bcd..62c927b2e44d8bd97137dc327469f2b06c77c83b 100644 --- a/libc/spawn/lib_psfa_addaction.c +++ b/libc/spawn/lib_psfa_addaction.c @@ -44,7 +44,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_addclose.c b/libc/spawn/lib_psfa_addclose.c index 4f813f65c254d0204ba3e8e9d3e8c59d2e6f5654..3ee6f19083adf8a2965a51585380088e82f4b29d 100644 --- a/libc/spawn/lib_psfa_addclose.c +++ b/libc/spawn/lib_psfa_addclose.c @@ -46,10 +46,10 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_adddup2.c b/libc/spawn/lib_psfa_adddup2.c index a10f476f1bf7b52e595fbc0c2f75ce8f295452b9..6473476275c8f1e27c04a3856ba865eaa4b17b53 100644 --- a/libc/spawn/lib_psfa_adddup2.c +++ b/libc/spawn/lib_psfa_adddup2.c @@ -46,10 +46,10 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_addopen.c b/libc/spawn/lib_psfa_addopen.c index 4be80ff1c3b2e5f10e0bcc24c43b474fcf876789..7f22c06af8dcf481b49ef3b0240e5b4ada9dff64 100644 --- a/libc/spawn/lib_psfa_addopen.c +++ b/libc/spawn/lib_psfa_addopen.c @@ -47,10 +47,10 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_destroy.c b/libc/spawn/lib_psfa_destroy.c index 9bbc3d906fa2fa1b608b156979bb07a1ebda9f8c..73a5ea25f5bd8275b4b82b3395632090a3b163e0 100644 --- a/libc/spawn/lib_psfa_destroy.c +++ b/libc/spawn/lib_psfa_destroy.c @@ -45,10 +45,10 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/spawn/lib_psfa_init.c b/libc/spawn/lib_psfa_init.c index 5c902125a8aaf0a49d0d7fc6353dc02a4e54fe9f..64d900a22c873b562204b24a9cd7faeeaec1ef21 100644 --- a/libc/spawn/lib_psfa_init.c +++ b/libc/spawn/lib_psfa_init.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/Make.defs b/libc/stdio/Make.defs index 66914b30f20f333f436e60ecc48d6763a3a6a663..595a222b27741886f0b24b0cfb90ca183877235e 100644 --- a/libc/stdio/Make.defs +++ b/libc/stdio/Make.defs @@ -38,7 +38,7 @@ # C streams. CSRCS += lib_fileno.c lib_printf.c lib_sprintf.c lib_asprintf.c -CSRCS += lib_snprintf.c lib_libsprintf.c lib_vsprintf.c lib_avsprintf.c +CSRCS += lib_snprintf.c lib_libsprintf.c lib_vsprintf.c lib_vasprintf.c CSRCS += lib_vsnprintf.c lib_libvsprintf.c lib_dprintf.c lib_vdprintf.c CSRCS += lib_meminstream.c lib_memoutstream.c lib_memsistream.c CSRCS += lib_memsostream.c lib_lowinstream.c lib_lowoutstream.c @@ -56,14 +56,15 @@ CSRCS += lib_rawsostream.c ifneq ($(CONFIG_NFILE_STREAMS),0) -CSRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c -CSRCS += lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c lib_fgets.c -CSRCS += lib_gets_s.c lib_gets.c lib_libfgets.c lib_fwrite.c lib_libfwrite.c -CSRCS += lib_fflush.c lib_libflushall.c lib_libfflush.c lib_rdflush.c -CSRCS += lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c -CSRCS += lib_vprintf.c lib_fprintf.c lib_vfprintf.c lib_stdinstream.c -CSRCS += lib_stdoutstream.c lib_stdsistream.c lib_stdsostream.c lib_perror.c -CSRCS += lib_feof.c lib_ferror.c lib_clearerr.c +CSRCS += lib_fopen.c lib_freopen.c lib_fclose.c lib_fread.c lib_libfread.c +CSRCS += lib_fseek.c lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c +CSRCS += lib_fgets.c lib_gets_s.c lib_gets.c lib_libfgets.c lib_fwrite.c +CSRCS += lib_libfwrite.c lib_fflush.c lib_libflushall.c lib_libfflush.c +CSRCS += lib_rdflush.c lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c +CSRCS += lib_ungetc.c lib_vprintf.c lib_fprintf.c lib_vfprintf.c +CSRCS += lib_stdinstream.c lib_stdoutstream.c lib_stdsistream.c +CSRCS += lib_stdsostream.c lib_perror.c lib_feof.c lib_ferror.c +CSRCS += lib_clearerr.c endif diff --git a/libc/stdio/lib_asprintf.c b/libc/stdio/lib_asprintf.c index c08d7360a61d952f9653e976bd079d15739a4762..b10a779dce420c452985148d2d5bde8581ec2064 100644 --- a/libc/stdio/lib_asprintf.c +++ b/libc/stdio/lib_asprintf.c @@ -40,7 +40,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -55,11 +55,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -67,11 +67,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -92,15 +92,15 @@ * ****************************************************************************/ -int asprintf (FAR char **ptr, const char *fmt, ...) +int asprintf (FAR char **ptr, FAR const IPTR char *fmt, ...) { va_list ap; int ret; - /* Let avsprintf do all of the work */ + /* Let vasprintf do all of the work */ va_start(ap, fmt); - ret = avsprintf(ptr, fmt, ap); + ret = vasprintf(ptr, fmt, ap); va_end(ap); return ret; diff --git a/libc/stdio/lib_dprintf.c b/libc/stdio/lib_dprintf.c index 0ea64751706f1fe6ebf64da6ba94f104c5e7ae15..0b8f676145e7d3d56f82213f3dbd18c124455f9b 100644 --- a/libc/stdio/lib_dprintf.c +++ b/libc/stdio/lib_dprintf.c @@ -41,13 +41,13 @@ /**************************************************************************** * Public Functions - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: dprintf - **************************************************************************/ + ****************************************************************************/ -int dprintf(int fd, FAR const char *fmt, ...) +int dprintf(int fd, FAR const IPTR char *fmt, ...) { va_list ap; int ret; diff --git a/libc/stdio/lib_dtoa.c b/libc/stdio/lib_dtoa.c index 6241a486b4a853ef50a8ee9d1d0a40837be049ab..e3452126d86db3cf7f06613c6fcf9e29b7db2d4c 100644 --- a/libc/stdio/lib_dtoa.c +++ b/libc/stdio/lib_dtoa.c @@ -48,7 +48,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -427,7 +427,10 @@ static Bigint *pow5mult(Bigint * b, int k) { Bigint *b1, *p5, *p51; int i; - static int p05[3] = { 5, 25, 125 }; + static int p05[3] = + { + 5, 25, 125 + }; if ((i = k & 3)) b = multadd(b, p05[i - 1], 0); @@ -444,7 +447,7 @@ static Bigint *pow5mult(Bigint * b, int k) p5->next = 0; } - for (;;) + for (; ; ) { if (k & 1) { @@ -574,7 +577,8 @@ static int cmp(Bigint * a, Bigint * b) xa = xa0 + j; xb0 = b->x; xb = xb0 + j; - for (;;) + + for (; ; ) { if (*--xa != *--xb) { @@ -807,13 +811,27 @@ static const double tens[] = }; #ifdef IEEE_Arith -static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; +static const double bigtens[] = +{ + 1e16, 1e32, 1e64, 1e128, 1e256 +}; + +static const double tinytens[] = +{ + 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 +}; # define n_bigtens 5 #else -static const double bigtens[] = { 1e16, 1e32 }; -static const double tinytens[] = { 1e-16, 1e-32 }; +static const double bigtens[] = +{ + 1e16, 1e32 +}; + +static const double tinytens[] = +{ + 1e-16, 1e-32 +}; # define n_bigtens 2 #endif @@ -1284,7 +1302,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) /* Use Steele & White method of only generating digits needed. */ eps = 0.5 / tens[ilim - 1] - eps; - for (i = 0;;) + for (i = 0; ; ) { L = (int)d; d -= L; @@ -1314,7 +1332,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) /* Generate ilim digits, then fix them up. */ eps *= tens[ilim - 1]; - for (i = 1;; i++, d *= 10.) + for (i = 1; ; i++, d *= 10.) { L = (int)d; d -= L; @@ -1363,7 +1381,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) goto one_digit; } - for (i = 1;; i++) + for (i = 1; ; i++) { L = (int)(d / ds); d -= L * ds; @@ -1586,7 +1604,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) mhi = lshift(mhi, Log2P); } - for (i = 1;; i++) + for (i = 1; ; i++) { dig = quorem(b, S) + '0'; /* Do we yet have the shortest decimal string that will round to d? */ @@ -1634,8 +1652,10 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) if (j_1 > 0) { if (dig == '9') - { /* possible if i == 1 */ - round_9_up: + { + /* possible if i == 1 */ + + round_9_up: *s++ = '9'; goto roundoff; } @@ -1664,7 +1684,7 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) } else { - for (i = 1;; i++) + for (i = 1; ; i++) { *s++ = dig = quorem(b, S) + '0'; if (i >= ilim) @@ -1713,7 +1733,9 @@ ret: ret1: Bfree(b); if (s == s0) - { /* Don't return empty string */ + { + /* Don't return empty string */ + *s++ = '0'; k = 0; } diff --git a/libc/stdio/lib_fclose.c b/libc/stdio/lib_fclose.c index 50e7e63bcb1c284b7711c78099253a501c5a6e8e..35301fc6bb45c02c59afd7fddb904b3f094d6bd4 100644 --- a/libc/stdio/lib_fclose.c +++ b/libc/stdio/lib_fclose.c @@ -45,10 +45,10 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_fflush.c b/libc/stdio/lib_fflush.c index a84a14a5995a50bec3c85cd845614de768ed3e39..ae88e0ced2f48f94ad480120972fe801123581e6 100644 --- a/libc/stdio/lib_fflush.c +++ b/libc/stdio/lib_fflush.c @@ -46,7 +46,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,11 +73,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_fgetc.c b/libc/stdio/lib_fgetc.c index 297d5e71644e4c426e56200b835f712b106b26fb..c4b32d69b9989f84cde31776ca5206bdf1e7e377 100644 --- a/libc/stdio/lib_fgetc.c +++ b/libc/stdio/lib_fgetc.c @@ -42,7 +42,7 @@ ****************************************************************************/ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,32 +57,32 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ -/************************************************************************** - * Global Constant Data - **************************************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ -/************************************************************************** +/**************************************************************************** * Private Constant Data - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** - * Private Variables - **************************************************************************/ + * Private Data + ****************************************************************************/ /**************************************************************************** - * Global Functions - **************************************************************************/ + * Public Functions + ****************************************************************************/ /**************************************************************************** * fgetc - **************************************************************************/ + ****************************************************************************/ int fgetc(FAR FILE *stream) { diff --git a/libc/stdio/lib_fgetpos.c b/libc/stdio/lib_fgetpos.c index 5727c63ef97887e43b3c7a51e319eacc472541a0..ba4fa478b27e7527c07fe4fe3e60ef7bdbe25aa3 100644 --- a/libc/stdio/lib_fgetpos.c +++ b/libc/stdio/lib_fgetpos.c @@ -47,7 +47,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -62,11 +62,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -74,7 +74,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -104,7 +104,7 @@ int fgetpos(FAR FILE *stream, FAR fpos_t *pos) { long position; -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!stream || !pos) { set_errno(EINVAL); diff --git a/libc/stdio/lib_fgets.c b/libc/stdio/lib_fgets.c index 47f35597c105a48a23df2a5d1377bc6e60b6281f..bce8261e6e4f7d1a2e03e43f6a6591a0280e2047 100644 --- a/libc/stdio/lib_fgets.c +++ b/libc/stdio/lib_fgets.c @@ -41,7 +41,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -65,7 +65,7 @@ * buffer. A null terminator is stored after the last character in the * buffer. * - **************************************************************************/ + ****************************************************************************/ char *fgets(FAR char *buf, int buflen, FILE *stream) { diff --git a/libc/stdio/lib_fileno.c b/libc/stdio/lib_fileno.c index dff72becc481fa6aca2c623d96fd72e4981168cd..73e6951da07ca4cc35a6a6fcdac760f30356bca4 100644 --- a/libc/stdio/lib_fileno.c +++ b/libc/stdio/lib_fileno.c @@ -47,12 +47,13 @@ #if CONFIG_NFILE_STREAMS > 0 /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ int fileno(FAR FILE *stream) { int ret = -1; + if (stream) { ret = stream->fs_fd; diff --git a/libc/stdio/lib_fopen.c b/libc/stdio/lib_fopen.c index 62cada68a6e8b8c265d7a1661a3a63f2774c70e5..b7208dba5fbd2ef7221e6d65d279915e5817d6c8 100644 --- a/libc/stdio/lib_fopen.c +++ b/libc/stdio/lib_fopen.c @@ -47,7 +47,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -69,18 +69,76 @@ #define MODE_MASK (MODE_R | MODE_W | MODE_A) /**************************************************************************** - * Private Types + * Public Functions ****************************************************************************/ /**************************************************************************** - * Private Functions + * Name: fdopen ****************************************************************************/ +FAR FILE *fdopen(int fd, FAR const char *mode) +{ + FAR FILE *ret = NULL; + int oflags; + + /* Map the open mode string to open flags */ + + oflags = lib_mode2oflags(mode); + if (oflags >= 0) + { + ret = fs_fdopen(fd, oflags, NULL); + } + + return ret; +} + +/**************************************************************************** + * Name: fopen + ****************************************************************************/ + +FAR FILE *fopen(FAR const char *path, FAR const char *mode) +{ + FAR FILE *ret = NULL; + int oflags; + int fd; + + /* Map the open mode string to open flags */ + + oflags = lib_mode2oflags(mode); + if (oflags < 0) + { + return NULL; + } + + /* Open the file */ + + fd = open(path, oflags, 0666); + + /* If the open was successful, then fdopen() the fil using the file + * descriptor returned by open. If open failed, then just return the + * NULL stream -- open() has already set the errno. + */ + + if (fd >= 0) + { + ret = fs_fdopen(fd, oflags, NULL); + if (!ret) + { + /* Don't forget to close the file descriptor if any other + * failures are reported by fdopen(). + */ + + (void)close(fd); + } + } + return ret; +} + /**************************************************************************** * Name: lib_mode2oflags ****************************************************************************/ -static int lib_mode2oflags(FAR const char *mode) +int lib_mode2oflags(FAR const char *mode) { unsigned int state; int oflags; @@ -137,7 +195,7 @@ static int lib_mode2oflags(FAR const char *mode) { /* Write to the end of the file */ - oflags = O_WROK|O_CREAT|O_APPEND; + oflags = O_WROK | O_CREAT | O_APPEND; state = MODE_A; } else @@ -246,69 +304,3 @@ errout: set_errno(EINVAL); return ERROR; } - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: fdopen - ****************************************************************************/ - -FAR FILE *fdopen(int fd, FAR const char *mode) -{ - FAR FILE *ret = NULL; - int oflags; - - /* Map the open mode string to open flags */ - - oflags = lib_mode2oflags(mode); - if (oflags >= 0) - { - ret = fs_fdopen(fd, oflags, NULL); - } - - return ret; -} - -/**************************************************************************** - * Name: fopen - ****************************************************************************/ - -FAR FILE *fopen(FAR const char *path, FAR const char *mode) -{ - FAR FILE *ret = NULL; - int oflags; - int fd; - - /* Map the open mode string to open flags */ - - oflags = lib_mode2oflags(mode); - if (oflags < 0) - { - return NULL; - } - - /* Open the file */ - - fd = open(path, oflags, 0666); - - /* If the open was successful, then fdopen() the fil using the file - * desciptor returned by open. If open failed, then just return the - * NULL stream -- open() has already set the errno. - */ - - if (fd >= 0) - { - ret = fs_fdopen(fd, oflags, NULL); - if (!ret) - { - /* Don't forget to close the file descriptor if any other - * failures are reported by fdopen(). - */ - - (void)close(fd); - } - } - return ret; -} diff --git a/libc/stdio/lib_fprintf.c b/libc/stdio/lib_fprintf.c index 718dc40f5bff63eb58c318e15fac16a1d22d14f2..191dc2e34a41602f13ee5d3c70ccf786d3bcc31c 100644 --- a/libc/stdio/lib_fprintf.c +++ b/libc/stdio/lib_fprintf.c @@ -56,11 +56,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -68,7 +68,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -79,7 +79,7 @@ * Name: fprintf ****************************************************************************/ -int fprintf(FAR FILE *stream, FAR const char *fmt, ...) +int fprintf(FAR FILE *stream, FAR const IPTR char *fmt, ...) { va_list ap; int n; diff --git a/libc/stdio/lib_fputc.c b/libc/stdio/lib_fputc.c index d6029b07b96e70d479fb7a7ad47d9e8098a2d823..57e784759a31554d220b1de5c1e9b60344f80add 100644 --- a/libc/stdio/lib_fputc.c +++ b/libc/stdio/lib_fputc.c @@ -42,7 +42,7 @@ ****************************************************************************/ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,15 +57,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,11 +73,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_fputs.c b/libc/stdio/lib_fputs.c index fdfbd53904eacd109cfd8e4813220503a3ef4fe9..4b47a0462881483b199f56acddee5278ff28adec 100644 --- a/libc/stdio/lib_fputs.c +++ b/libc/stdio/lib_fputs.c @@ -49,7 +49,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -64,15 +64,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -80,7 +80,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_fread.c b/libc/stdio/lib_fread.c index 3bfac69956bbf63160f6f88433d4d6cfdcf712c8..8132b3275affd83ef2ba08879aaa39147e007c35 100644 --- a/libc/stdio/lib_fread.c +++ b/libc/stdio/lib_fread.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -69,7 +69,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_freopen.c b/libc/stdio/lib_freopen.c new file mode 100644 index 0000000000000000000000000000000000000000..830ea9a78f51a97dc66005b46473ff66cdbbfb48 --- /dev/null +++ b/libc/stdio/lib_freopen.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * libc/stdio/lib_freopen.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: freopen + * + * Description: + * Reuses stream to either open the file specified by path or to change + * its access mode. + * + * If a new path is specified, the function first attempts to close + * any file already associated with stream (third parameter) and + * disassociates it. Then, independently of whether that stream was + * successfuly closed or not, freopen opens the file specified by path + * and associates it with the stream just as fopen would do using the + * specified mode. + * + * If path is a null pointer, the function attempts to change the mode + * of the stream. Although a particular library implementation is allowed + * to restrict the changes permitted, and under which circumstances. + * + * The error indicator and eof indicator are automatically cleared (as if + * clearerr was called). + * + * Input Paramters: + * path - If non-NULL, refers to the name of the file to be opened. + * mode - String describing the new file access mode + * stream - Pointer to the type FILE to be reopened. + * + * Returned Value: + * If the file is successfully reopened, the function returns the pointer + * passed as parameter stream, which can be used to identify the reopened + * stream. Otherwise, a null pointer is returned and the errno variable + * is also set to a system-specific error code on failure. + * + ****************************************************************************/ + +FAR FILE *freopen(FAR const char *path, FAR const char *mode, + FAR FILE *stream) +{ + int oflags; + int ret; + int fd; + + /* Was a file name provided? */ + + if (path != NULL) + { + /* Yes, close the stream */ + + if (stream) + { + (void)fclose(stream); + } + + /* And attempt to reopen the file at the provided path */ + + return fopen(path, mode); + } + + /* Otherwise, we are just changing the mode of the current file. */ + + if (stream) + { + /* Convert the mode string into standard file open mode flags. */ + + oflags = lib_mode2oflags(mode); + if (oflags == 0) + { + return NULL; + } + + /* Get the underlying file descriptor from the stream */ + + fd = fileno(stream); + if (fd < 0) + { + return NULL; + } + + /* Set the new file mode for the file descriptor */ + + ret = fcntl(fd, F_SETFL, oflags); + if (ret < 0) + { + return NULL; + } + + clearerr(stream); + return stream; + } + + set_errno(EINVAL); + return NULL; +} diff --git a/libc/stdio/lib_fseek.c b/libc/stdio/lib_fseek.c index c73d5154a1764ba39e61f770e601703b4246f5a8..bafe4488e4357e5befb5d201e343a341f367e58c 100644 --- a/libc/stdio/lib_fseek.c +++ b/libc/stdio/lib_fseek.c @@ -49,7 +49,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -64,11 +64,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -76,7 +76,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -107,7 +107,7 @@ int fseek(FAR FILE *stream, long int offset, int whence) { - #if CONFIG_STDIO_BUFFER_SIZE > 0 +#if CONFIG_STDIO_BUFFER_SIZE > 0 /* Flush any valid read/write data in the buffer (also verifies stream) */ if (lib_rdflush(stream) < 0 || lib_wrflush(stream) < 0) diff --git a/libc/stdio/lib_fsetpos.c b/libc/stdio/lib_fsetpos.c index 6cf1c9eedb2423651af0d935a014bd7faab72869..18843cb6f7eb23a99ced3e91e5c34721e44a3e56 100644 --- a/libc/stdio/lib_fsetpos.c +++ b/libc/stdio/lib_fsetpos.c @@ -49,7 +49,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -64,11 +64,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -76,7 +76,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -104,7 +104,7 @@ int fsetpos(FAR FILE *stream, FAR fpos_t *pos) { -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (!stream || !pos) { set_errno(EINVAL); diff --git a/libc/stdio/lib_ftell.c b/libc/stdio/lib_ftell.c index 85390c918a3e0dab3106423cb869401a1e5b7f09..8707c9b2645304c4f47b59fc61993ea87e5400d9 100644 --- a/libc/stdio/lib_ftell.c +++ b/libc/stdio/lib_ftell.c @@ -49,7 +49,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -64,11 +64,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -76,7 +76,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_fwrite.c b/libc/stdio/lib_fwrite.c index e10eef8e190ef42c16f36bbad36a77fb04934761..ffb76765ae82106738e9eedf4523b56a7f8c9304 100644 --- a/libc/stdio/lib_fwrite.c +++ b/libc/stdio/lib_fwrite.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -69,7 +69,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_gets.c b/libc/stdio/lib_gets.c index d15c8bd08a6c18777892a3ce7e9f52864766574d..e8573edca90e2b8591b3cc728983d77f31522285 100644 --- a/libc/stdio/lib_gets.c +++ b/libc/stdio/lib_gets.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -67,7 +67,7 @@ * This API should not be used because it is inherently unsafe. Consider * using fgets which is safer and slightly more efficient. * - **************************************************************************/ + ****************************************************************************/ FAR char *gets(FAR char *s) { diff --git a/libc/stdio/lib_gets_s.c b/libc/stdio/lib_gets_s.c index 54f8891f915310d0f3418e46d5273a31cedf38fb..d811bdfcfcb3962f6641e4f4d0959e9d0047bdf7 100644 --- a/libc/stdio/lib_gets_s.c +++ b/libc/stdio/lib_gets_s.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -77,7 +77,7 @@ * characters from stdin until new-line character, end-of-file condition, * or read error. * - **************************************************************************/ + ****************************************************************************/ FAR char *gets_s(FAR char *s, rsize_t n) { diff --git a/libc/stdio/lib_libdtoa.c b/libc/stdio/lib_libdtoa.c index 0120bafd2d382e1da40251a184112f5fac427ecf..a3ef37d2209e2ec5c934994cd00e673543402060 100644 --- a/libc/stdio/lib_libdtoa.c +++ b/libc/stdio/lib_libdtoa.c @@ -46,7 +46,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -71,11 +71,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -83,7 +83,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_libfflush.c b/libc/stdio/lib_libfflush.c index 842de018a804d2a6527891ab72d910fa48f18bb3..ef20834b21922475bfc00e1aebae216365963e56 100644 --- a/libc/stdio/lib_libfflush.c +++ b/libc/stdio/lib_libfflush.c @@ -47,7 +47,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -62,11 +62,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -74,7 +74,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -121,11 +121,11 @@ ssize_t lib_fflush(FAR FILE *stream, bool bforce) if (stream->fs_bufpos != stream->fs_bufstart) { - /* Make sure that the buffer holds buffered write data. We do not - * support concurrent read/write buffer usage. - */ + /* Make sure that the buffer holds buffered write data. We do not + * support concurrent read/write buffer usage. + */ - if (stream->fs_bufread != stream->fs_bufstart) + if (stream->fs_bufread != stream->fs_bufstart) { /* The buffer holds read data... just return zero meaning "no bytes * remaining in the buffer." diff --git a/libc/stdio/lib_libfgets.c b/libc/stdio/lib_libfgets.c index 73cf47adc762e619c183a08630434d6ddd826577..4c3c41db05911d52b332dc1be0acd3a2ad092471 100644 --- a/libc/stdio/lib_libfgets.c +++ b/libc/stdio/lib_libfgets.c @@ -47,7 +47,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -92,7 +92,7 @@ * 'stream' until an EOF or a newline encountered or until a read error * occurs. * - **************************************************************************/ + ****************************************************************************/ static void consume_eol(FILE *stream, bool consume) { @@ -139,7 +139,7 @@ static void consume_eol(FILE *stream, bool consume) * until a read error occurs. Otherwise, lib_fgets() returns with the * remaining of the incoming stream buffer. * - **************************************************************************/ + ****************************************************************************/ FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream, bool keepnl, bool consume) @@ -177,7 +177,7 @@ FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream, * the next character and one for the null terminator. */ - for (;;) + for (; ; ) { /* Get the next character */ diff --git a/libc/stdio/lib_libflushall.c b/libc/stdio/lib_libflushall.c index 9bb94c5c8ea8a87fa7c3ad6bec1336d0f4b4f5f0..342c96a5bd7c81aa87ac2e7478a427d86ab0d2d4 100644 --- a/libc/stdio/lib_libflushall.c +++ b/libc/stdio/lib_libflushall.c @@ -45,7 +45,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -60,11 +60,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -72,11 +72,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -97,38 +97,38 @@ int lib_flushall(FAR struct streamlist *list) if (list) { - int i; - - /* Process each stream in the thread's stream list */ - - stream_semtake(list); - for (i = 0; i < CONFIG_NFILE_STREAMS; i++) - { - FILE *stream = &list->sl_streams[i]; - - /* If the stream is open (i.e., assigned a non-negative file - * descriptor) and opened for writing, then flush all of the pending - * write data in the stream. - */ - - if (stream->fs_fd >= 0 && (stream->fs_oflags & O_WROK) != 0) - { - /* Flush the writable FILE */ - - ret = lib_fflush(stream, true); - if (ret < 0) - { - /* An error occurred during the flush AND/OR we were unable - * to flush all of the buffered write data. Remember the - * last errcode. - */ - - lasterrno = ret; - } - } - } - - stream_semgive(list); + int i; + + /* Process each stream in the thread's stream list */ + + stream_semtake(list); + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + FILE *stream = &list->sl_streams[i]; + + /* If the stream is open (i.e., assigned a non-negative file + * descriptor) and opened for writing, then flush all of the pending + * write data in the stream. + */ + + if (stream->fs_fd >= 0 && (stream->fs_oflags & O_WROK) != 0) + { + /* Flush the writable FILE */ + + ret = lib_fflush(stream, true); + if (ret < 0) + { + /* An error occurred during the flush AND/OR we were unable + * to flush all of the buffered write data. Remember the + * last errcode. + */ + + lasterrno = ret; + } + } + } + + stream_semgive(list); } /* If any flush failed, return the errorcode of the last failed flush */ diff --git a/libc/stdio/lib_libfread.c b/libc/stdio/lib_libfread.c index 684f33b743971bd538a177368a8297cf7467621e..8597209cd3cd2420ce36b03fca6edf739465cea3 100644 --- a/libc/stdio/lib_libfread.c +++ b/libc/stdio/lib_libfread.c @@ -46,7 +46,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,7 +73,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -86,10 +86,10 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream) { - unsigned char *dest = (unsigned char*)ptr; - ssize_t bytes_read; + FAR unsigned char *dest = (FAR unsigned char*)ptr; + ssize_t bytes_read; #if CONFIG_STDIO_BUFFER_SIZE > 0 - int ret; + int ret; #endif /* Make sure that reading from this stream is allowed */ @@ -288,7 +288,7 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream) #if CONFIG_STDIO_BUFFER_SIZE > 0 shortread: #endif - bytes_read = dest - (unsigned char*)ptr; + bytes_read = dest - (FAR unsigned char *)ptr; /* Set or clear the EOF indicator. If we get here because of a * short read and the total number of* bytes read is zero, then diff --git a/libc/stdio/lib_libfwrite.c b/libc/stdio/lib_libfwrite.c index ea75da6d7f944e4b95ff04c690cdb56ae0554f74..12138e62ba04379e5310dc6f773a5686080a98c5 100644 --- a/libc/stdio/lib_libfwrite.c +++ b/libc/stdio/lib_libfwrite.c @@ -46,7 +46,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,7 +73,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -94,7 +94,13 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream) /* Make sure that writing to this stream is allowed */ - if (!stream || (stream->fs_oflags & O_WROK) == 0) + if (stream == NULL) + { + set_errno(EBADF); + return ret; + } + + if ((stream->fs_oflags & O_WROK) == 0) { set_errno(EBADF); goto errout; diff --git a/libc/stdio/lib_libnoflush.c b/libc/stdio/lib_libnoflush.c index eafe63977bbe62a6c410f01cff5b9d49d2221586..be4ea8ae5406d8a6af7c6f5ed03585eeb82d1425 100644 --- a/libc/stdio/lib_libnoflush.c +++ b/libc/stdio/lib_libnoflush.c @@ -47,7 +47,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_STDIO_LINEBUFFER @@ -64,11 +64,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -76,11 +76,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_libsnoflush.c b/libc/stdio/lib_libsnoflush.c index d3cf8c0f484fc708677dbab1414313865496d965..6deef38e039a96da705c4fa01e5589aa18517a4c 100644 --- a/libc/stdio/lib_libsnoflush.c +++ b/libc/stdio/lib_libsnoflush.c @@ -46,7 +46,7 @@ #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_STDIO_LINEBUFFER @@ -63,11 +63,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -75,11 +75,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_libsprintf.c b/libc/stdio/lib_libsprintf.c index fd7fa56e327480664ef2312663e8288d2a47c9b4..edb49f883251cc9efec12b6a5308c2895fea247f 100644 --- a/libc/stdio/lib_libsprintf.c +++ b/libc/stdio/lib_libsprintf.c @@ -38,7 +38,7 @@ ****************************************************************************/ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -53,11 +53,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -65,7 +65,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -76,7 +76,8 @@ * Name: lib_sprintf ****************************************************************************/ -int lib_sprintf(FAR struct lib_outstream_s *obj, const char *fmt, ...) +int lib_sprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *fmt, + ...) { va_list ap; int n; diff --git a/libc/stdio/lib_libvsprintf.c b/libc/stdio/lib_libvsprintf.c index b075487821e838d4408d6c3070bf9854b1e6dc8e..a103b0c4eeaf765cde2308ed5d8d8909d9e51049 100644 --- a/libc/stdio/lib_libvsprintf.c +++ b/libc/stdio/lib_libvsprintf.c @@ -46,7 +46,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -145,7 +145,8 @@ enum /* Pointer to ASCII conversion */ #ifdef CONFIG_PTR_IS_NOT_INT -static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, FAR void *p); +static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, + FAR void *p); #ifndef CONFIG_NOPRINTF_FIELDWIDTH static int getsizesize(uint8_t fmt, uint8_t flags, FAR void *p) #endif /* CONFIG_NOPRINTF_FIELDWIDTH */ @@ -154,7 +155,8 @@ static int getsizesize(uint8_t fmt, uint8_t flags, FAR void *p) /* Unsigned int to ASCII conversion */ static void utodec(FAR struct lib_outstream_s *obj, unsigned int n); -static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, uint8_t a); +static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, + uint8_t a); static void utooct(FAR struct lib_outstream_s *obj, unsigned int n); static void utobin(FAR struct lib_outstream_s *obj, unsigned int n); static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, @@ -169,7 +171,8 @@ static int getusize(uint8_t fmt, uint8_t flags, unsigned int lln); #ifdef CONFIG_LONG_IS_NOT_INT static void lutodec(FAR struct lib_outstream_s *obj, unsigned long ln); -static void lutohex(FAR struct lib_outstream_s *obj, unsigned long ln, uint8_t a); +static void lutohex(FAR struct lib_outstream_s *obj, unsigned long ln, + uint8_t a); static void lutooct(FAR struct lib_outstream_s *obj, unsigned long ln); static void lutobin(FAR struct lib_outstream_s *obj, unsigned long ln); static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, @@ -184,14 +187,16 @@ static int getlusize(uint8_t fmt, FAR uint8_t flags, unsigned long ln); #if defined(CONFIG_HAVE_LONG_LONG) && defined(CONFIG_LIBC_LONG_LONG) static void llutodec(FAR struct lib_outstream_s *obj, unsigned long long lln); -static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long lln, uint8_t a); +static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long lln, + uint8_t a); static void llutooct(FAR struct lib_outstream_s *obj, unsigned long long lln); static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long lln); static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long long lln); #ifndef CONFIG_NOPRINTF_FIELDWIDTH static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln); -static int getllusize(uint8_t fmt, FAR uint8_t flags, FAR unsigned long long lln); +static int getllusize(uint8_t fmt, FAR uint8_t flags, + FAR unsigned long long lln); #endif #endif @@ -203,11 +208,11 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, #endif /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -217,7 +222,7 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static const char g_nullstring[] = "(null)"; /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -235,7 +240,8 @@ static const char g_nullstring[] = "(null)"; ****************************************************************************/ #ifdef CONFIG_PTR_IS_NOT_INT -static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, FAR void *p) +static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, + FAR void *p) { union { @@ -309,7 +315,8 @@ static void utodec(FAR struct lib_outstream_s *obj, unsigned int n) * Name: utohex ****************************************************************************/ -static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, uint8_t a) +static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, + uint8_t a) { bool nonzero = false; uint8_t bits; @@ -376,7 +383,8 @@ static void utobin(FAR struct lib_outstream_s *obj, unsigned int n) * Name: utoascii ****************************************************************************/ -static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned int n) +static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned int n) { /* Perform the integer conversion according to the format specifier */ @@ -577,7 +585,8 @@ static void lutodec(FAR struct lib_outstream_s *obj, unsigned long n) * Name: lutohex ****************************************************************************/ -static void lutohex(FAR struct lib_outstream_s *obj, unsigned long n, uint8_t a) +static void lutohex(FAR struct lib_outstream_s *obj, unsigned long n, + uint8_t a) { bool nonzero = false; uint8_t bits; @@ -644,7 +653,8 @@ static void lutobin(FAR struct lib_outstream_s *obj, unsigned long n) * Name: lutoascii ****************************************************************************/ -static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long ln) +static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned long ln) { /* Perform the integer conversion according to the format specifier */ @@ -827,7 +837,8 @@ static void llutodec(FAR struct lib_outstream_s *obj, unsigned long long n) * Name: llutohex ****************************************************************************/ -static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long n, uint8_t a) +static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long n, + uint8_t a) { bool nonzero = false; uint8_t bits; @@ -894,7 +905,8 @@ static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long n) * Name: llutoascii ****************************************************************************/ -static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long long lln) +static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned long long lln) { /* Perform the integer conversion according to the format specifier */ @@ -1164,7 +1176,8 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, * libc/stdio/lib_vsprintf ****************************************************************************/ -int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list ap) +int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src, + va_list ap) { FAR char *ptmp; #ifndef CONFIG_NOPRINTF_FIELDWIDTH @@ -1291,7 +1304,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a /* Accumulate the field width integer. */ int n = ((int)(FMT_CHAR)) - (int)'0'; - for (;;) + for (; ; ) { FMT_NEXT; if (FMT_CHAR >= '0' && FMT_CHAR <= '9') @@ -1363,10 +1376,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a #endif /* Get the string to output */ - ptmp = va_arg(ap, char *); + ptmp = va_arg(ap, FAR char *); if (!ptmp) { - ptmp = (char*)g_nullstring; + ptmp = (FAR char *)g_nullstring; } /* Get the width of the string and perform right-justification @@ -1616,5 +1629,3 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a return obj->nput; } - - diff --git a/libc/stdio/lib_lowinstream.c b/libc/stdio/lib_lowinstream.c index 8c11fee9072f85094225f9db107177586d9db09f..8964b56749d1361619110d5fd9b911f80bab62d4 100644 --- a/libc/stdio/lib_lowinstream.c +++ b/libc/stdio/lib_lowinstream.c @@ -45,7 +45,7 @@ #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_ARCH_LOWGETC diff --git a/libc/stdio/lib_lowoutstream.c b/libc/stdio/lib_lowoutstream.c index f600bc614a0fda1c292189c70f7746de81aeb7a3..91604c90c49e02f4050b5b78e6472dca5781f0f6 100644 --- a/libc/stdio/lib_lowoutstream.c +++ b/libc/stdio/lib_lowoutstream.c @@ -46,7 +46,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_meminstream.c b/libc/stdio/lib_meminstream.c index 195b294e4d7a0ef15619987a5f881a7bfc6e0d3b..c975419499e4ebef9dab9a50cdfc7ec1c3594db1 100644 --- a/libc/stdio/lib_meminstream.c +++ b/libc/stdio/lib_meminstream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_memoutstream.c b/libc/stdio/lib_memoutstream.c index 492661e68aaa0b25cc96d264623dc6cbbba13632..1c658512ea971a2e64994ebe0379c31f12f3d17a 100644 --- a/libc/stdio/lib_memoutstream.c +++ b/libc/stdio/lib_memoutstream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_memsistream.c b/libc/stdio/lib_memsistream.c index d258c7fde17d1a7cec0b806ebd2d70756564dae0..af241b4c2ed8f23a5fce6811d2e54fd907055754 100644 --- a/libc/stdio/lib_memsistream.c +++ b/libc/stdio/lib_memsistream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_memsostream.c b/libc/stdio/lib_memsostream.c index 8726ea187ea1b5092bbdc40e77e4a989d7e89977..6570ef8942bdb7113178baaa7716a3ba654e9993 100644 --- a/libc/stdio/lib_memsostream.c +++ b/libc/stdio/lib_memsostream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_nullinstream.c b/libc/stdio/lib_nullinstream.c index aeb0af3790f962e8711d7a6ff340a7b85ee63179..9ca50d6379b4174e9550516113c80cf454dbbf24 100644 --- a/libc/stdio/lib_nullinstream.c +++ b/libc/stdio/lib_nullinstream.c @@ -40,7 +40,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_nulloutstream.c b/libc/stdio/lib_nulloutstream.c index 57429534489f8701051f6a8d7d0c2bf7900a591c..89a5a2524dfebc86682c694299a5523e2a161a36 100644 --- a/libc/stdio/lib_nulloutstream.c +++ b/libc/stdio/lib_nulloutstream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_printf.c b/libc/stdio/lib_printf.c index b306ca3b348c3116ad3868d9f9d62d4a1a6bfcf5..5f1096a3a2f7df75b432eeaf144d402d3937ed9d 100644 --- a/libc/stdio/lib_printf.c +++ b/libc/stdio/lib_printf.c @@ -33,10 +33,6 @@ * ****************************************************************************/ -/**************************************************************************** - * Compilation Switches - ****************************************************************************/ - /**************************************************************************** * Included Files ****************************************************************************/ @@ -44,49 +40,17 @@ #include #include -#include "lib_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ +#include "libc.h" /**************************************************************************** - * Private Function Prototypes + * Public Functions ****************************************************************************/ -/**************************************************************************** - * Global Function Prototypes - ****************************************************************************/ - -/************************************************************************** - * Global Constant Data - **************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/************************************************************************** - * Private Constant Data - **************************************************************************/ - -/**************************************************************************** - * Private Variables - **************************************************************************/ - -/**************************************************************************** - * Global Functions - **************************************************************************/ - /**************************************************************************** * Name: printf - **************************************************************************/ + ****************************************************************************/ -int printf(FAR const char *fmt, ...) +int printf(FAR const IPTR char *fmt, ...) { va_list ap; int ret; @@ -108,4 +72,3 @@ int printf(FAR const char *fmt, ...) return ret; } - diff --git a/libc/stdio/lib_puts.c b/libc/stdio/lib_puts.c index a9317dc4992a3d1a65cb4a4240829d8526d52f34..957e7426b98d07e3dd4f3c4efd08201a9979f2f6 100644 --- a/libc/stdio/lib_puts.c +++ b/libc/stdio/lib_puts.c @@ -42,7 +42,7 @@ ****************************************************************************/ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,7 +57,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** @@ -65,7 +65,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,7 +73,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_rawinstream.c b/libc/stdio/lib_rawinstream.c index 19a980787d836bd6c6897e09919d56586698147a..913a413bff4fcdc5f126ddc0efaf1d7dd7ced030 100644 --- a/libc/stdio/lib_rawinstream.c +++ b/libc/stdio/lib_rawinstream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_rawoutstream.c b/libc/stdio/lib_rawoutstream.c index 7f2c52247469310b7957b66596550186c3bd02b3..aed1fc5272e8abd6974aef71b205215c4188d44a 100644 --- a/libc/stdio/lib_rawoutstream.c +++ b/libc/stdio/lib_rawoutstream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_rawsistream.c b/libc/stdio/lib_rawsistream.c index b013e43a80f603bd0473bd5bd8767087af40bea3..d52fad1daf66a8e13e249e6dee7adb35f130c61c 100644 --- a/libc/stdio/lib_rawsistream.c +++ b/libc/stdio/lib_rawsistream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_rawsostream.c b/libc/stdio/lib_rawsostream.c index 82db850f787c0c862d798ebce7cb6695b2b00dc6..3c0b96dfa8dcf5bc0c75e92e7bd0119ba55a44b6 100644 --- a/libc/stdio/lib_rawsostream.c +++ b/libc/stdio/lib_rawsostream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_rdflush.c b/libc/stdio/lib_rdflush.c index efc5d4ea02cf53c62fc24d999177d5f595f06a72..cb928fb820cbe2469faafba9e2839779c6b06f6a 100644 --- a/libc/stdio/lib_rdflush.c +++ b/libc/stdio/lib_rdflush.c @@ -48,7 +48,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -63,11 +63,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -75,11 +75,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_snprintf.c b/libc/stdio/lib_snprintf.c index d1232e11a91b19f4779187fec458ed118ecb564c..a7bf89cebeb6b0d87f198726931ad41cf5e29951 100644 --- a/libc/stdio/lib_snprintf.c +++ b/libc/stdio/lib_snprintf.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -69,18 +69,18 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** * sprintf ****************************************************************************/ -int snprintf(FAR char *buf, size_t size, const char *format, ...) +int snprintf(FAR char *buf, size_t size, FAR const IPTR char *format, ...) { union { diff --git a/libc/stdio/lib_sprintf.c b/libc/stdio/lib_sprintf.c index 347efc59cba45c70d726c290f0525d65685cb165..8f75192896ccf61fa1030e71a5765b76b35a261d 100644 --- a/libc/stdio/lib_sprintf.c +++ b/libc/stdio/lib_sprintf.c @@ -38,7 +38,7 @@ ****************************************************************************/ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -53,11 +53,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -65,18 +65,18 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** * sprintf ****************************************************************************/ -int sprintf (FAR char *buf, const char *fmt, ...) +int sprintf (FAR char *buf, FAR const IPTR char *fmt, ...) { struct lib_memoutstream_s memoutstream; va_list ap; diff --git a/libc/stdio/lib_sscanf.c b/libc/stdio/lib_sscanf.c index c9375d35d60e9e67ed3782c46d6141f0745c85ab..c54fb3f1458a4ffb0868a5f8fed17742c3c9b21c 100644 --- a/libc/stdio/lib_sscanf.c +++ b/libc/stdio/lib_sscanf.c @@ -73,17 +73,17 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap); /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -151,7 +151,7 @@ static int findwidth(FAR const char *buf, FAR const char *fmt) } /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -168,7 +168,7 @@ int sscanf(FAR const char *buf, FAR const char *fmt, ...) int count; va_start(ap, fmt); - count = vsscanf((FAR const char*)buf, fmt, ap); + count = vsscanf((FAR const char *)buf, fmt, ap); va_end(ap); return count; } @@ -274,7 +274,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) tv = NULL; /* To avoid warnings about begin uninitialized */ if (!noassign) { - tv = va_arg(ap, char*); + tv = va_arg(ap, FAR char *); tv[0] = '\0'; } @@ -330,7 +330,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) tv = NULL; /* To avoid warnings about beign uninitialized */ if (!noassign) { - tv = va_arg(ap, char*); + tv = va_arg(ap, FAR char *); tv[0] = '\0'; } @@ -389,12 +389,12 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) if (lflag) { - plong = va_arg(ap, long*); + plong = va_arg(ap, FAR long *); *plong = 0; } else { - pint = va_arg(ap, int*); + pint = va_arg(ap, FAR int *); *pint = 0; } } @@ -513,9 +513,11 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) } } - /* Process %f: Floating point conversion */ + /* Process %a, %A, %f, %F, %e, %E, %g, and %G: Floating point + * conversions + */ - else if (*fmt == 'f' || *fmt == 'F') + else if (strchr("aAfFeEgG", *fmt) != NULL) { #ifdef CONFIG_HAVE_DOUBLE FAR double_t *pd = NULL; @@ -538,13 +540,13 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) #ifdef CONFIG_HAVE_DOUBLE if (lflag) { - pd = va_arg(ap, double_t*); + pd = va_arg(ap, FAR double_t *); *pd = 0.0; } else #endif { - pf = va_arg(ap, float*); + pf = va_arg(ap, FAR float *); *pf = 0.0; } } @@ -642,12 +644,12 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) if (lflag) { - FAR long *plong = va_arg(ap, long*); + FAR long *plong = va_arg(ap, FAR long *); *plong = (long)nchars; } else { - FAR int *pint = va_arg(ap, int*); + FAR int *pint = va_arg(ap, FAR int *); *pint = (int)nchars; } } diff --git a/libc/stdio/lib_stdinstream.c b/libc/stdio/lib_stdinstream.c index 4b00888787be42667f2af8ccc4b67edef1d96ca0..f1b5f3da998e76502c8b5c8dfa9c8b12f3522f2b 100644 --- a/libc/stdio/lib_stdinstream.c +++ b/libc/stdio/lib_stdinstream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions @@ -64,7 +64,7 @@ static int stdinstream_getc(FAR struct lib_instream_s *this) this->nget++; } - return ret; + return ret; } /**************************************************************************** diff --git a/libc/stdio/lib_stdoutstream.c b/libc/stdio/lib_stdoutstream.c index 73321c7fdb364d77b5dd67f8187dfd2d3e71bf6d..b30e8151608b225b10a61614e96eae474e62b9ee 100644 --- a/libc/stdio/lib_stdoutstream.c +++ b/libc/stdio/lib_stdoutstream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_stdsistream.c b/libc/stdio/lib_stdsistream.c index 85eaf0fe711ea4feed79af62c949ac2350b901c3..b569bb412222b8772ff827a5cce8990a23929e41 100644 --- a/libc/stdio/lib_stdsistream.c +++ b/libc/stdio/lib_stdsistream.c @@ -39,7 +39,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions @@ -64,7 +64,7 @@ static int stdsistream_getc(FAR struct lib_sistream_s *this) this->nget++; } - return ret; + return ret; } /**************************************************************************** diff --git a/libc/stdio/lib_stdsostream.c b/libc/stdio/lib_stdsostream.c index ade6369c51c18b0433cf336e44e9a66641fdaa88..4e196b1a22bb0638f2265c4b2431377969a28342 100644 --- a/libc/stdio/lib_stdsostream.c +++ b/libc/stdio/lib_stdsostream.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdio/lib_ungetc.c b/libc/stdio/lib_ungetc.c index 68eb5d5c038c5d01d4ac2f47afbe543ab35756d2..89220751b39d39036e398b8528a9b1cc13b84f12 100644 --- a/libc/stdio/lib_ungetc.c +++ b/libc/stdio/lib_ungetc.c @@ -46,7 +46,7 @@ #include #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -61,32 +61,32 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ -/************************************************************************** - * Global Constant Data - **************************************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ -/************************************************************************** +/**************************************************************************** * Private Constant Data - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** - * Private Variables - **************************************************************************/ + * Private Data + ****************************************************************************/ /**************************************************************************** * Public Functions - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: ungetc - **************************************************************************/ + ****************************************************************************/ int ungetc(int c, FAR FILE *stream) { diff --git a/libc/stdio/lib_avsprintf.c b/libc/stdio/lib_vasprintf.c similarity index 92% rename from libc/stdio/lib_avsprintf.c rename to libc/stdio/lib_vasprintf.c index 6f9e5cb77c5da1d6c2f214633593cec9ac9763cd..7338d03f594838e3770da62507e4f3a57db60b33 100644 --- a/libc/stdio/lib_avsprintf.c +++ b/libc/stdio/lib_vasprintf.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/stdio/lib_avsprintf.c + * libc/stdio/lib_vasprintf.c * * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -42,14 +42,14 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /* On some architectures, va_list is really a pointer to a structure on the * stack. And the va_arg builtin will modify that instance of va_list. Since - * avsprintf traverse the parameters in the va_list twice, the va_list will + * vasprintf traverse the parameters in the va_list twice, the va_list will * be altered in this first cases and the second usage will fail. So far, I * have seen this only on the X86 family with GCC. */ @@ -75,11 +75,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -87,22 +87,22 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: avsprintf + * Name: vasprintf * * Description: * This function is similar to vsprintf, except that it dynamically * allocates a string (as with malloc) to hold the output, instead of * putting the output in a buffer you allocate in advance. The ptr * argument should be the address of a char * object, and a successful - * call to avsprintf stores a pointer to the newly allocated string at that + * call to vasprintf stores a pointer to the newly allocated string at that * location. * * Returned Value: @@ -112,7 +112,7 @@ * ****************************************************************************/ -int avsprintf(FAR char **ptr, const char *fmt, va_list ap) +int vasprintf(FAR char **ptr, FAR const IPTR char *fmt, va_list ap) { struct lib_outstream_s nulloutstream; struct lib_memoutstream_s memoutstream; @@ -130,12 +130,12 @@ int avsprintf(FAR char **ptr, const char *fmt, va_list ap) va_copy(ap2, ap); #endif -/* First, use a nullstream to get the size of the buffer. The number + /* First, use a nullstream to get the size of the buffer. The number * of bytes returned may or may not include the null terminator. */ lib_nulloutstream(&nulloutstream); - nbytes = lib_vsprintf((FAR struct lib_outstream_s *)&nulloutstream, fmt, ap1); + (void)lib_vsprintf((FAR struct lib_outstream_s *)&nulloutstream, fmt, ap1); /* Then allocate a buffer to hold that number of characters, adding one * for the null terminator. diff --git a/libc/stdio/lib_vdprintf.c b/libc/stdio/lib_vdprintf.c index d96ca40f88f06545ebbe3821d42354653fef3aa7..9c76078d6eb26c8d79cd2e7b1badadb47aa0de9f 100644 --- a/libc/stdio/lib_vdprintf.c +++ b/libc/stdio/lib_vdprintf.c @@ -42,13 +42,13 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Public Functions ****************************************************************************/ -int vdprintf(int fd, FAR const char *fmt, va_list ap) +int vdprintf(int fd, FAR const IPTR char *fmt, va_list ap) { struct lib_rawoutstream_s rawoutstream; diff --git a/libc/stdio/lib_vfprintf.c b/libc/stdio/lib_vfprintf.c index c6bfe588c79c2610cb10c7a1af906bd494748626..b77b1cb6af16db64c51e5a219a95a0d343836d91 100644 --- a/libc/stdio/lib_vfprintf.c +++ b/libc/stdio/lib_vfprintf.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -69,14 +69,14 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** * Public Functions ****************************************************************************/ -int vfprintf(FAR FILE *stream, FAR const char *fmt, va_list ap) +int vfprintf(FAR FILE *stream, FAR const IPTR char *fmt, va_list ap) { struct lib_stdoutstream_s stdoutstream; int n = ERROR; diff --git a/libc/stdio/lib_vprintf.c b/libc/stdio/lib_vprintf.c index 13890e928b8c9d45b70754211f1f9999f42d8013..5f7a0844539102140e4a36ea587534160cad4d5a 100644 --- a/libc/stdio/lib_vprintf.c +++ b/libc/stdio/lib_vprintf.c @@ -56,34 +56,34 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ -/************************************************************************** - * Global Constant Data - **************************************************************************/ +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ -/************************************************************************** +/**************************************************************************** * Private Constant Data - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** - * Private Variables - **************************************************************************/ + * Private Data + ****************************************************************************/ /**************************************************************************** * Public Functions - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: vprintf - **************************************************************************/ + ****************************************************************************/ -int vprintf(FAR const char *fmt, va_list ap) +int vprintf(FAR const IPTR char *fmt, va_list ap) { /* vfprintf into stdout */ diff --git a/libc/stdio/lib_vsnprintf.c b/libc/stdio/lib_vsnprintf.c index dca39e61eb335251645ed58af93b28585b7b6d8b..ddbb1ef9ef92c73361cf565968d0a3f7c147e3e3 100644 --- a/libc/stdio/lib_vsnprintf.c +++ b/libc/stdio/lib_vsnprintf.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -69,7 +69,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -80,7 +80,8 @@ * Name: vsnprintf ****************************************************************************/ -int vsnprintf(FAR char *buf, size_t size, const char *format, va_list ap) +int vsnprintf(FAR char *buf, size_t size, FAR const IPTR char *format, + va_list ap) { struct lib_memoutstream_s memoutstream; int n; diff --git a/libc/stdio/lib_vsprintf.c b/libc/stdio/lib_vsprintf.c index 737cfdc5b9154e64a946322c7ffb67056c7cda8d..a64fef6e7363f5b57c53308fd45e8ce25b6ff15b 100644 --- a/libc/stdio/lib_vsprintf.c +++ b/libc/stdio/lib_vsprintf.c @@ -41,7 +41,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -56,11 +56,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -68,7 +68,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -79,7 +79,7 @@ * Name: vsprintf ****************************************************************************/ -int vsprintf(FAR char *dest, const char *src, va_list ap) +int vsprintf(FAR char *dest, FAR const IPTR char *src, va_list ap) { struct lib_memoutstream_s memoutstream; diff --git a/libc/stdio/lib_wrflush.c b/libc/stdio/lib_wrflush.c index 40b8e38c8d2eb28fed457863b51ae7ce7f51984b..b07c48b2904e43e3acbd37d2970c265295060054 100644 --- a/libc/stdio/lib_wrflush.c +++ b/libc/stdio/lib_wrflush.c @@ -43,7 +43,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Pre-processor Definitions @@ -58,11 +58,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -70,7 +70,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/stdio/lib_zeroinstream.c b/libc/stdio/lib_zeroinstream.c index a52ecc1d069dd400a721dba28a6a93b9fb0c3e6d..506d00587173ee2cc2f670442747ddaf2f530df4 100644 --- a/libc/stdio/lib_zeroinstream.c +++ b/libc/stdio/lib_zeroinstream.c @@ -39,7 +39,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdlib/Make.defs b/libc/stdlib/Make.defs index 6a0d8ad7d8b808c034e9aaa2681e18ca584b7ee9..68eb75e68b4e83726706255c4889a2c738fbd1a6 100644 --- a/libc/stdlib/Make.defs +++ b/libc/stdlib/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libc/stdlib/Make.defs # -# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -35,8 +35,9 @@ # Add the stdlib C files to the build -CSRCS += lib_abs.c lib_abort.c lib_imaxabs.c lib_itoa.c lib_labs.c -CSRCS += lib_llabs.c lib_rand.c lib_qsort.c +CSRCS += lib_abs.c lib_abort.c lib_div.c lib_ldiv.c lib_lldiv.c +CSRCS += lib_imaxabs.c lib_itoa.c lib_labs.c lib_llabs.c +CSRCS += lib_bsearch.c lib_rand.c lib_qsort.c CSRCS += lib_strtol.c lib_strtoll.c lib_strtoul.c lib_strtoull.c CSRCS += lib_strtod.c lib_checkbase.c diff --git a/libc/stdlib/lib_abort.c b/libc/stdlib/lib_abort.c index 1c7442c7f579f725f78ccd7ee995df78bb71c63f..f037e8d8cc48068da2dd21bc9ccdd243eb5eab01 100644 --- a/libc/stdlib/lib_abort.c +++ b/libc/stdlib/lib_abort.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib/lib_abort.c * * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved. @@ -31,46 +31,46 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Global Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Function Prototypes - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: Abort * * Description: @@ -93,7 +93,7 @@ * Returned Value: * This function does not return, * - ************************************************************************/ + ****************************************************************************/ void abort(void) { diff --git a/libc/stdlib/lib_abs.c b/libc/stdlib/lib_abs.c index a4e4ec6694289c4a62a65802330fe5e966489566..b3a7854f7c1fc5f8d2e11a81b343f0656acc0ee3 100644 --- a/libc/stdlib/lib_abs.c +++ b/libc/stdlib/lib_abs.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib/lib_abs.c * * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. @@ -31,18 +31,18 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ int abs(int j) { diff --git a/libc/stdlib/lib_bsearch.c b/libc/stdlib/lib_bsearch.c new file mode 100644 index 0000000000000000000000000000000000000000..b6586cc9d2db691d9509b207665f8ac37c81161f --- /dev/null +++ b/libc/stdlib/lib_bsearch.c @@ -0,0 +1,138 @@ +/**************************************************************************** + * libc/stdlib/lib_bsearch.c + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bsearch + * + * Description: + * The bsearch() function will search an array of nel objects, the initial + * element of which is pointed to by 'base', for an element that matches + * the object pointed to by 'key'. The size of each element in the array + * is specified by 'width'. If the nel argument has the value zero, the + * comparison function pointed to by 'compar' will not be called and no + * match will be found. + * + * The comparison function pointed to by 'compar' will be called with two + * arguments that point to the 'key' object and to an array element, in + * that order. + * + * The application will ensure that the comparison function pointed to by + * 'compar 'does not alter the contents of the array. The implementation + * may reorder elements of the array between calls to the comparison + * function, but will not alter the contents of any individual element. + * + * The implementation will ensure that the first argument is always a + * pointer to the 'key'. + * + * When the same objects (consisting of width bytes, irrespective of their + * current positions in the array) are passed more than once to the + * comparison function, the results will be consistent with one another. + * That is, the same object will always compare the same way with the key. + * + * The application will ensure that the function returns an integer less + * than, equal to, or greater than 0 if the key object is considered, + * respectively, to be less than, to match, or to be greater than the + * array element. The application will ensure that the array consists of + * all the elements that compare less than, all the elements that compare + * equal to, and all the elements that compare greater than the key + * object, in that order. + * + * (Based on description from OpenGroup.org). + * + * Returned Value: + * The bsearch() function will return a pointer to a matching member of + * the array, or a null pointer if no match is found. If two or more + * members compare equal, which member is returned is unspecified. + * + * Notes from the NetBSD version: + * The code below is a bit sneaky. After a comparison fails, we divide + * the work in half by moving either left or right. If 'lim' is odd, + * moving left simply involves halving 'lim': e.g., when 'lim' is 5 we + * look at item 2, so we change 'lim' to 2 so that we will look at items + * 0 & 1. If 'lim' is even, the same applies. If 'lim' is odd, moving + * right again involes halving 'lim', this time moving the base up one + * item past 'ptr': e.g., when 'lim' is 5 we change base to item 3 and + * make 'lim' 2 so that we will look at items 3 and 4. If 'lim' is + * even, however, we have to shrink it by one before halving: e.g., + * when 'lim' is 4, we still looked at item 2, so we have to make 'lim' + * 3, then halve, obtaining 1, so that we will only look at item 3. + * + ****************************************************************************/ + +FAR void *bsearch(FAR const void *key, FAR const void *base, size_t nel, + size_t width, CODE int (*compar)(FAR const void *, + FAR const void *)) +{ + FAR const void *ptr; + size_t lim; + int cmp; + + DEBUGASSERT(key != NULL); + DEBUGASSERT(base != NULL || nel == 0); + DEBUGASSERT(compar != NULL); + + for (lim = nel; lim != 0; lim >>= 1) + { + ptr = base + (lim >> 1) * width; + cmp = (*compar)(key, ptr); + + if (cmp == 0) + { + return (FAR void *)ptr; + } + + if (cmp > 0) + { + /* key > ptr: move right (else move left) */ + + base = (FAR const char *)ptr + width; + lim--; + } + } + + return NULL; +} diff --git a/libc/stdlib/lib_checkbase.c b/libc/stdlib/lib_checkbase.c index 83199bcfaed8de57ccab4288003d273c7f0f1ccf..05abe7b8968bbb6fdfd46dc1786bf73005ee8378 100644 --- a/libc/stdlib/lib_checkbase.c +++ b/libc/stdlib/lib_checkbase.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/stdlib/lib_div.c b/libc/stdlib/lib_div.c new file mode 100644 index 0000000000000000000000000000000000000000..290cc7a1c48faa3bb6636233b5ae9be40dfe66cd --- /dev/null +++ b/libc/stdlib/lib_div.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * libc/stdlib/lib_div.c + * + * Copyright (C) 2015 Stavros Polymenis. All rights reserved. + * Author: Stavros Polymenis + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#ifdef CONFIG_CAN_PASS_STRUCTS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: div + * + * Description: + * The div() function computes the quotient and remainder of the division + * of the numerator 'numer' by the denominator 'denom". If the division is + * inexact, the resulting quotient is the integer of lesser magnitude that + * is the nearest to the algebraic quotient. If the result cannot be + * represented, the behavior is undefined; otherwise, quot * denom + rem + * will equal 'numer'. + * + * Input Parameters: + * numer - Numerator of the Division + * denom - Denominator of the division + * + * Returned Value: + * The result of the devision represent as values of type div_t + * + ****************************************************************************/ + +div_t div(int numer, int denom) +{ + div_t f; + + f.quot = numer / denom; + f.rem = numer % denom; + return f; +} + +#endif /* CONFIG_CAN_PASS_STRUCTS */ \ No newline at end of file diff --git a/libc/stdlib/lib_imaxabs.c b/libc/stdlib/lib_imaxabs.c index d365043727b06e0d7f3002adc5cef8500e3e3b79..12c5dc15a715e3502f4ea97ee5ca3fa15c9772fb 100644 --- a/libc/stdlib/lib_imaxabs.c +++ b/libc/stdlib/lib_imaxabs.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib//lib_abs.c * * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. @@ -31,18 +31,18 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ intmax_t imaxabs(intmax_t j) { diff --git a/libc/stdlib/lib_itoa.c b/libc/stdlib/lib_itoa.c index 553591c09762950903fa29c700ccb32278672b72..ad3563cde9170a97367044089e12fa92ac3270d1 100644 --- a/libc/stdlib/lib_itoa.c +++ b/libc/stdlib/lib_itoa.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib/lib_itoa.c * * Copyright (C) 2013 Brooks Automation, Inc. All rights reserved. @@ -36,24 +36,24 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ -char *itoa(int val, char *str, int base) +FAR char *itoa(int val, FAR char *str, int base) { - static const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + static FAR const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; int intval = abs(val), digit, pos, len; - char *buf = str; + FAR char *buf = str; char swap; if (base >= 2 && base <= 36) diff --git a/libc/stdlib/lib_labs.c b/libc/stdlib/lib_labs.c index 7cf92a0a19f3ef77ce8e105ca0e8ed78ab41e709..ad398d0beb77b67f157d5a168804ae751079f603 100644 --- a/libc/stdlib/lib_labs.c +++ b/libc/stdlib/lib_labs.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib/lib_labs.c * * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. @@ -31,18 +31,18 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ long int labs(long int j) { diff --git a/libc/stdlib/lib_ldiv.c b/libc/stdlib/lib_ldiv.c new file mode 100644 index 0000000000000000000000000000000000000000..66b2a88e3d5216aff7b88b18991c88743e915ebe --- /dev/null +++ b/libc/stdlib/lib_ldiv.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * libc/stdlib/lib_ldiv.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * A direct leverage of the div() inplement by: + * + * Copyright (C) 2015 Stavros Polymenis. All rights reserved. + * Author: Stavros Polymenis + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#ifdef CONFIG_CAN_PASS_STRUCTS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ldiv + * + * Description: + * The ldiv() function computes the quotient and remainder of the division + * of the numerator 'numer' by the denominator 'denom". If the division is + * inexact, the resulting quotient is the integer of lesser magnitude that + * is the nearest to the algebraic quotient. If the result cannot be + * represented, the behavior is undefined; otherwise, quot * denom + rem + * will equal 'numer'. + * + * Input Parameters: + * numer - Numerator of the Division + * denom - Denominator of the division + * + * Returned Value: + * The result of the devision represent as values of type ldiv_t + * + ****************************************************************************/ + +ldiv_t ldiv(long numer, long denom) +{ + ldiv_t f; + + f.quot = numer / denom; + f.rem = numer % denom; + return f; +} + +#endif /* CONFIG_CAN_PASS_STRUCTS */ \ No newline at end of file diff --git a/libc/stdlib/lib_llabs.c b/libc/stdlib/lib_llabs.c index 3630d1716f5b2772259bd3ddc2278e9f597c64da..ee8b76225e40cc2ccde1672e44ae21f895f1182c 100644 --- a/libc/stdlib/lib_llabs.c +++ b/libc/stdlib/lib_llabs.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/stdlib/lib_llabs.c * * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. @@ -31,19 +31,19 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ #ifdef CONFIG_HAVE_LONG_LONG long long int llabs(long long int j) diff --git a/libc/stdlib/lib_lldiv.c b/libc/stdlib/lib_lldiv.c new file mode 100644 index 0000000000000000000000000000000000000000..753cdd93ae7387a34aaadb1904cc7156450b9f18 --- /dev/null +++ b/libc/stdlib/lib_lldiv.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * libc/stdlib/lib_lldiv.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * A direct leverage of the div() inplement by: + * + * Copyright (C) 2015 Stavros Polymenis. All rights reserved. + * Author: Stavros Polymenis + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#if defined(CONFIG_CAN_PASS_STRUCTS) && defined(CONFIG_HAVE_LONG_LONG) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lldiv + * + * Description: + * The lldiv() function computes the quotient and remainder of the division + * of the numerator 'numer' by the denominator 'denom". If the division is + * inexact, the resulting quotient is the integer of lesser magnitude that + * is the nearest to the algebraic quotient. If the result cannot be + * represented, the behavior is undefined; otherwise, quot * denom + rem + * will equal 'numer'. + * + * Input Parameters: + * numer - Numerator of the Division + * denom - Denominator of the division + * + * Returned Value: + * The result of the devision represent as values of type lldiv_t + * + ****************************************************************************/ + +lldiv_t lldiv(long long numer, long long denom) +{ + lldiv_t f; + + f.quot = numer / denom; + f.rem = numer % denom; + return f; +} + +#endif /* CONFIG_CAN_PASS_STRUCTS && CONFIG_HAVE_LONG_LONG */ \ No newline at end of file diff --git a/libc/stdlib/lib_mkstemp.c b/libc/stdlib/lib_mkstemp.c index 94b6dcc0afa36ac9105562dfa2960ff3c1d50b00..fdf93cdfaf43ba5ea2315aba42ae6a866b714532 100644 --- a/libc/stdlib/lib_mkstemp.c +++ b/libc/stdlib/lib_mkstemp.c @@ -54,14 +54,14 @@ * Pre-processor definitions ****************************************************************************/ - #ifndef CONFIG_LIBC_TMPDIR +#ifndef CONFIG_LIBC_TMPDIR # define CONFIG_LIBC_TMPDIR "/tmp" #endif #define MAX_XS 6 #define MIN_NUMERIC 0 /* 0-9: Numeric */ #define MAX_NUMERIC 9 -#define MIN_UPPERCASE 10 /* 10-35: Upper case */ +#define MIN_UPPERCASE 10 /* 10-35: Upper case */ #define MAX_UPPERCASE 35 #define MIN_LOWERCASE 36 /* 36-61: Lower case */ #define MAX_LOWERCASE 61 @@ -153,7 +153,7 @@ static void get_base62(FAR uint8_t *ptr) { DEBUGASSERT(errno == EINTR); } - + memcpy(ptr, g_base62, MAX_XS); incr_base62(); sem_post(&g_b62sem); diff --git a/libc/stdlib/lib_qsort.c b/libc/stdlib/lib_qsort.c index 8850f50c10d42d33f313590b05cb0821ebc5eff3..8c0e2825b1f7ce2a89592bae74aaa01edeab681c 100644 --- a/libc/stdlib/lib_qsort.c +++ b/libc/stdlib/lib_qsort.c @@ -58,8 +58,8 @@ #define swapcode(TYPE, parmi, parmj, n) \ { \ long i = (n) / sizeof (TYPE); \ - register TYPE *pi = (TYPE *) (parmi); \ - register TYPE *pj = (TYPE *) (parmj); \ + register TYPE *pi = (TYPE *)(parmi); \ + register TYPE *pj = (TYPE *)(parmj); \ do { \ register TYPE t = *pi; \ *pi++ = *pj; \ @@ -67,9 +67,9 @@ } while (--i > 0); \ } -#define SWAPINIT(a, size) \ - swaptype = ((char *)a - (char *)0) % sizeof(long) || \ - size % sizeof(long) ? 2 : size == sizeof(long)? 0 : 1; +#define SWAPINIT(a, width) \ + swaptype = ((FAR char *)a - (FAR char *)0) % sizeof(long) || \ + width % sizeof(long) ? 2 : width == sizeof(long)? 0 : 1; #define swap(a, b) \ if (swaptype == 0) \ @@ -80,7 +80,7 @@ } \ else \ { \ - swapfunc(a, b, size, swaptype); \ + swapfunc(a, b, width, swaptype); \ } #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) @@ -89,15 +89,16 @@ * Private Function Prototypes ****************************************************************************/ -static inline void swapfunc(char *a, char *b, int n, int swaptype); -static inline char *med3(char *a, char *b, char *c, - int (*compar)(const void *, const void *)); +static inline void swapfunc(FAR char *a, FAR char *b, int n, int swaptype); +static inline FAR char *med3(FAR char *a, FAR char *b, FAR char *c, + CODE int (*compar)(FAR const void *, + FAR const void *)); /**************************************************************************** * Private Functions ****************************************************************************/ -static inline void swapfunc(char *a, char *b, int n, int swaptype) +static inline void swapfunc(FAR char *a, FAR char *b, int n, int swaptype) { if (swaptype <= 1) { @@ -109,12 +110,13 @@ static inline void swapfunc(char *a, char *b, int n, int swaptype) } } -static inline char *med3(char *a, char *b, char *c, - int (*compar)(const void *, const void *)) +static inline FAR char *med3(FAR char *a, FAR char *b, FAR char *c, + CODE int (*compar)(FAR const void *, + FAR const void *)) { return compar(a, b) < 0 ? - (compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a )) - :(compar(b, c) > 0 ? b : (compar(a, c) < 0 ? a : c )); + (compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a)) : + (compar(b, c) > 0 ? b : (compar(a, c) < 0 ? a : c)); } /**************************************************************************** @@ -125,50 +127,98 @@ static inline char *med3(char *a, char *b, char *c, * Name: qsort * * Description: + * The qsort() function will sort an array of 'nel' objects, the initial + * element of which is pointed to by 'base'. The size of each object, in + * bytes, is specified by the 'width" argument. If the 'nel' argument has + * the value zero, the comparison function pointed to by 'compar' will not + * be called and no rearrangement will take place. + * + * The application will ensure that the comparison function pointed to by + * 'compar' does not alter the contents of the array. The implementation + * may reorder elements of the array between calls to the comparison + * function, but will not alter the contents of any individual element. + * + * When the same objects (consisting of 'width" bytes, irrespective of + * their current positions in the array) are passed more than once to + * the comparison function, the results will be consistent with one + * another. That is, they will define a total ordering on the array. + * + * The contents of the array will be sorted in ascending order according + * to a comparison function. The 'compar' argument is a pointer to the + * comparison function, which is called with two arguments that point to + * the elements being compared. The application will ensure that the + * function returns an integer less than, equal to, or greater than 0, + * if the first argument is considered respectively less than, equal to, + * or greater than the second. If two members compare as equal, their + * order in the sorted array is unspecified. + * + * (Based on description from OpenGroup.org). + * + * Returned Value: + * The qsort() function will not return a value. + * + * Notes from the original BSD version: * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". * ****************************************************************************/ -void qsort(void *base, size_t nmemb, size_t size, - int(*compar)(const void *, const void *)) +void qsort(FAR void *base, size_t nel, size_t width, + CODE int(*compar)(FAR const void *, FAR const void *)) { - char *pa, *pb, *pc, *pd, *pl, *pm, *pn; - int d, r, swaptype, swap_cnt; + FAR char *pa; + FAR char *pb; + FAR char *pc; + FAR char *pd; + FAR char *pl; + FAR char *pm; + FAR char *pn; + int swaptype; + int swap_cnt; + int d; + int r; loop: - SWAPINIT(base, size); + SWAPINIT(base, width); swap_cnt = 0; - if (nmemb < 7) + + if (nel < 7) { - for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size) + for (pm = (FAR char *)base + width; + pm < (FAR char *)base + nel * width; + pm += width) { - for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size) + for (pl = pm; + pl > (FAR char *)base && compar(pl - width, pl) > 0; + pl -= width) { - swap(pl, pl - size); + swap(pl, pl - width); } } + return; } - pm = (char *) base + (nmemb / 2) * size; - if (nmemb > 7) + pm = (FAR char *)base + (nel / 2) * width; + if (nel > 7) { pl = base; - pn = (char *) base + (nmemb - 1) * size; - if (nmemb > 40) + pn = (FAR char *)base + (nel - 1) * width; + if (nel > 40) { - d = (nmemb / 8) * size; + d = (nel / 8) * width; pl = med3(pl, pl + d, pl + 2 * d, compar); pm = med3(pm - d, pm, pm + d, compar); pn = med3(pn - 2 * d, pn - d, pn, compar); } + pm = med3(pl, pm, pn, compar); } + swap(base, pm); - pa = pb = (char *) base + size; + pa = pb = (FAR char *)base + width; - pc = pd = (char *) base + (nmemb - 1) * size; - for (;;) + pc = pd = (FAR char *)base + (nel - 1) * width; + for (; ; ) { while (pb <= pc && (r = compar(pb, base)) <= 0) { @@ -176,19 +226,22 @@ loop: { swap_cnt = 1; swap(pa, pb); - pa += size; + pa += width; } - pb += size; + + pb += width; } + while (pb <= pc && (r = compar(pc, base)) >= 0) { if (r == 0) { swap_cnt = 1; swap(pc, pd); - pd -= size; + pd -= width; } - pc -= size; + + pc -= width; } if (pb > pc) @@ -198,43 +251,47 @@ loop: swap(pb, pc); swap_cnt = 1; - pb += size; - pc -= size; + pb += width; + pc -= width; } if (swap_cnt == 0) { /* Switch to insertion sort */ - for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size) + for (pm = (FAR char *)base + width; + pm < (FAR char *)base + nel * width; + pm += width) { - for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size) + for (pl = pm; + pl > (FAR char *)base && compar(pl - width, pl) > 0; + pl -= width) { - swap(pl, pl - size); + swap(pl, pl - width); } } return; } - pn = (char *) base + nmemb * size; - r = min(pa - (char *)base, pb - pa); + pn = (FAR char *)base + nel * width; + r = min(pa - (FAR char *)base, pb - pa); vecswap(base, pb - r, r); - r = min(pd - pc, pn - pd - size); + + r = min(pd - pc, pn - pd - width); vecswap(pb, pn - r, r); - if ((r = pb - pa) > size) + if ((r = pb - pa) > width) { - qsort(base, r / size, size, compar); + qsort(base, r / width, width, compar); } - if ((r = pd - pc) > size) + if ((r = pd - pc) > width) { /* Iterate rather than recurse to save stack space */ base = pn - r; - nmemb = r / size; + nel = r / width; goto loop; } } - diff --git a/libc/stdlib/lib_strtod.c b/libc/stdlib/lib_strtod.c index 5b462b35270f0b052709d17316f8b9a396dd7dc0..9b7462368bff7b09f5c0d81de814537da3452a85 100644 --- a/libc/stdlib/lib_strtod.c +++ b/libc/stdlib/lib_strtod.c @@ -87,7 +87,7 @@ static inline int is_real(double x) * ****************************************************************************/ -double_t strtod(const char *str, char **endptr) +double_t strtod(FAR const char *str, FAR char **endptr) { double_t number; int exponent; @@ -168,7 +168,7 @@ double_t strtod(const char *str, char **endptr) /* Handle optional sign */ negative = 0; - switch(*++p) + switch (*++p) { case '-': negative = 1; /* Fall through to increment pos */ @@ -238,4 +238,3 @@ double_t strtod(const char *str, char **endptr) } #endif /* CONFIG_HAVE_DOUBLE */ - diff --git a/libc/stdlib/lib_strtol.c b/libc/stdlib/lib_strtol.c index dd17691a07843e7db24ac5d02738a2ff3acc4147..8c7f639901c47eb0c460c28f2ac6286174cb022f 100644 --- a/libc/stdlib/lib_strtol.c +++ b/libc/stdlib/lib_strtol.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions @@ -64,7 +64,7 @@ * ****************************************************************************/ -long strtol(const char *nptr, char **endptr, int base) +long strtol(FAR const char *nptr, FAR char **endptr, int base) { unsigned long accum = 0; bool negate = false; @@ -101,4 +101,3 @@ long strtol(const char *nptr, char **endptr, int base) return (long)accum; } - diff --git a/libc/stdlib/lib_strtoll.c b/libc/stdlib/lib_strtoll.c index af4afb90d1f4e82ed431c5131bc7412da4980747..bc8cc2eb6f484652a8e445639521ae26373bee55 100644 --- a/libc/stdlib/lib_strtoll.c +++ b/libc/stdlib/lib_strtoll.c @@ -42,7 +42,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_HAVE_LONG_LONG @@ -66,7 +66,7 @@ * ****************************************************************************/ -long long strtoll(const char *nptr, char **endptr, int base) +long long strtoll(FAR const char *nptr, FAR char **endptr, int base) { unsigned long long accum = 0; bool negate = false; @@ -105,4 +105,3 @@ long long strtoll(const char *nptr, char **endptr, int base) } #endif - diff --git a/libc/stdlib/lib_strtoul.c b/libc/stdlib/lib_strtoul.c index c9b0915e6fcdac72d2383667dcf7d4bd21aade3e..3dfe5a5e60b0acb20ee41ea476a82937003caaa2 100644 --- a/libc/stdlib/lib_strtoul.c +++ b/libc/stdlib/lib_strtoul.c @@ -41,7 +41,7 @@ #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions @@ -63,7 +63,7 @@ * ****************************************************************************/ -unsigned long strtoul(const char *nptr, char **endptr, int base) +unsigned long strtoul(FAR const char *nptr, FAR char **endptr, int base) { unsigned long accum = 0; int value; @@ -96,4 +96,3 @@ unsigned long strtoul(const char *nptr, char **endptr, int base) return accum; } - diff --git a/libc/stdlib/lib_strtoull.c b/libc/stdlib/lib_strtoull.c index 7e961d7333d6fbfa64ddb6fd7d27ff150fe59686..82adc0450ac2ad7fb0d0f3f508aeb65dbb9752df 100644 --- a/libc/stdlib/lib_strtoull.c +++ b/libc/stdlib/lib_strtoull.c @@ -42,7 +42,7 @@ #include -#include "lib_internal.h" +#include "libc.h" #ifdef CONFIG_HAVE_LONG_LONG @@ -64,7 +64,7 @@ * ****************************************************************************/ -unsigned long long strtoull(const char *nptr, char **endptr, int base) +unsigned long long strtoull(FAR const char *nptr, FAR char **endptr, int base) { unsigned long long accum = 0; int value; @@ -96,5 +96,5 @@ unsigned long long strtoull(const char *nptr, char **endptr, int base) } return accum; } -#endif +#endif diff --git a/libc/string/lib_isbasedigit.c b/libc/string/lib_isbasedigit.c index dff8138811346dd3114e1720a1a1cfec2cddb871..e72e33de5cf4936172eb740b2b473acf75c269f7 100644 --- a/libc/string/lib_isbasedigit.c +++ b/libc/string/lib_isbasedigit.c @@ -43,7 +43,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/string/lib_memccpy.c b/libc/string/lib_memccpy.c index 1d77f58fe9e30cf6e55c94423800311448bfed3f..2201870911e29e0f5abba2db410a794288b99c2a 100644 --- a/libc/string/lib_memccpy.c +++ b/libc/string/lib_memccpy.c @@ -46,7 +46,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ @@ -68,8 +68,8 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n) { - FAR unsigned char *pout = (FAR unsigned char*)s1; - FAR unsigned char *pin = (FAR unsigned char*)s2; + FAR unsigned char *pout = (FAR unsigned char *)s1; + FAR unsigned char *pin = (FAR unsigned char *)s2; /* Copy at most n bytes */ @@ -81,16 +81,12 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n) /* Did we just copy the terminating byte c? */ - if (*pout == (unsigned char)c) + if (*pout++ == (unsigned char)c) { /* Yes return a pointer to the byte after the copy of c into s1 */ return (FAR void *)pout; } - - /* No increment to the next destination location */ - - pout++; } /* C was not found in the first n bytes of s2 */ diff --git a/libc/string/lib_memchr.c b/libc/string/lib_memchr.c index 0ac609104253e66f7358451af292c3237b4c3471..f1fe85baf22f3f797b0b62fc84eecec8c5fdaecd 100644 --- a/libc/string/lib_memchr.c +++ b/libc/string/lib_memchr.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/string/lib_memcmp.c b/libc/string/lib_memcmp.c index 5434bb84742c7ef22ef218df7dc41d91f3c5c109..a4f5004bfd6dbf054f1d69f2cf3c9638fcd8f5b7 100644 --- a/libc/string/lib_memcmp.c +++ b/libc/string/lib_memcmp.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/string/lib_memcmp.c * * Copyright (C) 2007, 2011-2012 Gregory Nutt. All rights reserved. @@ -31,23 +31,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Compilation Switches - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************ - * Global Functions - ************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ #ifndef CONFIG_ARCH_MEMCMP int memcmp(FAR const void *s1, FAR const void *s2, size_t n) diff --git a/libc/string/lib_memcpy.c b/libc/string/lib_memcpy.c index 2ebd5beee135bdbe1929a355dab6748e87b7ae85..6a4b2bbe34c4f47e7d4ea9447cf45dd7ecf956f3 100644 --- a/libc/string/lib_memcpy.c +++ b/libc/string/lib_memcpy.c @@ -46,7 +46,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -56,8 +56,8 @@ #ifndef CONFIG_ARCH_MEMCPY FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n) { - FAR unsigned char *pout = (FAR unsigned char*)dest; - FAR unsigned char *pin = (FAR unsigned char*)src; + FAR unsigned char *pout = (FAR unsigned char *)dest; + FAR unsigned char *pin = (FAR unsigned char *)src; while (n-- > 0) *pout++ = *pin++; return dest; } diff --git a/libc/string/lib_memmove.c b/libc/string/lib_memmove.c index cc83172238c4635c6af4b55257fae8184358d11c..fb672f54eb751fe8d9df0a432056a129a40f51b9 100644 --- a/libc/string/lib_memmove.c +++ b/libc/string/lib_memmove.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/string/lib_memmove.c * * Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved. @@ -31,44 +31,48 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Compilation Switches - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************ - * Global Functions - ************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ #ifndef CONFIG_ARCH_MEMMOVE FAR void *memmove(FAR void *dest, FAR const void *src, size_t count) { - char *tmp, *s; + FAR char *tmp; + FAR char *s; + if (dest <= src) { - tmp = (char*) dest; - s = (char*) src; + tmp = (FAR char *) dest; + s = (FAR char *) src; + while (count--) { - *tmp++ = *s++; + *tmp++ = *s++; } } else { - tmp = (char*) dest + count; - s = (char*) src + count; + tmp = (FAR char *) dest + count; + s = (FAR char *) src + count; + while (count--) { - *--tmp = *--s; + *--tmp = *--s; } } diff --git a/libc/string/lib_memset.c b/libc/string/lib_memset.c index 0b98ebf96f9058d75b786d5c7df435aca550d8d9..fc2f83b30bcc273bf5a65e839d659d3dbd4e63b4 100644 --- a/libc/string/lib_memset.c +++ b/libc/string/lib_memset.c @@ -60,11 +60,11 @@ #endif /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ #ifndef CONFIG_ARCH_MEMSET -void *memset(void *s, int c, size_t n) +FAR void *memset(FAR void *s, int c, size_t n) { #ifdef CONFIG_MEMSET_OPTSPEED /* This version is optimized for speed (you could do better @@ -87,7 +87,7 @@ void *memset(void *s, int c, size_t n) if ((addr & 1) != 0) { - *(uint8_t*)addr = (uint8_t)c; + *(FAR uint8_t *)addr = (uint8_t)c; addr += 1; n -= 1; } @@ -102,7 +102,7 @@ void *memset(void *s, int c, size_t n) if ((addr & 3) != 0) { - *(uint16_t*)addr = val16; + *(FAR uint16_t *)addr = val16; addr += 2; n -= 2; } @@ -112,7 +112,7 @@ void *memset(void *s, int c, size_t n) while (n >= 4) { - *(uint32_t*)addr = val32; + *(FAR uint32_t *)addr = val32; addr += 4; n -= 4; } @@ -127,7 +127,7 @@ void *memset(void *s, int c, size_t n) if ((addr & 7) != 0) { - *(uint32_t*)addr = val32; + *(FAR uint32_t *)addr = val32; addr += 4; n -= 4; } @@ -136,7 +136,7 @@ void *memset(void *s, int c, size_t n) while (n >= 8) { - *(uint64_t*)addr = val64; + *(FAR uint64_t *)addr = val64; addr += 8; n -= 8; } @@ -151,7 +151,7 @@ void *memset(void *s, int c, size_t n) if (n >= 4) { - *(uint32_t*)addr = val32; + *(FAR uint32_t *)addr = val32; addr += 4; n -= 4; } @@ -167,20 +167,20 @@ void *memset(void *s, int c, size_t n) if (n >= 2) { - *(uint16_t*)addr = val16; + *(FAR uint16_t *)addr = val16; addr += 2; n -= 2; } if (n >= 1) { - *(uint8_t*)addr = (uint8_t)c; + *(FAR uint8_t *)addr = (uint8_t)c; } } #else /* This version is optimized for size */ - unsigned char *p = (unsigned char*)s; + FAR unsigned char *p = (FAR unsigned char*)s; while (n-- > 0) *p++ = c; #endif return s; diff --git a/libc/string/lib_skipspace.c b/libc/string/lib_skipspace.c index 4b72b1ec37842f06682cfd201b039449189e9468..602c03a2742c996a4dfe2c461921cb3c92fcd682 100644 --- a/libc/string/lib_skipspace.c +++ b/libc/string/lib_skipspace.c @@ -41,7 +41,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" /**************************************************************************** * Private Functions diff --git a/libc/string/lib_stpcpy.c b/libc/string/lib_stpcpy.c index 046846468efec55dc3910711bda4f7e870e89a23..dd2917f7bc5f30d785b2a7b4154ddc2248060c55 100644 --- a/libc/string/lib_stpcpy.c +++ b/libc/string/lib_stpcpy.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string/lib_strppy.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,21 +31,21 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: stpcpy * * Description: @@ -56,7 +56,7 @@ * The stpcpy() function returns a pointer to the terminating NUL * character copied into the 'dest' buffer * - ************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_ARCH_STPCPY FAR char *stpcpy(FAR char *dest, FAR const char *src) diff --git a/libc/string/lib_strcasecmp.c b/libc/string/lib_strcasecmp.c index df6f08118d2bad159a5a589e0b178276fc8858c2..5fa3e28914973085ff78598b61b51b9eae2c20ac 100644 --- a/libc/string/lib_strcasecmp.c +++ b/libc/string/lib_strcasecmp.c @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -44,13 +44,13 @@ /**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -#ifndef CONFIG_ARCH_STRCMP -int strcasecmp(const char *cs, const char *ct) +#ifndef CONFIG_ARCH_STRCASECMP +int strcasecmp(FAR const char *cs, FAR const char *ct) { int result; - for (;;) + for (; ; ) { if ((result = (int)toupper(*cs) - (int)toupper(*ct)) != 0 || !*cs) { diff --git a/libc/string/lib_strcasestr.c b/libc/string/lib_strcasestr.c index 7f17a686d018eb0a91b7a7ffdbc447279ac4869d..0a56c731802f2f5cd94e27209ca43266a75d00a2 100644 --- a/libc/string/lib_strcasestr.c +++ b/libc/string/lib_strcasestr.c @@ -57,7 +57,7 @@ static FAR char *strcasechr(FAR const char *s, int uc) ch = *s; if (toupper(ch) == uc) { - return (FAR char*)s; + return (FAR char *)s; } } } @@ -66,14 +66,14 @@ static FAR char *strcasechr(FAR const char *s, int uc) } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ FAR char *strcasestr(FAR const char *str, FAR const char *substr) { - const char *candidate; /* Candidate in str with matching start character */ - char ch; /* First character of the substring */ - int len; /* The length of the substring */ + FAR const char *candidate; /* Candidate in str with matching start character */ + char ch; /* First character of the substring */ + int len; /* The length of the substring */ /* Special case the empty substring */ @@ -86,7 +86,7 @@ FAR char *strcasestr(FAR const char *str, FAR const char *substr) * the string */ - return (char*)str; + return (FAR char *)str; } /* Search for the substring */ @@ -94,7 +94,7 @@ FAR char *strcasestr(FAR const char *str, FAR const char *substr) candidate = str; ch = toupper(ch); - for (;;) + for (; ; ) { /* strcasechr() will return a pointer to the next occurrence of the * character ch in the string (ignoring case) @@ -103,23 +103,23 @@ FAR char *strcasestr(FAR const char *str, FAR const char *substr) candidate = strcasechr(candidate, ch); if (!candidate || strlen(candidate) < len) { - /* First character of the substring does not appear in the string - * or the remainder of the string is not long enough to contain the - * substring. - */ + /* First character of the substring does not appear in the string + * or the remainder of the string is not long enough to contain the + * substring. + */ - return NULL; + return NULL; } /* Check if this is the beginning of a matching substring (ignoring case) */ if (strncasecmp(candidate, substr, len) == 0) { - /* Yes.. return the pointer to the first occurrence of the matching - * substring. - */ + /* Yes.. return the pointer to the first occurrence of the matching + * substring. + */ - return (char*)candidate; + return (FAR char *)candidate; } /* No, find the next candidate after this one */ diff --git a/libc/string/lib_strcat.c b/libc/string/lib_strcat.c index b331d3f1c145afea0e91891122b05d433a42a3d9..bc1cfde522cd69ab9b28acb402955575bfa02dc9 100644 --- a/libc/string/lib_strcat.c +++ b/libc/string/lib_strcat.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ #ifndef CONFIG_ARCH_STRCAT diff --git a/libc/string/lib_strchr.c b/libc/string/lib_strchr.c index 7d7cf3757cef5193d0ce493aa989c8a176a240e9..371c8492b03e304295b94d77178b93b38ac0072a 100644 --- a/libc/string/lib_strchr.c +++ b/libc/string/lib_strchr.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/string/lib_strcmp.c b/libc/string/lib_strcmp.c index d4036cd3ea29ddd94a26b3e6b5faa48e78395285..9839c4ee99d108e37da36b2859dcb4150e5672a4 100644 --- a/libc/string/lib_strcmp.c +++ b/libc/string/lib_strcmp.c @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -43,17 +43,18 @@ /**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_ARCH_STRCMP -int strcmp(const char *cs, const char *ct) +int strcmp(FAR const char *cs, FAR const char *ct) { register signed char result; - for (;;) + for (; ; ) { if ((result = *cs - *ct++) != 0 || !*cs++) - break; + break; } + return result; } #endif diff --git a/libc/string/lib_strcpy.c b/libc/string/lib_strcpy.c index efd4f2aca102e6097a2626dd97296d58f1f50d82..f5413688f5245afe2b2c05ae272ba4b3d327e4e0 100644 --- a/libc/string/lib_strcpy.c +++ b/libc/string/lib_strcpy.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string/lib_strcpy.c * * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved. @@ -31,21 +31,21 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: strcpy * * Description: @@ -55,7 +55,7 @@ * Returned value: * The strcpy() function returns the 'dest' pointer * - ************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_ARCH_STRCPY FAR char *strcpy(FAR char *dest, FAR const char *src) diff --git a/libc/string/lib_strcspn.c b/libc/string/lib_strcspn.c index 23e913fadf24f06d8969ad0563be501f3bb86fac..dd4a6928750aa70454d13e12cbaa3ecf3efdc953 100644 --- a/libc/string/lib_strcspn.c +++ b/libc/string/lib_strcspn.c @@ -46,7 +46,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/string/lib_strdup.c b/libc/string/lib_strdup.c index 38eed709c57d4bf656bb1a9a05210986f340cf75..4da233d1637abf519333fc78a4c872491d415e3e 100644 --- a/libc/string/lib_strdup.c +++ b/libc/string/lib_strdup.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string//lib_strdup.c * * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. @@ -31,28 +31,28 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ -FAR char *strdup(const char *s) +FAR char *strdup(FAR const char *s) { FAR char *news = NULL; if (s) { - news = (FAR char*)lib_malloc(strlen(s) + 1); + news = (FAR char *)lib_malloc(strlen(s) + 1); if (news) { strcpy(news, s); diff --git a/libc/string/lib_strerror.c b/libc/string/lib_strerror.c index 58724de35c11e9822394ef623ee5769cc70c5bb4..00eb2248a2e0d0dbb6c394943e0aac380b425222 100644 --- a/libc/string/lib_strerror.c +++ b/libc/string/lib_strerror.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string/lib_strerror.c * * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,13 +43,13 @@ #include #include -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Private Types - ************************************************************************/ + ****************************************************************************/ struct errno_strmap_s { @@ -57,9 +57,9 @@ struct errno_strmap_s const char *str; }; -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_LIBC_STRERROR @@ -334,17 +334,17 @@ static const struct errno_strmap_s g_errnomap[] = #endif /* CONFIG_LIBC_STRERROR */ -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: strerror - ************************************************************************/ + ****************************************************************************/ FAR const char *strerror(int errnum) { diff --git a/libc/string/lib_strlen.c b/libc/string/lib_strlen.c index 6077858e230a28a77f818408a54faf639c003479..e897354e54a07c1d0222d743127e097c9ec3acf9 100644 --- a/libc/string/lib_strlen.c +++ b/libc/string/lib_strlen.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ #ifndef CONFIG_ARCH_STRLEN diff --git a/libc/string/lib_strncasecmp.c b/libc/string/lib_strncasecmp.c index 35f701c5ef29bb0a6f8bf1223fdcbaf2416e6f7b..05d795b0a2c2fda04eb476b0b8248ccaca54f57f 100644 --- a/libc/string/lib_strncasecmp.c +++ b/libc/string/lib_strncasecmp.c @@ -31,15 +31,15 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Compilation Switches - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -48,8 +48,8 @@ #include /**************************************************************************** - * Global Functions - *****************************************************************************/ + * Public Functions + ****************************************************************************/ #ifndef CONFIG_ARCH_STRNCASECMP int strncasecmp(const char *cs, const char *ct, size_t nb) diff --git a/libc/string/lib_strncat.c b/libc/string/lib_strncat.c index 78c54835e084fbd7e6b6a1bf633fdef389fb6590..91ebbf608fa7b79dd988f19d5cebbfd2d1d83bdd 100644 --- a/libc/string/lib_strncat.c +++ b/libc/string/lib_strncat.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/string/lib_strncat.c * * Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved. @@ -31,19 +31,19 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************ - * Global Functions - ************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ #ifndef CONFIG_ARCH_STRNCAT char *strncat(char *dest, const char *src, size_t n) diff --git a/libc/string/lib_strncmp.c b/libc/string/lib_strncmp.c index 179cf031a4654d6f19744fdd4daf7cc05e060368..92df02a20bcaf691b729960032e424782c910c28 100644 --- a/libc/string/lib_strncmp.c +++ b/libc/string/lib_strncmp.c @@ -31,23 +31,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Compilation Switches - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include #include /**************************************************************************** - * Global Functions - *****************************************************************************/ + * Public Functions + ****************************************************************************/ #ifndef CONFIG_ARCH_STRNCMP int strncmp(const char *cs, const char *ct, size_t nb) diff --git a/libc/string/lib_strncpy.c b/libc/string/lib_strncpy.c index 095111c94df68c87920109edd2edf7b48052a9fc..dbafc1c3a171489ffa5252cae37ae73d1645f0cf 100644 --- a/libc/string/lib_strncpy.c +++ b/libc/string/lib_strncpy.c @@ -1,4 +1,4 @@ -/************************************************************ +/**************************************************************************** * libc/string/lib_strncpy.c * * Copyright (C) 2007, 2011, 2014 Gregory Nutt. All rights reserved. @@ -31,23 +31,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************ +/**************************************************************************** * Public Functions - ************************************************************/ + ****************************************************************************/ -/************************************************************ +/**************************************************************************** * Name: strncpy - ************************************************************/ + ****************************************************************************/ #ifndef CONFIG_ARCH_STRNCPY char *strncpy(FAR char *dest, FAR const char *src, size_t n) diff --git a/libc/string/lib_strndup.c b/libc/string/lib_strndup.c index 5a78e2dcfed9f7dc432ad0e616363fdd6c52ad09..1c097de81a0cb037dae9962a7a17567f35fdce09 100644 --- a/libc/string/lib_strndup.c +++ b/libc/string/lib_strndup.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string//lib_strndup.c * * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. @@ -31,22 +31,22 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -#include "lib_internal.h" +#include "libc.h" -/************************************************************************ - * Global Functions - ************************************************************************/ -/************************************************************************ +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** * Name: strndup * * Description: @@ -61,7 +61,7 @@ * character. The newly created string will always be properly * terminated. * - ************************************************************************/ + ****************************************************************************/ FAR char *strndup(FAR const char *s, size_t size) { @@ -74,7 +74,7 @@ FAR char *strndup(FAR const char *s, size_t size) /* Allocate the new string, adding 1 for the NUL terminator */ - news = (FAR char*)lib_malloc(allocsize + 1); + news = (FAR char *)lib_malloc(allocsize + 1); if (news) { /* Copy the string into the allocated memory and add a NUL diff --git a/libc/string/lib_strnlen.c b/libc/string/lib_strnlen.c index 9bc3064cb1903b3a8213a6862fad1a77097013ab..863a310caad60f13dcdce61829468979810c01d1 100644 --- a/libc/string/lib_strnlen.c +++ b/libc/string/lib_strnlen.c @@ -49,7 +49,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ #ifndef CONFIG_ARCH_STRNLEN diff --git a/libc/string/lib_strpbrk.c b/libc/string/lib_strpbrk.c index 3f19dec6e65d9fae0d462abda912509a568c55d0..4170926bb6843c723d98814b924e370b3f39c523 100644 --- a/libc/string/lib_strpbrk.c +++ b/libc/string/lib_strpbrk.c @@ -42,10 +42,10 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ -char *strpbrk(const char *str, const char *charset) +FAR char *strpbrk(FAR const char *str, FAR const char *charset) { /* Sanity checking */ @@ -66,8 +66,8 @@ char *strpbrk(const char *str, const char *charset) { /* Yes, then this position must be the first occurrence in string */ - return (char*)str; - } + return (FAR char *)str; + } /* This character from the strings matches none of those in the charset. * Try the next character from the string. diff --git a/libc/string/lib_strrchr.c b/libc/string/lib_strrchr.c index 08575c82bf589ca127a3c975bde3ad508037c46c..3b08598bb26a1605f66e171cd25e2303787e2ba5 100644 --- a/libc/string/lib_strrchr.c +++ b/libc/string/lib_strrchr.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * libc/string/lib_strrchr.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,25 +31,25 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ /* The strrchr() function returns a pointer to the last * occurrence of the character c in the string s. */ -char *strrchr(const char *s, int c) +FAR char *strrchr(FAR const char *s, int c) { if (s) { @@ -58,7 +58,7 @@ char *strrchr(const char *s, int c) { if (*p == c) { - return (char*)p; + return (FAR char *)p; } } } diff --git a/libc/string/lib_strspn.c b/libc/string/lib_strspn.c index 6894b2b9dc75e67e9dd89e8db51db9756bd9bab6..47ab34d8b203eaa23589d9dd0afc82c2788cf011 100644 --- a/libc/string/lib_strspn.c +++ b/libc/string/lib_strspn.c @@ -46,7 +46,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/string/lib_strstr.c b/libc/string/lib_strstr.c index 0c695f7de27609c37eda36069805b332289b571b..06404402a943cd7094cb285cef7f15e23d5025eb 100644 --- a/libc/string/lib_strstr.c +++ b/libc/string/lib_strstr.c @@ -42,7 +42,7 @@ #include /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ FAR char *strstr(FAR const char *str, FAR const char *substr) @@ -62,13 +62,13 @@ FAR char *strstr(FAR const char *str, FAR const char *substr) * the string */ - return (char*)str; + return (FAR char *)str; } /* Search for the substring */ candidate = str; - for (;;) + for (; ; ) { /* strchr() will return a pointer to the next occurrence of the * character ch in the string @@ -77,19 +77,19 @@ FAR char *strstr(FAR const char *str, FAR const char *substr) candidate = strchr(candidate, ch); if (!candidate || strlen(candidate) < len) { - /* First character of the substring does not appear in the string - * or the remainder of the string is not long enough to contain the - * substring. - */ + /* First character of the substring does not appear in the string + * or the remainder of the string is not long enough to contain the + * substring. + */ - return NULL; + return NULL; } /* Check if this is the beginning of a matching substring */ if (strncmp(candidate, substr, len) == 0) { - return (char*)candidate; + return (FAR char *)candidate; } /* No, find the next candidate after this one */ diff --git a/libc/string/lib_vikmemcpy.c b/libc/string/lib_vikmemcpy.c index 264b2f2511fcbf5aabdc96c5647ce07ed46c6e75..41ab3ecf37185c755d29cfbb893049a5fd1985ab 100644 --- a/libc/string/lib_vikmemcpy.c +++ b/libc/string/lib_vikmemcpy.c @@ -57,9 +57,9 @@ #define CONFIG_MEMCPY_INDEXED_COPY -/******************************************************************** +/**************************************************************************** * Included Files - *******************************************************************/ + ****************************************************************************/ #include #include @@ -68,9 +68,9 @@ #include #include -/******************************************************************** +/**************************************************************************** * Pre-processor Definitions - *******************************************************************/ + ****************************************************************************/ /* Can't support CONFIG_MEMCPY_64BIT if the platform does not have 64-bit * integer types. @@ -124,10 +124,10 @@ #endif /* CONFIG_ENDIAN_BIG */ -/******************************************************************** +/**************************************************************************** * Macros for copying words of different alignment. * Uses incremening pointers. - *******************************************************************/ + ****************************************************************************/ #define CP_INCR() \ { \ @@ -142,10 +142,10 @@ INC_VAL(dstN) = dstWord; \ } -/******************************************************************** +/**************************************************************************** * Macros for copying words of different alignment. * Uses array indexes. - *******************************************************************/ + ****************************************************************************/ #define CP_INDEX(idx) \ { \ @@ -160,11 +160,11 @@ dstN[x] = dstWord; \ } -/******************************************************************** +/**************************************************************************** * Macros for copying words of different alignment. * Uses incremening pointers or array indexes depending on * configuration. - *******************************************************************/ + ****************************************************************************/ #if defined (CONFIG_MEMCPY_INDEXED_COPY) @@ -279,9 +279,9 @@ return dest; \ } -/******************************************************************** +/**************************************************************************** * Type Definitions - *******************************************************************/ + ****************************************************************************/ #ifdef CONFIG_MEMCPY_64BIT typedef uint64_t UIntN; @@ -291,10 +291,10 @@ typedef uint32_t UIntN; # define TYPE_WIDTH 4L #endif -/******************************************************************** +/**************************************************************************** * Public Functions - *******************************************************************/ -/******************************************************************** + ****************************************************************************/ +/**************************************************************************** * Name: memcpy * * Description: @@ -308,12 +308,12 @@ typedef uint32_t UIntN; * Returned Value: * A pointer to destination buffer * - *******************************************************************/ + ****************************************************************************/ -void *memcpy(void *dest, const void *src, size_t count) +FAR void *memcpy(FAR void *dest, FAR const void *src, size_t count) { - uint8_t *dst8 = (uint8_t*)dest; - uint8_t *src8 = (uint8_t*)src; + FAR uint8_t *dst8 = (FAR uint8_t *)dest; + FAR uint8_t *src8 = (FAR uint8_t *)src; if (count < 8) { diff --git a/libc/symtab/Make.defs b/libc/symtab/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..84f2ed23f8b543c75085bc98204e74f5c94787c1 --- /dev/null +++ b/libc/symtab/Make.defs @@ -0,0 +1,44 @@ +############################################################################ +# libc/symtab/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Symbol table source files + +CSRCS += symtab_findbyname.c symtab_findbyvalue.c +CSRCS += symtab_findorderedbyname.c symtab_findorderedbyvalue.c + +# Add the symtab directory to the build + +DEPPATH += --dep-path symtab +VPATH += :symtab diff --git a/binfmt/symtab_findbyname.c b/libc/symtab/symtab_findbyname.c similarity index 78% rename from binfmt/symtab_findbyname.c rename to libc/symtab/symtab_findbyname.c index c0343e2708b815c874186faf12dec138a1514317..e84e5eb5271ab0a56490bd518f78a67ca7a5e4da 100644 --- a/binfmt/symtab_findbyname.c +++ b/libc/symtab/symtab_findbyname.c @@ -1,7 +1,7 @@ /**************************************************************************** - * binfmt/symtab_findbyname.c + * libc/symtab/symtab_findbyname.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,27 +44,11 @@ #include #include -#include +#include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/*********************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: symtab_findbyname @@ -94,4 +78,3 @@ symtab_findbyname(FAR const struct symtab_s *symtab, } return NULL; } - diff --git a/binfmt/symtab_findbyvalue.c b/libc/symtab/symtab_findbyvalue.c similarity index 81% rename from binfmt/symtab_findbyvalue.c rename to libc/symtab/symtab_findbyvalue.c index c47d5c7518f9f273e7bdca3e7ebf40f06d4c7f3c..d3a12105d1a94fa23f0ab7ca0860ee6b24da2408 100644 --- a/binfmt/symtab_findbyvalue.c +++ b/libc/symtab/symtab_findbyvalue.c @@ -1,7 +1,7 @@ /**************************************************************************** - * binfmt/symtab_findbyvalue.c + * libc/symtab/symtab_findbyvalue.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,27 +44,11 @@ #include #include -#include +#include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/*********************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: symtab_findbyvalue @@ -118,4 +102,3 @@ symtab_findbyvalue(FAR const struct symtab_s *symtab, return retval; } - diff --git a/binfmt/symtab_findorderedbyname.c b/libc/symtab/symtab_findorderedbyname.c similarity index 77% rename from binfmt/symtab_findorderedbyname.c rename to libc/symtab/symtab_findorderedbyname.c index ce63b458b0ad0249c7430bb451d28d8defed0a49..40d6e883a2cf96cb5549a27098adf4f946555784 100644 --- a/binfmt/symtab_findorderedbyname.c +++ b/libc/symtab/symtab_findorderedbyname.c @@ -1,7 +1,7 @@ /**************************************************************************** - * binfmt/symtab_findorderedbyname.c + * libc/symtab/symtab_findorderedbyname.c * - * Copyright (C) 2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,27 +44,11 @@ #include #include -#include +#include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/*********************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: symtab_findorderedbyname @@ -129,13 +113,13 @@ symtab_findorderedbyname(FAR const struct symtab_s *symtab, } } - /* low == high... One final check. We might not have actually tested - * the final symtab[] name. - * - * Example: Only the last pass through loop, suppose low = 1, high = 2, - * mid = 1, and symtab[high].sym_name == name. Then we would get here with - * low = 2, high = 2, but symtab[2].sym_name was never tested. - */ + /* low == high... One final check. We might not have actually tested + * the final symtab[] name. + * + * Example: Only the last pass through loop, suppose low = 1, high = 2, + * mid = 1, and symtab[high].sym_name == name. Then we would get here with + * low = 2, high = 2, but symtab[2].sym_name was never tested. + */ return strcmp(name, symtab[low].sym_name) == 0 ? &symtab[low] : NULL; } diff --git a/binfmt/symtab_findorderedbyvalue.c b/libc/symtab/symtab_findorderedbyvalue.c similarity index 74% rename from binfmt/symtab_findorderedbyvalue.c rename to libc/symtab/symtab_findorderedbyvalue.c index bad4bf8cd7825252ba6b0c44c004d5b736a9dfcb..253ec2cc5fb9a6bca5b736cd228b6a1921aa5758 100644 --- a/binfmt/symtab_findorderedbyvalue.c +++ b/libc/symtab/symtab_findorderedbyvalue.c @@ -1,7 +1,7 @@ /**************************************************************************** - * binfmt/symtab_findorderedbyvalue.c + * libc/symtab/symtab_findorderedbyvalue.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,27 +44,11 @@ #include #include -#include +#include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/*********************************************************************** * Public Functions - ***********************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: symtab_findorderedbyvalue @@ -100,7 +84,7 @@ symtab_findorderedbyvalue(FAR const struct symtab_s *symtab, */ mid = (low + high) >> 1; - if ( value < symtab[mid].sym_value) + if (value < symtab[mid].sym_value) { high = mid - 1; } @@ -114,14 +98,13 @@ symtab_findorderedbyvalue(FAR const struct symtab_s *symtab, } } - /* low == high... One final check. We might not have actually tested - * the final symtab[] name. - * - * Example: Only the last pass through loop, suppose low = 1, high = 2, - * mid = 1, and symtab[high].sym_name == name. Then we would get here with - * low = 2, high = 2, but symtab[2].sym_name was never tested. - */ + /* low == high... One final check. We might not have actually tested + * the final symtab[] name. + * + * Example: Only the last pass through loop, suppose low = 1, high = 2, + * mid = 1, and symtab[high].sym_name == name. Then we would get here with + * low = 2, high = 2, but symtab[2].sym_name was never tested. + */ return value == symtab[low].sym_value ? &symtab[low] : NULL; } - diff --git a/libc/syslog/lib_lowsyslog.c b/libc/syslog/lib_lowsyslog.c index 79c4a99ff88edb0b09109f398b4db843024fa852..1ea8540781171404cdb27575dfb3801e31db4546 100644 --- a/libc/syslog/lib_lowsyslog.c +++ b/libc/syslog/lib_lowsyslog.c @@ -61,15 +61,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Global Constant Data + * Public Constant Data ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -93,7 +93,7 @@ * ****************************************************************************/ -static inline int lowvsyslog_internal(FAR const char *fmt, va_list ap) +static inline int lowvsyslog_internal(FAR const IPTR char *fmt, va_list ap) { struct lib_outstream_s stream; @@ -121,7 +121,7 @@ static inline int lowvsyslog_internal(FAR const char *fmt, va_list ap) * ****************************************************************************/ -int lowvsyslog(int priority, FAR const char *fmt, va_list ap) +int lowvsyslog(int priority, FAR const IPTR char *fmt, va_list ap) { int ret = 0; @@ -154,7 +154,7 @@ int lowvsyslog(int priority, FAR const char *fmt, va_list ap) * ****************************************************************************/ -int lowsyslog(int priority, FAR const char *fmt, ...) +int lowsyslog(int priority, FAR const IPTR char *fmt, ...) { va_list ap; int ret; diff --git a/libc/syslog/lib_setlogmask.c b/libc/syslog/lib_setlogmask.c index f51572e408720655359652ca68c6cb9f0984c246..2179b7b6a93df637b0e5b88ed7fe1d9c01cb0e3b 100644 --- a/libc/syslog/lib_setlogmask.c +++ b/libc/syslog/lib_setlogmask.c @@ -1,7 +1,7 @@ /**************************************************************************** * lib/syslog/lib_setlogmask.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ #include #include -#include +#include #include "syslog/syslog.h" @@ -97,11 +97,11 @@ int setlogmask(int mask) * as interrupts. */ - flags = irqsave(); + flags = enter_critical_section(); oldmask = g_syslog_mask; g_syslog_mask = (uint8_t)mask; - irqrestore(flags); + leave_critical_section(flags); return oldmask; } diff --git a/libc/syslog/lib_syslog.c b/libc/syslog/lib_syslog.c index 636401046142c6bcf31887cd9e59b698561da91a..f6e35b35b563309565c49af0fdab22766bb872a9 100644 --- a/libc/syslog/lib_syslog.c +++ b/libc/syslog/lib_syslog.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/syslog/lib_syslog.c * - * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,43 +42,12 @@ #include #include +#include #include #include #include "syslog/syslog.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Global Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Global Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -92,7 +61,7 @@ * ****************************************************************************/ -static inline int vsyslog_internal(FAR const char *fmt, va_list ap) +static inline int vsyslog_internal(FAR const IPTR char *fmt, va_list ap) { #if defined(CONFIG_SYSLOG) struct lib_outstream_s stream; @@ -104,11 +73,19 @@ static inline int vsyslog_internal(FAR const char *fmt, va_list ap) #if defined(CONFIG_SYSLOG_TIMESTAMP) struct timespec ts; - int ret; - /* Get the current time */ + /* Get the current time. Since debug output may be generated very early + * in the start-up sequence, hardware timer support may not yet be + * available. + */ - ret = clock_systimespec(&ts); + if (!OSINIT_HW_READY() || clock_systimespec(&ts) < 0) + { + /* Timer hardware is not available, or clock_systimespec failed */ + + ts.tv_sec = 0; + ts.tv_nsec = 0; + } #endif #if defined(CONFIG_SYSLOG) @@ -119,14 +96,11 @@ static inline int vsyslog_internal(FAR const char *fmt, va_list ap) lib_syslogstream((FAR struct lib_outstream_s *)&stream); #if defined(CONFIG_SYSLOG_TIMESTAMP) - /* Pre-pend the message with the current time */ + /* Pre-pend the message with the current time, if available */ + + (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, + "[%6d.%06d]", ts.tv_sec, ts.tv_nsec/1000); - if (ret == OK) - { - (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, - "[%6d.%06d]", - ts.tv_sec, ts.tv_nsec/1000); - } #endif return lib_vsprintf((FAR struct lib_outstream_s *)&stream, fmt, ap); @@ -139,14 +113,10 @@ static inline int vsyslog_internal(FAR const char *fmt, va_list ap) lib_rawoutstream(&stream, 1); #if defined(CONFIG_SYSLOG_TIMESTAMP) - /* Pre-pend the message with the current time */ + /* Pre-pend the message with the current time, if available */ - if (ret == OK) - { - (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, - "[%6d.%06d]", - ts.tv_sec, ts.tv_nsec/1000); - } + (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, + "[%6d.%06d]", ts.tv_sec, ts.tv_nsec/1000); #endif return lib_vsprintf(&stream.public, fmt, ap); @@ -159,20 +129,18 @@ static inline int vsyslog_internal(FAR const char *fmt, va_list ap) lib_lowoutstream((FAR struct lib_outstream_s *)&stream); #if defined(CONFIG_SYSLOG_TIMESTAMP) - /* Pre-pend the message with the current time */ + /* Pre-pend the message with the current time, if available */ - if (ret == OK) - { - (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, - "[%6d.%06d]", - ts.tv_sec, ts.tv_nsec/1000); - } + (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, + "[%6d.%06d]", ts.tv_sec, ts.tv_nsec/1000); #endif return lib_vsprintf((FAR struct lib_outstream_s *)&stream, fmt, ap); #else /* CONFIG_SYSLOG */ + return 0; + #endif /* CONFIG_SYSLOG */ } @@ -190,7 +158,7 @@ static inline int vsyslog_internal(FAR const char *fmt, va_list ap) * ****************************************************************************/ -int vsyslog(int priority, FAR const char *fmt, va_list ap) +int vsyslog(int priority, FAR const IPTR char *fmt, va_list ap) { int ret = 0; @@ -220,7 +188,7 @@ int vsyslog(int priority, FAR const char *fmt, va_list ap) * ****************************************************************************/ -int syslog(int priority, FAR const char *fmt, ...) +int syslog(int priority, FAR const IPTR char *fmt, ...) { va_list ap; int ret; diff --git a/libc/termios/lib_cfgetspeed.c b/libc/termios/lib_cfgetspeed.c index 1cd5ee96d3633fb2de0ab8da81910038f4adbf05..507890a10d1fd422082ae7bc16af4fbaf342d37f 100644 --- a/libc/termios/lib_cfgetspeed.c +++ b/libc/termios/lib_cfgetspeed.c @@ -45,11 +45,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/termios/lib_cfsetspeed.c b/libc/termios/lib_cfsetspeed.c index bb1bde7011ae713456fce291ed3fd7b29f5305a4..7dce45d6a9a79c1214c09961e82faef888cdba01 100644 --- a/libc/termios/lib_cfsetspeed.c +++ b/libc/termios/lib_cfsetspeed.c @@ -46,11 +46,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/termios/lib_tcflush.c b/libc/termios/lib_tcflush.c index 1a9710f6a0a01a5b2efc97f677bc47ada0c627f5..013ebd49847749df8476885652a6d3a08c38823d 100644 --- a/libc/termios/lib_tcflush.c +++ b/libc/termios/lib_tcflush.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/termios/lib_tcgetattr.c b/libc/termios/lib_tcgetattr.c index 631bb60638d5186e8a9d6e22ddf8ce7dc27a5fac..447e2ecf01933075c4ef4b4fe76ab7b4a1744ee3 100644 --- a/libc/termios/lib_tcgetattr.c +++ b/libc/termios/lib_tcgetattr.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/termios/lib_tcsetattr.c b/libc/termios/lib_tcsetattr.c index 8d7b5ccb076ab07b4673a2514075f1b7c98c0991..ab93e2aafd46041dd5062854fcb43f7efd5aa91c 100644 --- a/libc/termios/lib_tcsetattr.c +++ b/libc/termios/lib_tcsetattr.c @@ -51,11 +51,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/time/lib_asctime.c b/libc/time/lib_asctime.c index 6583969dc8add51f3d47efdd702d29761f515d0c..cd15699559e1c38a0a9a3c133b99b3e63827be04 100644 --- a/libc/time/lib_asctime.c +++ b/libc/time/lib_asctime.c @@ -41,7 +41,7 @@ #include -#ifdef CONFIG_TIME_EXTENDED +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) /**************************************************************************** * Public Functions @@ -70,4 +70,4 @@ FAR char *asctime(FAR const struct tm *tp) return asctime_r(tp, buf); } -#endif /* CONFIG_TIME_EXTENDED */ +#endif /* CONFIG_LIBC_LOCALTIME || CONFIG_TIME_EXTENDED */ diff --git a/libc/time/lib_asctimer.c b/libc/time/lib_asctimer.c index 77ee312796d742416f223ed325f1fb43c9ee91f5..0235b89c15709e1e9802f9aa7d594937a4ea6427 100644 --- a/libc/time/lib_asctimer.c +++ b/libc/time/lib_asctimer.c @@ -42,7 +42,7 @@ #include #include -#ifdef CONFIG_TIME_EXTENDED +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) /**************************************************************************** * Private Data @@ -94,4 +94,4 @@ FAR char *asctime_r(FAR const struct tm *tp, FAR char *buf) return buf; } -#endif /* CONFIG_TIME_EXTENDED */ +#endif /* CONFIG_LIBC_LOCALTIME || CONFIG_TIME_EXTENDED */ diff --git a/libc/time/lib_calendar2utc.c b/libc/time/lib_calendar2utc.c index 4ed9f1d60852fb110a9b30e780fdcb66f2efa7b9..2c2d507d9dcacce1fdeda3b0e363bea298c26240 100644 --- a/libc/time/lib_calendar2utc.c +++ b/libc/time/lib_calendar2utc.c @@ -62,11 +62,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/time/lib_ctime.c b/libc/time/lib_ctime.c index 2d0b8023ab1aa922b0f514e1e58efd61f399487d..6d1bcb8efeb1d8174e0867e4664dedb18e7c2677 100644 --- a/libc/time/lib_ctime.c +++ b/libc/time/lib_ctime.c @@ -41,7 +41,7 @@ #include -#ifdef CONFIG_TIME_EXTENDED +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) /**************************************************************************** * Public Functions @@ -79,4 +79,4 @@ FAR char *ctime(FAR const time_t *timep) #endif } -#endif /* CONFIG_TIME_EXTENDED */ +#endif /* CONFIG_LIBC_LOCALTIME || CONFIG_TIME_EXTENDED */ diff --git a/libc/time/lib_ctimer.c b/libc/time/lib_ctimer.c index 7f7cf0b31c550756d3e9fa9a555c98d2b5a08f00..935a72bbd6fe1bed0877a309cf638bf4d03ed246 100644 --- a/libc/time/lib_ctimer.c +++ b/libc/time/lib_ctimer.c @@ -41,7 +41,7 @@ #include -#ifdef CONFIG_TIME_EXTENDED +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) /**************************************************************************** * Private Data @@ -80,4 +80,4 @@ FAR char *ctime_r(FAR const time_t *timep, FAR char *buf) #endif } -#endif /* CONFIG_TIME_EXTENDED */ +#endif /* CONFIG_LIBC_LOCALTIME || CONFIG_TIME_EXTENDED */ diff --git a/libc/time/lib_dayofweek.c b/libc/time/lib_dayofweek.c index 40d7516dc45d80a6d33390cd08557a79b4308932..bf1ed7280f1959794efd392504621e5308afd484 100644 --- a/libc/time/lib_dayofweek.c +++ b/libc/time/lib_dayofweek.c @@ -64,11 +64,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -104,6 +104,7 @@ int clock_dayoftheweek(int mday, int month, int year) } month -= 2; - return (mday + year + year/4 - year/100 + year/400 + ( 31 * month) / 12) % 7; + return (mday + year + year / 4 - year / 100 + year / 400 + + (31 * month) / 12) % 7; } #endif /* CONFIG_TIME_EXTENDED */ diff --git a/libc/time/lib_daysbeforemonth.c b/libc/time/lib_daysbeforemonth.c index ec08afbdae34d4251ae4bf304828305296aa9e33..8c09c2203e8479645222b7353b62e653efba674b 100644 --- a/libc/time/lib_daysbeforemonth.c +++ b/libc/time/lib_daysbeforemonth.c @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static const uint16_t g_daysbeforemonth[13] = diff --git a/libc/time/lib_gmtime.c b/libc/time/lib_gmtime.c index 9ad670900323435579d89bfa7b4b3ebd41e6c58a..1eeade4675e922c93eab5bbf07da35f2022d4656 100644 --- a/libc/time/lib_gmtime.c +++ b/libc/time/lib_gmtime.c @@ -57,17 +57,17 @@ * Private Function Prototypes ****************************************************************************/ -/************************************************************************** +/**************************************************************************** * Public Constant Data - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ -/************************************************************************** - * Private Variables - **************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ /**************************************************************************** * Private Functions diff --git a/libc/time/lib_gmtimer.c b/libc/time/lib_gmtimer.c index 59b32fe57ed5179fd9db15245ad041159c641cc5..d6b224cfcc04cd323a95ad19964a307217d91fb3 100644 --- a/libc/time/lib_gmtimer.c +++ b/libc/time/lib_gmtimer.c @@ -73,17 +73,17 @@ static void clock_utc2julian(time_t jdn, int *year, int *month, int *day); #endif /* CONFIG_JULIAN_TIME */ #endif /* CONFIG_GREGORIAN_TIME */ -/************************************************************************** +/**************************************************************************** * Public Constant Data - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ -/************************************************************************** - * Private Variables - **************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ /**************************************************************************** * Private Functions @@ -169,7 +169,8 @@ static void clock_utc2julian(time_t jd, int *year, int *month, int *day) /* Only handles dates since Jan 1, 1970 */ -static void clock_utc2calendar(time_t days, int *year, int *month, int *day) +static void clock_utc2calendar(time_t days, FAR int *year, FAR int *month, + FAR int *day) { int value; int min; @@ -181,13 +182,13 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day) * following: */ - value = days / (4*365 + 1); /* Number of 4-years periods since the epoch*/ - days -= value * (4*365 + 1); /* Remaining days */ - value <<= 2; /* Years since the epoch */ + value = days / (4 * 365 + 1); /* Number of 4-years periods since the epoch */ + days -= value * (4 * 365 + 1); /* Remaining days */ + value <<= 2; /* Years since the epoch */ /* Then we will brute force the next 0-3 years */ - for (;;) + for (; ; ) { /* Is this year a leap year (we'll need this later too) */ @@ -231,7 +232,7 @@ static void clock_utc2calendar(time_t days, int *year, int *month, int *day) /* Get the number of days that occurred before the beginning of the month * following the midpoint. - */ + */ tmp = clock_daysbeforemonth(value + 1, leapyear); diff --git a/libc/time/lib_isleapyear.c b/libc/time/lib_isleapyear.c index 2a1a8664c4cbdf77614706737af65f61631b5e3d..3bad316477474b2606a5c7546db42144dd27782c 100644 --- a/libc/time/lib_isleapyear.c +++ b/libc/time/lib_isleapyear.c @@ -58,11 +58,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/time/lib_localtime.c b/libc/time/lib_localtime.c index 6e587f9486d4e756f391203a4601b140d7e238fc..c091d3d50de063c11ce1301d724cde3d52115831 100644 --- a/libc/time/lib_localtime.c +++ b/libc/time/lib_localtime.c @@ -437,10 +437,10 @@ static void settzname(void) FAR struct state_s *const sp = lclptr; int i; - tzname[0] = tzname[1] = (FAR char*)g_wildabbr; + tzname[0] = tzname[1] = (FAR char *)g_wildabbr; if (sp == NULL) { - tzname[0] = tzname[1] = (FAR char*)GMT; + tzname[0] = tzname[1] = (FAR char *)GMT; return; } @@ -528,6 +528,7 @@ static int tzload(FAR const char *name, struct state_s st; } u; }; + char *fullname; u_t *up; int doaccess; @@ -1158,7 +1159,7 @@ static FAR const char *getrule(FAR const char *strp, return strp; } -/*Given a year, a rule, and the offset from UT at the time that rule takes +/* Given a year, a rule, and the offset from UT at the time that rule takes * effect, calculate the year-relative time that rule takes effect. */ @@ -2122,7 +2123,7 @@ static time_t time2sub(struct tm *const tmp, } } - for (;;) + for (; ; ) { i = g_mon_lengths[isleap(y)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) @@ -2198,7 +2199,7 @@ static time_t time2sub(struct tm *const tmp, hi = -(lo + 1); } - for (;;) + for (; ; ) { t = lo / 2 + hi / 2; if (t < lo) diff --git a/libc/time/lib_mktime.c b/libc/time/lib_mktime.c index b216c8dc3512e106c0e19f091b2c709f04694036..5798ce530992216d89d45d002a910f3dee901905 100644 --- a/libc/time/lib_mktime.c +++ b/libc/time/lib_mktime.c @@ -61,11 +61,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/time/lib_settimeofday.c b/libc/time/lib_settimeofday.c index a28b634a7e2172438ade9557eb603677eebb677a..ea404b7e0397b96da280274ced858c914287bd68 100644 --- a/libc/time/lib_settimeofday.c +++ b/libc/time/lib_settimeofday.c @@ -83,8 +83,8 @@ int settimeofday(FAR const struct timeval *tv, FAR struct timezone *tz) /* Convert the timeval to a timespec */ - ts.tv_sec = tv->tv_sec; - ts.tv_nsec = tv->tv_usec * NSEC_PER_USEC; + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * NSEC_PER_USEC; /* Let clock_settime do the work */ diff --git a/libc/time/lib_strftime.c b/libc/time/lib_strftime.c index 83171c7cb41ba55221bfa35ffc057491c780cecf..6af922029765cfec3cb2ca05fbcb43eb7360a338 100644 --- a/libc/time/lib_strftime.c +++ b/libc/time/lib_strftime.c @@ -70,7 +70,19 @@ * Private Data ****************************************************************************/ -static const char * const g_abbrevmonthname[12] = +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) +static const char * const g_abbrev_wdayname[7] = +{ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static const char * const g_wdayname[7] = +{ + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +}; +#endif + +static const char * const g_abbrev_monthname[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" @@ -169,6 +181,31 @@ size_t strftime(FAR char *s, size_t max, FAR const char *format, switch (*format++) { +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* %a: A three-letter abbreviation for the day of the week. */ + + case 'a': + { + if (tm->tm_wday < 7) + { + str = g_abbrev_wdayname[tm->tm_wday]; + len = snprintf(dest, chleft, "%s", str); + } + } + break; + + /* %A: The full name for the day of the week. */ + + case 'A': + { + if (tm->tm_wday < 7) + { + str = g_wdayname[tm->tm_wday]; + len = snprintf(dest, chleft, "%s", str); + } + } + break; +#else /* %a: A three-letter abbreviation for the day of the week. */ /* %A: The full name for the day of the week. */ @@ -178,6 +215,7 @@ size_t strftime(FAR char *s, size_t max, FAR const char *format, len = snprintf(dest, chleft, "Day"); /* Not supported */ } break; +#endif /* %h: Equivalent to %b */ @@ -189,7 +227,7 @@ size_t strftime(FAR char *s, size_t max, FAR const char *format, { if (tm->tm_mon < 12) { - str = g_abbrevmonthname[tm->tm_mon]; + str = g_abbrev_monthname[tm->tm_mon]; len = snprintf(dest, chleft, "%s", str); } } diff --git a/libc/tls/Make.defs b/libc/tls/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..c948e071944e384dc98cfabcf67e7eed74de766d --- /dev/null +++ b/libc/tls/Make.defs @@ -0,0 +1,45 @@ +############################################################################ +# libc/tls/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_TLS),y) + +CSRCS += tls_setelem.c tls_getelem.c + +# Include tls build support + +DEPPATH += --dep-path tls +VPATH += :tls + +endif diff --git a/libc/tls/tls.h b/libc/tls/tls.h new file mode 100644 index 0000000000000000000000000000000000000000..c7d361a3f795d08aa5964b33f27ad71ae32cd5f1 --- /dev/null +++ b/libc/tls/tls.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * sched/tls/tls.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __SCHED_TLS_TLS_H +#define __SCHED_TLS_TLS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __SCHED_TLS_TLS_H */ diff --git a/libc/tls/tls_getelem.c b/libc/tls/tls_getelem.c new file mode 100644 index 0000000000000000000000000000000000000000..a7a10299fc51c460295e4e3a3a5de1864aecd35e --- /dev/null +++ b/libc/tls/tls_getelem.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * libc/fixedmath/tls_getelem.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_TLS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_get_element + * + * Description: + * Return an the TLS element associated with the 'elem' index + * + * Input Parameters: + * elem - Index of TLS element to return + * + * Returned Value: + * The value of TLS element associated with 'elem'. Errors are not reported. + * Aero is returned in the event of an error, but zero may also be valid + * value and returned when there is no error. The only possible error would + * be if elem >=CONFIG_TLS_NELEM. + * + ****************************************************************************/ + +uintptr_t tls_get_element(int elem) +{ + FAR struct tls_info_s *info; + uintptr_t ret = 0; + + DEBUGASSERT(elem >= 0 && elem < CONFIG_TLS_NELEM); + if (elem >= 0 && elem < CONFIG_TLS_NELEM) + { + /* Get the TLS info structure from the current threads stack */ + + info = up_tls_info(); + DEBUGASSERT(info != NULL); + + /* Get the element value from the TLS info. */ + + ret = info->tl_elem[elem]; + } + + return ret; +} + +#endif /* CONFIG_TLS */ diff --git a/libc/tls/tls_setelem.c b/libc/tls/tls_setelem.c new file mode 100644 index 0000000000000000000000000000000000000000..14152590daa9efc12ea39b6ed78898cc5319a945 --- /dev/null +++ b/libc/tls/tls_setelem.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * libc/fixedmath/tls_setelem.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_TLS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_get_element + * + * Description: + * Set the TLS element associated with the 'elem' index to 'value' + * + * Input Parameters: + * elem - Index of TLS element to set + * value - The new value of the TLS element + * + * Returned Value: + * None. Errors are not reported. The only possible error would be if + * elem >=CONFIG_TLS_NELEM. + * + ****************************************************************************/ + +void tls_set_element(int elem, uintptr_t value) +{ + FAR struct tls_info_s *info; + + DEBUGASSERT(elem >= 0 && elem < CONFIG_TLS_NELEM); + if (elem >= 0 && elem < CONFIG_TLS_NELEM) + { + /* Get the TLS info structure from the current threads stack */ + + info = up_tls_info(); + DEBUGASSERT(info != NULL); + + /* Set the element value int the TLS info. */ + + info->tl_elem[elem] = value; + } +} + +#endif /* CONFIG_TLS */ diff --git a/libc/unistd/lib_access.c b/libc/unistd/lib_access.c index ce7e24c7ed8ed707f35a7d45e467d90b298a48d8..b9d22f9e83fecde22ebd9227bf0ae193477a5343 100644 --- a/libc/unistd/lib_access.c +++ b/libc/unistd/lib_access.c @@ -50,11 +50,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_chdir.c b/libc/unistd/lib_chdir.c index 8953fb19b67172a555733377d7c4a8f94e86b6e9..4780a6b72e927d41b2eb80a4b6d48353ca6d3803 100644 --- a/libc/unistd/lib_chdir.c +++ b/libc/unistd/lib_chdir.c @@ -45,12 +45,12 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON) /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -64,14 +64,14 @@ #if 0 static inline void _trimdir(char *path) { - /* Skip any trailing '/' characters (unless it is also the leading '/') */ + /* Skip any trailing '/' characters (unless it is also the leading '/') */ - int len = strlen(path) - 1; - while (len > 0 && path[len] == '/') - { + int len = strlen(path) - 1; + while (len > 0 && path[len] == '/') + { path[len] = '\0'; len--; - } + } } #else # define _trimdir(p) diff --git a/libc/unistd/lib_execl.c b/libc/unistd/lib_execl.c index 040941c170531a1f952743740953bc8f921d334b..08dbdc6112ea3536b53835d5312aec9778b16724 100644 --- a/libc/unistd/lib_execl.c +++ b/libc/unistd/lib_execl.c @@ -56,15 +56,15 @@ #define MAX_EXECL_ARGS 256 /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_getcwd.c b/libc/unistd/lib_getcwd.c index 694af4070d1cb78c8fbd744eeb3791db8526ceab..851d380fb6c864401df7f47fe140c38b9137b4eb 100644 --- a/libc/unistd/lib_getcwd.c +++ b/libc/unistd/lib_getcwd.c @@ -45,7 +45,7 @@ #include #include -#include "lib_internal.h" +#include "libc.h" #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON) @@ -54,7 +54,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_gethostname.c b/libc/unistd/lib_gethostname.c index ec12b5afe5a74feb164d00e05e44c6c53d8e1172..c21b9157b3f54ba4badf17873baa9339efb28b68 100644 --- a/libc/unistd/lib_gethostname.c +++ b/libc/unistd/lib_gethostname.c @@ -2,7 +2,7 @@ * libc/unistd/lib_gethostname.c * * Copyright (C) 2015 Stavros Polymenis. All rights reserved. - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. * Author: Stavros Polymenis * Gregory Nutt * @@ -45,7 +45,7 @@ #include #include -#include +#include /* This file is only compiled if network support is enabled */ @@ -119,9 +119,9 @@ int gethostname(FAR char *name, size_t namelen) * that it could change while we are copying it. */ - flags = irqsave(); + flags = enter_critical_section(); strncpy(name, g_hostname, namelen); - irqrestore(flags); + leave_critical_section(flags); return 0; diff --git a/libc/unistd/lib_getopt.c b/libc/unistd/lib_getopt.c index bda9666be557868f773fa7d24e5b420b55b5ef71..47ac0855095dbd4101c4beac802a29ab2c380f7a 100644 --- a/libc/unistd/lib_getopt.c +++ b/libc/unistd/lib_getopt.c @@ -48,7 +48,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ FAR char *optarg; /* Optional argument following option */ @@ -56,14 +56,14 @@ int optind = 1; /* Index into argv */ int optopt = '?'; /* unrecognized option character */ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ static FAR char *g_optptr = NULL; static bool g_binitialized = false; /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -187,82 +187,82 @@ int getopt(int argc, FAR char *const argv[], FAR const char *optstring) g_optptr++; } - /* Special case handling of "-" and "-:" */ + /* Special case handling of "-" and "-:" */ - if (!*g_optptr) - { - optopt = '\0'; /* We'll fix up g_optptr the next time we are called */ - return '?'; - } + if (!*g_optptr) + { + optopt = '\0'; /* We'll fix up g_optptr the next time we are called */ + return '?'; + } - /* Handle the case of "-:" */ + /* Handle the case of "-:" */ - if (*g_optptr == ':') - { - optopt = ':'; - g_optptr++; - return '?'; - } + if (*g_optptr == ':') + { + optopt = ':'; + g_optptr++; + return '?'; + } - /* g_optptr now points at the next option and it is not something crazy. - * check if the option is in the list of valid options. - */ + /* g_optptr now points at the next option and it is not something crazy. + * check if the option is in the list of valid options. + */ - optchar = strchr(optstring, *g_optptr); - if (!optchar) - { - /* No this character is not in the list of valid options */ + optchar = strchr(optstring, *g_optptr); + if (!optchar) + { + /* No this character is not in the list of valid options */ - optopt = *g_optptr; - g_optptr++; - return '?'; - } + optopt = *g_optptr; + g_optptr++; + return '?'; + } - /* Yes, the character is in the list of valid options. Does it have an - * required argument? - */ + /* Yes, the character is in the list of valid options. Does it have an + * required argument? + */ - if (optchar[1] != ':') - { - /* No, no arguments. Just return the character that we found */ + if (optchar[1] != ':') + { + /* No, no arguments. Just return the character that we found */ - g_optptr++; - return *optchar; - } + g_optptr++; + return *optchar; + } - /* Yes, it has a required argument. Is the required argument - * immediately after the command in this same argument? - */ + /* Yes, it has a required argument. Is the required argument + * immediately after the command in this same argument? + */ - if (g_optptr[1] != '\0') - { - /* Yes, return a pointer into the current argument */ + if (g_optptr[1] != '\0') + { + /* Yes, return a pointer into the current argument */ - optarg = &g_optptr[1]; - optind++; - g_optptr = NULL; - return *optchar; - } + optarg = &g_optptr[1]; + optind++; + g_optptr = NULL; + return *optchar; + } - /* No.. is the optional argument the next argument in argv[] ? */ + /* No.. is the optional argument the next argument in argv[] ? */ - if (argv[optind+1] && *argv[optind+1] != '-') - { - /* Yes.. return that */ + if (argv[optind+1] && *argv[optind+1] != '-') + { + /* Yes.. return that */ - optarg = argv[optind+1]; - optind += 2; - g_optptr = NULL; - return *optchar; - } + optarg = argv[optind+1]; + optind += 2; + g_optptr = NULL; + return *optchar; + } - /* No argument was supplied */ + /* No argument was supplied */ - g_optptr = NULL; - optarg = NULL; - optopt = *optchar; - optind++; - return noarg_ret; + g_optptr = NULL; + optarg = NULL; + optopt = *optchar; + optind++; + return noarg_ret; } /* Restore the initial, uninitialized state */ diff --git a/libc/unistd/lib_getoptargp.c b/libc/unistd/lib_getoptargp.c index 5cd1a55d3dff7e237c1f73471d794c312bcc6a6a..876b287929d74ca15e65845be4344925703ecd1c 100644 --- a/libc/unistd/lib_getoptargp.c +++ b/libc/unistd/lib_getoptargp.c @@ -46,15 +46,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_getoptindp.c b/libc/unistd/lib_getoptindp.c index 2563aa38481acf23689ba50cad00a5785a36e208..d4136423292ebbfa29f326213562d3bc89413fe1 100644 --- a/libc/unistd/lib_getoptindp.c +++ b/libc/unistd/lib_getoptindp.c @@ -46,15 +46,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_getoptoptp.c b/libc/unistd/lib_getoptoptp.c index 95e024a72689c6f542c028ca97982a7d0cb11d9b..b1aa2fc218c1ea4698dff3bc00bcf521aebac1e5 100644 --- a/libc/unistd/lib_getoptoptp.c +++ b/libc/unistd/lib_getoptoptp.c @@ -46,15 +46,15 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_sethostname.c b/libc/unistd/lib_sethostname.c index 2546e0fce97d46ed2cc6300425ece759c3b5c7b4..8d51c74971e8466cb40993cf28efa06d5f2667e1 100644 --- a/libc/unistd/lib_sethostname.c +++ b/libc/unistd/lib_sethostname.c @@ -2,7 +2,9 @@ * libc/unistd/lib_gethostname.c * * Copyright (C) 2015 Stavros Polymenis. All rights reserved. + * Copyright (C) 2015, 2016 Gregory Nutt. All rights reserved. * Author: Stavros Polymenis + * Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,7 +44,7 @@ #include #include -#include +#include /* This file is only compiled if network support is enabled */ @@ -118,10 +120,10 @@ int sethostname(FAR const char *name, size_t size) * are setting it. */ - flags = irqsave(); + flags = enter_critical_section(); strncpy(g_hostname, name, MIN(HOST_NAME_MAX, size)); g_hostname[HOST_NAME_MAX] = '\0'; - irqrestore(flags); + leave_critical_section(flags); return 0; } diff --git a/libc/unistd/lib_sleep.c b/libc/unistd/lib_sleep.c index 23b6cfb838fa7c8b4cc074163a72571433f95e79..785d76b63b52842dcf6e712fb4bbce7043cf5578 100644 --- a/libc/unistd/lib_sleep.c +++ b/libc/unistd/lib_sleep.c @@ -54,11 +54,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/unistd/lib_usleep.c b/libc/unistd/lib_usleep.c index c09de769d8e1219ab8d39bdf0541d213697db829..5b72bbdcdf7df6ec0dc5f7aeef824710695a23fd 100644 --- a/libc/unistd/lib_usleep.c +++ b/libc/unistd/lib_usleep.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -114,7 +114,7 @@ * * nanosleep(), setitimer(), timer_create(), timer_delete(), timer_getoverrun(), * timer_gettime(), timer_settime(), ualarm(), sleep() - + * * Parameters: * usec - the number of microseconds to wait. * diff --git a/libc/wqueue/work_cancel.c b/libc/wqueue/work_cancel.c index c7b1a8435bcaa612756ca1c1d45f0a79dee698b1..8fe330ef0a11d8d98f2c00b5ec9bdf09eaf1b7f0 100644 --- a/libc/wqueue/work_cancel.c +++ b/libc/wqueue/work_cancel.c @@ -59,11 +59,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -110,11 +110,13 @@ static int work_qcancel(FAR struct usr_wqueue_s *wqueue, FAR struct work_s *work { /* A little test of the integrity of the work queue */ - DEBUGASSERT(work->dq.flink || (FAR dq_entry_t *)work == wqueue->q.tail); - DEBUGASSERT(work->dq.blink || (FAR dq_entry_t *)work == wqueue->q.head); + DEBUGASSERT(work->dq.flink != NULL || + (FAR dq_entry_t *)work == wqueue->q.tail); + DEBUGASSERT(work->dq.blink != NULL || + (FAR dq_entry_t *)work == wqueue->q.head); /* Remove the entry from the work queue and make sure that it is - * mark as available (i.e., the worker field is nullified). + * marked as available (i.e., the worker field is nullified). */ dq_rem((FAR dq_entry_t *)work, &wqueue->q); diff --git a/libc/wqueue/work_lock.c b/libc/wqueue/work_lock.c index 6ae5d11e83983e2737de9d50daf97ef6c7955f2c..a8f1078707a1f77d080e82ca42507f7c0c24b955 100644 --- a/libc/wqueue/work_lock.c +++ b/libc/wqueue/work_lock.c @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/wqueue/work_queue.c b/libc/wqueue/work_queue.c index ffe98af8c78fc16292e3af8b46dd23c3f4123afa..ba9e13c97e531498c1205a1adffa7a69aed160fb 100644 --- a/libc/wqueue/work_queue.c +++ b/libc/wqueue/work_queue.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/wqueue/work_queue.c * - * Copyright (C) 2009-2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,22 +52,6 @@ #if defined(CONFIG_LIB_USRWORK) && !defined(__KERNEL__) -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -103,20 +87,20 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue, FAR struct work_s *work, worker_t worker, - FAR void *arg, uint32_t delay) + FAR void *arg, systime_t delay) { DEBUGASSERT(work != NULL); - /* First, initialize the work structure */ - - work->worker = worker; /* Work callback */ - work->arg = arg; /* Callback argument */ - work->delay = delay; /* Delay until work performed */ - /* Get exclusive access to the work queue */ while (work_lock() < 0); + /* Initialize the work structure */ + + work->worker = worker; /* Work callback. non-NULL means queued */ + work->arg = arg; /* Callback argument */ + work->delay = delay; /* Delay until work performed */ + /* Now, time-tag that entry and put it in the work queue. */ work->qtime = clock_systimer(); /* Time work queued */ @@ -162,7 +146,7 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue, ****************************************************************************/ int work_queue(int qid, FAR struct work_s *work, worker_t worker, - FAR void *arg, uint32_t delay) + FAR void *arg, systime_t delay) { if (qid == USRWORK) { diff --git a/libc/wqueue/work_signal.c b/libc/wqueue/work_signal.c index 7e0cfb1adea11f09c0043f66bc083860a5a30cf6..da8b174cd585724f93f10630f1134b2d12758041 100644 --- a/libc/wqueue/work_signal.c +++ b/libc/wqueue/work_signal.c @@ -57,11 +57,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/libc/wqueue/work_usrthread.c b/libc/wqueue/work_usrthread.c index 0179ed3c51a4a9172d52f5fbd55f2155c0776f13..f0815ac0c7ae5cc78c9413c59cc8f8c36acea3a4 100644 --- a/libc/wqueue/work_usrthread.c +++ b/libc/wqueue/work_usrthread.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/wqueue/work_usrthread.c * - * Copyright (C) 2009-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -122,11 +122,11 @@ void work_process(FAR struct usr_wqueue_s *wqueue) volatile FAR struct work_s *work; worker_t worker; FAR void *arg; - uint32_t elapsed; - uint32_t remaining; - uint32_t stick; - uint32_t ctick; - uint32_t next; + systime_t elapsed; + systime_t remaining; + systime_t stick; + systime_t ctick; + systime_t next; int ret; /* Then process queued work. Lock the work queue while we process items @@ -304,7 +304,7 @@ static pthread_addr_t work_usrthread(pthread_addr_t arg) { /* Loop forever */ - for (;;) + for (; ; ) { /* Then process queued work. We need to keep the work queue locked * while we process items in the work list. @@ -386,7 +386,7 @@ int work_usrstart(void) (void)pthread_attr_init(&attr); (void)pthread_attr_setstacksize(&attr, CONFIG_LIB_USRWORKSTACKSIZE); -+#ifdef CONFIG_SCHED_SPORADIC +#ifdef CONFIG_SCHED_SPORADIC /* Get the current sporadic scheduling parameters. Those will not be * modified. */ diff --git a/libnx/nxcontext.h b/libnx/nxcontext.h index 95fdf7a82e1375374fdb9c941195cf16fe8a2767..59bf928327fe0ac921c136fbb9f76b2a91be1a38 100644 --- a/libnx/nxcontext.h +++ b/libnx/nxcontext.h @@ -51,7 +51,7 @@ #include /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /* The NuttX NX library an be build in two modes: (1) as a standard, C-library @@ -105,7 +105,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN diff --git a/libnx/nxfonts/nxfonts_internal.h b/libnx/nxfonts/nxfonts.h similarity index 94% rename from libnx/nxfonts/nxfonts_internal.h rename to libnx/nxfonts/nxfonts.h index 7fccd5ab4e14b06a4a06ddd9785f04073f44b04d..1e3fa18bb3f89e36036ebf498dc33c4b49fda47f 100644 --- a/libnx/nxfonts/nxfonts_internal.h +++ b/libnx/nxfonts/nxfonts.h @@ -1,5 +1,5 @@ /**************************************************************************** - * libnx/nxfonts/nxfonts_internal.h + * libnx/nxfonts/nxfonts.h * * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __LIBNX_NXFONTS_NXFONTS_INTERNAL_H -#define __LIBNX_NXFONTS_NXFONTS_INTERNAL_H +#ifndef __LIBNX_NXFONTS_NXFONTS_H +#define __LIBNX_NXFONTS_NXFONTS_H /**************************************************************************** * Included Files @@ -85,4 +85,4 @@ EXTERN struct nx_font_s g_fonts; } #endif -#endif /* __LIBNX_NXFONTS_NXFONTS_INTERNAL_H */ +#endif /* __LIBNX_NXFONTS_NXFONTS_H */ diff --git a/libnx/nxfonts/nxfonts_bitmaps.c b/libnx/nxfonts/nxfonts_bitmaps.c index 0a71faacfed442fc247955ed999a73257cde5fb0..28e6aa18dcc3395c04da52118a1d9bf8b0e91e09 100644 --- a/libnx/nxfonts/nxfonts_bitmaps.c +++ b/libnx/nxfonts/nxfonts_bitmaps.c @@ -42,7 +42,7 @@ #include #include -#include "nxfonts_internal.h" +#include "nxfonts.h" /* Pick the fontset */ diff --git a/libnx/nxfonts/nxfonts_convert.c b/libnx/nxfonts/nxfonts_convert.c index a223c7f0a99f1f4d27e60396678447367685ca01..6d3b5a71e2cb1e9eb46e97795c90c313eb4465de 100644 --- a/libnx/nxfonts/nxfonts_convert.c +++ b/libnx/nxfonts/nxfonts_convert.c @@ -46,7 +46,7 @@ #include #include -#include "nxfonts_internal.h" +#include "nxfonts.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxfonts/nxfonts_getfont.c b/libnx/nxfonts/nxfonts_getfont.c index fe443138df142779a2027038dbaca60f7c2e06e9..c52c082281c2c07c090a6d80b33b1092d6f610ec 100644 --- a/libnx/nxfonts/nxfonts_getfont.c +++ b/libnx/nxfonts/nxfonts_getfont.c @@ -46,7 +46,7 @@ #include #include -#include "nxfonts_internal.h" +#include "nxfonts.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxglib/nxglib_rgbblend.c b/libnx/nxglib/nxglib_rgbblend.c index 41b8cc94300c1800d9ac4c0febfc87c31a788351..96b1fd70036f23e3d443dc8b2fa817be80ddf57f 100644 --- a/libnx/nxglib/nxglib_rgbblend.c +++ b/libnx/nxglib/nxglib_rgbblend.c @@ -1,233 +1,233 @@ -/**************************************************************************** - * libnx/nxglib/nxglib_runcopy.c - * - * Copyright (C) 2008-2011, 2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxglib_rgb24_blend and nxglib_rgb565_blend - * - * Description: - * Blend a single RGB color component. This is *not* alpha blending: - * component2 is assumed to be opaque and "under" a semi-transparent - * component1. - * - * The frac1 value could be though as related to the 1/alpha value for - * component1. However, the background, component2, is always treated as though - * alpha == 1. - * - * This algorithm is used to handle endpoints as part of the - * implementation of anti-aliasing without transparency. - * - * Input Parameters: - * component1 - The semi-transparent, forground 8-bit color component - * component2 - The opaque, background color component - * frac1 - The fractional amount of component1 to blend into component2 - * - * Returned Value: - * The blended 8-bit color component. - * - ****************************************************************************/ - -#if !defined(CONFIG_NX_DISABLE_16BPP) || !defined(CONFIG_NX_DISABLE_24BPP) || \ - !defined(CONFIG_NX_DISABLE_32BPP) - -static uint8_t nxglib_blend_component(uint8_t component1, uint8_t component2, - ub8_t frac1) -{ - uint16_t blend; - uint32_t blendb8; - - /* Use a uint32_t for the intermediate calculation. Due to rounding this - * value could exceed ub8MAX (0xffff == 255.999..). - * - * Hmm.. that might not actually be possible but this gives me piece of - * mind and there should not be any particular overhead on a 32-bit - * processor. - */ - - blendb8 = (uint32_t)((ub16_t)component1 * frac1) + - (uint32_t)((ub16_t)component2 * (b8ONE - frac1)) + - (uint32_t)b8HALF; - - /* Now we can snap it down to 16-bits and check for the overflow condition. */ - - blend = ub8toi(blendb8); - if (blend > 255) - { - blend = 255; - } - - /* Return the blended value */ - - return (uint8_t)blend; -} - -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxglib_rgb24_blend and nxglib_rgb565_blend - * - * Description: - * Blend a foreground color onto a background color. This is *not* alpha - * blending: color2 is assumed to be opaque and "under" a semi- - * transparent color1. - * - * The frac1 value could be though as related to the 1/alpha value for - * color1. However, the background, color2, is always treated as though - * alpha == 1. - * - * This algorithm is used to handle endpoints as part of the - * implementation of anti-aliasing without transparency. - * - * Input Parameters: - * color1 - The semi-transparent, forground color - * color2 - The opaque, background color - * frac1 - The fractional amount of color1 to blend into color2 - * - * Returned Value: - * The blended color, encoded just was the input color1 and color2 - * - ****************************************************************************/ - -#if !defined(CONFIG_NX_DISABLE_24BPP) || !defined(CONFIG_NX_DISABLE_32BPP) - -uint32_t nxglib_rgb24_blend(uint32_t color1, uint32_t color2, ub16_t frac1) -{ - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t bg; - ub8_t fracb8; - - /* Convert the fraction to ub8_t. We don't need that much precision to - * scale an 8-bit color component. - */ - - fracb8 = ub16toub8(frac1); - - /* Some limit checks. Rounding in the b16 to b8 conversion could cause - * the fraction exceed one; the loss of precision could cause small b16 - * values to convert to zero. - */ - - if (fracb8 >= b8ONE) - { - return color1; - } - else if (fracb8 == 0) - { - return color2; - } - - /* Separate and blend each component */ - - r = RGB24RED(color1); - bg = RGB24RED(color2); - r = nxglib_blend_component(r, bg, fracb8); - - g = RGB24GREEN(color1); - bg = RGB24GREEN(color2); - g = nxglib_blend_component(g, bg, fracb8); - - b = RGB24BLUE(color1); - bg = RGB24BLUE(color2); - b = nxglib_blend_component(b, bg, fracb8); - - /* Recombine and return the blended value */ - - return RGBTO24(r,g,b) ; -} - -#endif - -#ifndef CONFIG_NX_DISABLE_16BPP - -uint16_t nxglib_rgb565_blend(uint16_t color1, uint16_t color2, ub16_t frac1) -{ - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t bg; - ub8_t fracb8; - - /* Convert the fraction to ub8_t. We don't need that much precision. */ - - fracb8 = ub16toub8(frac1); - - /* Some limit checks */ - - if (fracb8 >= b8ONE) - { - return color1; - } - else if (fracb8 == 0) - { - return color2; - } - - /* Separate and blend each component */ - - r = RGB16RED(color1); - bg = RGB16RED(color2); - r = nxglib_blend_component(r, bg, fracb8); - - g = RGB16GREEN(color1); - bg = RGB16GREEN(color2); - g = nxglib_blend_component(g, bg, fracb8); - - b = RGB16BLUE(color1); - bg = RGB16BLUE(color2); - b = nxglib_blend_component(b, bg, fracb8); - - /* Recombine and return the blended value */ - - return RGBTO24(r,g,b) ; -} - -#endif +/**************************************************************************** + * libnx/nxglib/nxglib_runcopy.c + * + * Copyright (C) 2008-2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxglib_rgb24_blend and nxglib_rgb565_blend + * + * Description: + * Blend a single RGB color component. This is *not* alpha blending: + * component2 is assumed to be opaque and "under" a semi-transparent + * component1. + * + * The frac1 value could be though as related to the 1/alpha value for + * component1. However, the background, component2, is always treated as though + * alpha == 1. + * + * This algorithm is used to handle endpoints as part of the + * implementation of anti-aliasing without transparency. + * + * Input Parameters: + * component1 - The semi-transparent, forground 8-bit color component + * component2 - The opaque, background color component + * frac1 - The fractional amount of component1 to blend into component2 + * + * Returned Value: + * The blended 8-bit color component. + * + ****************************************************************************/ + +#if !defined(CONFIG_NX_DISABLE_16BPP) || !defined(CONFIG_NX_DISABLE_24BPP) || \ + !defined(CONFIG_NX_DISABLE_32BPP) + +static uint8_t nxglib_blend_component(uint8_t component1, uint8_t component2, + ub8_t frac1) +{ + uint16_t blend; + uint32_t blendb8; + + /* Use a uint32_t for the intermediate calculation. Due to rounding this + * value could exceed ub8MAX (0xffff == 255.999..). + * + * Hmm.. that might not actually be possible but this gives me piece of + * mind and there should not be any particular overhead on a 32-bit + * processor. + */ + + blendb8 = (uint32_t)((ub16_t)component1 * frac1) + + (uint32_t)((ub16_t)component2 * (b8ONE - frac1)) + + (uint32_t)b8HALF; + + /* Now we can snap it down to 16-bits and check for the overflow condition. */ + + blend = ub8toi(blendb8); + if (blend > 255) + { + blend = 255; + } + + /* Return the blended value */ + + return (uint8_t)blend; +} + +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxglib_rgb24_blend and nxglib_rgb565_blend + * + * Description: + * Blend a foreground color onto a background color. This is *not* alpha + * blending: color2 is assumed to be opaque and "under" a semi- + * transparent color1. + * + * The frac1 value could be though as related to the 1/alpha value for + * color1. However, the background, color2, is always treated as though + * alpha == 1. + * + * This algorithm is used to handle endpoints as part of the + * implementation of anti-aliasing without transparency. + * + * Input Parameters: + * color1 - The semi-transparent, forground color + * color2 - The opaque, background color + * frac1 - The fractional amount of color1 to blend into color2 + * + * Returned Value: + * The blended color, encoded just was the input color1 and color2 + * + ****************************************************************************/ + +#if !defined(CONFIG_NX_DISABLE_24BPP) || !defined(CONFIG_NX_DISABLE_32BPP) + +uint32_t nxglib_rgb24_blend(uint32_t color1, uint32_t color2, ub16_t frac1) +{ + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t bg; + ub8_t fracb8; + + /* Convert the fraction to ub8_t. We don't need that much precision to + * scale an 8-bit color component. + */ + + fracb8 = ub16toub8(frac1); + + /* Some limit checks. Rounding in the b16 to b8 conversion could cause + * the fraction exceed one; the loss of precision could cause small b16 + * values to convert to zero. + */ + + if (fracb8 >= b8ONE) + { + return color1; + } + else if (fracb8 == 0) + { + return color2; + } + + /* Separate and blend each component */ + + r = RGB24RED(color1); + bg = RGB24RED(color2); + r = nxglib_blend_component(r, bg, fracb8); + + g = RGB24GREEN(color1); + bg = RGB24GREEN(color2); + g = nxglib_blend_component(g, bg, fracb8); + + b = RGB24BLUE(color1); + bg = RGB24BLUE(color2); + b = nxglib_blend_component(b, bg, fracb8); + + /* Recombine and return the blended value */ + + return RGBTO24(r,g,b); +} + +#endif + +#ifndef CONFIG_NX_DISABLE_16BPP + +uint16_t nxglib_rgb565_blend(uint16_t color1, uint16_t color2, ub16_t frac1) +{ + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t bg; + ub8_t fracb8; + + /* Convert the fraction to ub8_t. We don't need that much precision. */ + + fracb8 = ub16toub8(frac1); + + /* Some limit checks */ + + if (fracb8 >= b8ONE) + { + return color1; + } + else if (fracb8 == 0) + { + return color2; + } + + /* Separate and blend each component */ + + r = RGB16RED(color1); + bg = RGB16RED(color2); + r = nxglib_blend_component(r, bg, fracb8); + + g = RGB16GREEN(color1); + bg = RGB16GREEN(color2); + g = nxglib_blend_component(g, bg, fracb8); + + b = RGB16BLUE(color1); + bg = RGB16BLUE(color2); + b = nxglib_blend_component(b, bg, fracb8); + + /* Recombine and return the blended value */ + + return RGBTO24(r,g,b); +} + +#endif diff --git a/libnx/nxtk/nxtk_internal.h b/libnx/nxtk/nxtk.h similarity index 98% rename from libnx/nxtk/nxtk_internal.h rename to libnx/nxtk/nxtk.h index 7a62293413bdf23dafb88c01444fbe6cc6e75e3b..44d507ee015e2c6bcafb1db887f4971a7488035b 100644 --- a/libnx/nxtk/nxtk_internal.h +++ b/libnx/nxtk/nxtk.h @@ -1,5 +1,5 @@ /**************************************************************************** - * libnx/nxtk/nxtk_internal.h + * libnx/nxtk/nxtk.h * * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __LIBNX_NXTK_NXTK_INTERNAL_H -#define __LIBNX_NXTK_NXTK_INTERNAL_H +#ifndef __LIBNX_NXTK_NXTK_H +#define __LIBNX_NXTK_NXTK_H /**************************************************************************** * Included Files @@ -222,4 +222,4 @@ int nxtk_drawframe(FAR struct nxtk_framedwindow_s *fwnd, } #endif -#endif /* __LIBNX_NXTK_NXTK_INTERNAL_H */ +#endif /* __LIBNX_NXTK_NXTK_H */ diff --git a/libnx/nxtk/nxtk_bitmaptoolbar.c b/libnx/nxtk/nxtk_bitmaptoolbar.c index abeb14d184f7fb7dbba6cad1be7283884251fdda..abc1815b8f70d0de1ebb47589aa1d40c8a93f72c 100644 --- a/libnx/nxtk/nxtk_bitmaptoolbar.c +++ b/libnx/nxtk/nxtk_bitmaptoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_bitmapwindow.c b/libnx/nxtk/nxtk_bitmapwindow.c index da814fe10ae394784a15748e39a3519d1c2eba9e..59a8776b626e7ee07b3f67a52054e304296dbcd5 100644 --- a/libnx/nxtk/nxtk_bitmapwindow.c +++ b/libnx/nxtk/nxtk_bitmapwindow.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_closetoolbar.c b/libnx/nxtk/nxtk_closetoolbar.c index 8f65a75a8412e0f6c380f9f511189806b198102f..7be217d18de8a2e192c46e253eb03226adab4f10 100644 --- a/libnx/nxtk/nxtk_closetoolbar.c +++ b/libnx/nxtk/nxtk_closetoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_closewindow.c b/libnx/nxtk/nxtk_closewindow.c index 7bda3ff06b825fe00894d5f319f6062cde0afc59..54857521305de246af323063ee5aa35f2e43be9e 100644 --- a/libnx/nxtk/nxtk_closewindow.c +++ b/libnx/nxtk/nxtk_closewindow.c @@ -47,7 +47,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_containerclip.c b/libnx/nxtk/nxtk_containerclip.c index 12dc4987b3f1234bff2e52ceab579c45c9e4281c..67ed6cb17b18ae198e6f1b2ab7d41a1e1ec0967c 100644 --- a/libnx/nxtk/nxtk_containerclip.c +++ b/libnx/nxtk/nxtk_containerclip.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_drawframe.c b/libnx/nxtk/nxtk_drawframe.c index ae0be64425f3e17535b00323a0263d1edee61111..adafccc574468d0282dd2d4a0ea7b7dfbc5a041b 100644 --- a/libnx/nxtk/nxtk_drawframe.c +++ b/libnx/nxtk/nxtk_drawframe.c @@ -47,7 +47,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_drawlinewindow.c b/libnx/nxtk/nxtk_drawlinewindow.c index 4c4dd49d078c0fbb95bed26e59c9b64a272da03f..a616ce13205741b0118c5332802443f18652ed4a 100644 --- a/libnx/nxtk/nxtk_drawlinewindow.c +++ b/libnx/nxtk/nxtk_drawlinewindow.c @@ -94,7 +94,7 @@ int nxtk_drawlinewindow(NXTKWINDOW hfwnd, FAR struct nxgl_vector_s *vector, nxgl_coord_t width, nxgl_mxpixel_t color[CONFIG_NX_NPLANES], - bool caps) + uint8_t caps) { struct nxgl_trapezoid_s trap[3]; diff --git a/libnx/nxtk/nxtk_events.c b/libnx/nxtk/nxtk_events.c index d22d04aa859fce5ace9a4dafea8cd930ff4ab70d..d7f33e6ebedd0259410da459feae54e9f8586684 100644 --- a/libnx/nxtk/nxtk_events.c +++ b/libnx/nxtk/nxtk_events.c @@ -48,10 +48,10 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** diff --git a/libnx/nxtk/nxtk_filltoolbar.c b/libnx/nxtk/nxtk_filltoolbar.c index 13de3724982bb484c2cc885bf4f42e1bfbf03b69..0d62eaaf84e2f52bc7af2cdaa06fd50cfef2bbee 100644 --- a/libnx/nxtk/nxtk_filltoolbar.c +++ b/libnx/nxtk/nxtk_filltoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_filltraptoolbar.c b/libnx/nxtk/nxtk_filltraptoolbar.c index a55d05e7e97f5ff78f5a71495e30ef2f0a4e50a1..1b7ae272770a6de462c3140bd198644baf983431 100644 --- a/libnx/nxtk/nxtk_filltraptoolbar.c +++ b/libnx/nxtk/nxtk_filltraptoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_filltrapwindow.c b/libnx/nxtk/nxtk_filltrapwindow.c index 66aef4184f1eba407177ceb7ce4e7ed58a0afd6e..bbfba26599e69acd5c56c663bd078dc9a0987366 100644 --- a/libnx/nxtk/nxtk_filltrapwindow.c +++ b/libnx/nxtk/nxtk_filltrapwindow.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_fillwindow.c b/libnx/nxtk/nxtk_fillwindow.c index 77f043391c8387708f12499189740737ade51529..fa0fd8d8f2408c533ab022c08e1c7d2ef36e277b 100644 --- a/libnx/nxtk/nxtk_fillwindow.c +++ b/libnx/nxtk/nxtk_fillwindow.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_getposition.c b/libnx/nxtk/nxtk_getposition.c index a0b21bedba613f7cd4eb348891178dfc2e6ab119..1f0bdceeef7d08b3bb2fce23d19aa9e865ab545c 100644 --- a/libnx/nxtk/nxtk_getposition.c +++ b/libnx/nxtk/nxtk_getposition.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_gettoolbar.c b/libnx/nxtk/nxtk_gettoolbar.c index a83a1aa3e621c404c06ea5fb1d076005cb8c524b..593fcb09a639525f803d5d399edcaf48da82e1e2 100644 --- a/libnx/nxtk/nxtk_gettoolbar.c +++ b/libnx/nxtk/nxtk_gettoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_getwindow.c b/libnx/nxtk/nxtk_getwindow.c index a91ad05fc6b0b5c712db16b7570dbfafd6bd3038..b22945997378144b7825fee5b592deb7c61945e1 100644 --- a/libnx/nxtk/nxtk_getwindow.c +++ b/libnx/nxtk/nxtk_getwindow.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_lower.c b/libnx/nxtk/nxtk_lower.c index de26ac509b6a27d54e0398c586b852b4b79fedff..08a588897d9833fa62ad5583772b93bc02e60a23 100644 --- a/libnx/nxtk/nxtk_lower.c +++ b/libnx/nxtk/nxtk_lower.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_movetoolbar.c b/libnx/nxtk/nxtk_movetoolbar.c index 275bb46e660db3f5f466644709f12e688bf2efe9..62d14e7bf85fa8ab02c41cfcee411b10f36862b5 100644 --- a/libnx/nxtk/nxtk_movetoolbar.c +++ b/libnx/nxtk/nxtk_movetoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_movewindow.c b/libnx/nxtk/nxtk_movewindow.c index 66aed9d16a76e74472c38e8e6b9dc2d2aa2b3613..2b34f44a8b655bf9040a167dca201d45e96e92f2 100644 --- a/libnx/nxtk/nxtk_movewindow.c +++ b/libnx/nxtk/nxtk_movewindow.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_opentoolbar.c b/libnx/nxtk/nxtk_opentoolbar.c index ffdf629013f25ee0ba544414c01b49d8c8d9c19d..26aa4c504f745781b041c6b7a2385a3807923fa5 100644 --- a/libnx/nxtk/nxtk_opentoolbar.c +++ b/libnx/nxtk/nxtk_opentoolbar.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_openwindow.c b/libnx/nxtk/nxtk_openwindow.c index c7c050b8dada960969729bc214c2c39d942d7d69..796a57d3b7048e3a0a4ecddca6eebe4dba5e7232 100644 --- a/libnx/nxtk/nxtk_openwindow.c +++ b/libnx/nxtk/nxtk_openwindow.c @@ -46,7 +46,7 @@ #include #include "nxcontext.h" -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_raise.c b/libnx/nxtk/nxtk_raise.c index 2b54f81cb6f5f310bf8538c6dd78bbf5abcf862f..d0273fe704845cb1e9951040a9f43abde41b3455 100644 --- a/libnx/nxtk/nxtk_raise.c +++ b/libnx/nxtk/nxtk_raise.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_setposition.c b/libnx/nxtk/nxtk_setposition.c index f3ba11872698a9670953da7bf75df598fcbd8989..ed856252720a4484fc19f35e34a266b988c6c23b 100644 --- a/libnx/nxtk/nxtk_setposition.c +++ b/libnx/nxtk/nxtk_setposition.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_setsize.c b/libnx/nxtk/nxtk_setsize.c index 671aa8054062cdc8a5881b1a208a8ab0d7600b7e..8848c717200c60c1e3cc99bbfdd1444785c2e6ce 100644 --- a/libnx/nxtk/nxtk_setsize.c +++ b/libnx/nxtk/nxtk_setsize.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_setsubwindows.c b/libnx/nxtk/nxtk_setsubwindows.c index e528f43e9a8e4feb9559271b098eb628afafe0bf..943825a8b01c43c5f97d9168aef299f282bb01ed 100644 --- a/libnx/nxtk/nxtk_setsubwindows.c +++ b/libnx/nxtk/nxtk_setsubwindows.c @@ -45,10 +45,10 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** diff --git a/libnx/nxtk/nxtk_subwindowclip.c b/libnx/nxtk/nxtk_subwindowclip.c index b2688a543d29470c7c574189838e6e6088ce29bc..b1b4024ee7e813ccb3155da86a9e9727bcf33c0d 100644 --- a/libnx/nxtk/nxtk_subwindowclip.c +++ b/libnx/nxtk/nxtk_subwindowclip.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_subwindowmove.c b/libnx/nxtk/nxtk_subwindowmove.c index 6ae737b58045672406223a46ac8193f7b131a749..6b80609d3da5bef106e858f4b95c5c6ddbb642fc 100644 --- a/libnx/nxtk/nxtk_subwindowmove.c +++ b/libnx/nxtk/nxtk_subwindowmove.c @@ -46,7 +46,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libnx/nxtk/nxtk_toolbarbounds.c b/libnx/nxtk/nxtk_toolbarbounds.c index 6303b4d20de15bd75b72d90a7f08a4c8af7a070b..eacaf9057311c1c280e763302334e15d32b3f86b 100644 --- a/libnx/nxtk/nxtk_toolbarbounds.c +++ b/libnx/nxtk/nxtk_toolbarbounds.c @@ -45,7 +45,7 @@ #include #include -#include "nxtk_internal.h" +#include "nxtk.h" /**************************************************************************** * Pre-Processor Definitions diff --git a/libxx/Makefile b/libxx/Makefile index 5c5be9c41cd94b17438d85a90328f0a3a7425339..2fee701186508fa60e2b9d55361bc2c13e5621f8 100644 --- a/libxx/Makefile +++ b/libxx/Makefile @@ -50,7 +50,7 @@ endif ifneq ($(CONFIG_UCLIBCXX),y) CXXSRCS += libxx_delete.cxx libxx_deletea.cxx libxx_new.cxx libxx_newa.cxx -CXXSRCS += libxx_stdthrow.cxx +CXXSRCS += libxx_stdthrow.cxx libxx_cxa_guard.cxx else ifneq ($(UCLIBCXX_EXCEPTION),y) CXXSRCS += libxx_stdthrow.cxx diff --git a/libxx/libxx_internal.hxx b/libxx/libxx.hxx similarity index 96% rename from libxx/libxx_internal.hxx rename to libxx/libxx.hxx index 6669e90052d78ea79980f2c0e275d539e7cbab2d..be740aaf873e92f30bc28084ec8e7129c61ef0fb 100644 --- a/libxx/libxx_internal.hxx +++ b/libxx/libxx.hxx @@ -1,5 +1,5 @@ //*************************************************************************** -// lib/libxx_internal.h +// lib/libxx.hxx // // Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. // Author: Gregory Nutt @@ -33,8 +33,8 @@ // //*************************************************************************** -#ifndef __LIBXX_LIBXX_INTERNAL_HXX -#define __LIBXX_LIBXX_INTERNAL_HXX +#ifndef __LIBXX_LIBXX_HXX +#define __LIBXX_LIBXX__HXX //*************************************************************************** // Included Files @@ -74,7 +74,7 @@ typedef CODE void (*__cxa_exitfunc_t)(void *arg); //*************************************************************************** -// Public Variables +// Public Data //*************************************************************************** extern "C" FAR void *__dso_handle; @@ -85,4 +85,4 @@ extern "C" FAR void *__dso_handle; extern "C" int __cxa_atexit(__cxa_exitfunc_t func, void *arg, void *dso_handle); -#endif // __LIBXX_LIBXX_INTERNAL_HXX +#endif // __LIBXX_LIBXX_HXX diff --git a/libxx/libxx__gnu_unwind_find_exidx.hxx b/libxx/libxx__gnu_unwind_find_exidx.hxx index 0925d76e90e924b547ce308f3a695008611728ef..9156874a6ce2d097d2c39a8884bbac5f22c55554 100644 --- a/libxx/libxx__gnu_unwind_find_exidx.hxx +++ b/libxx/libxx__gnu_unwind_find_exidx.hxx @@ -60,7 +60,7 @@ typedef struct __EIT_entry } __EIT_entry; //*************************************************************************** -// Public Variables +// Public Data //*************************************************************************** extern __EIT_entry __exidx_start; diff --git a/libxx/libxx_cxa_atexit.cxx b/libxx/libxx_cxa_atexit.cxx index d7a82fe5b733edcd484dc2b23824297c57666e33..cb60e1c7e2dd6277eedbf73e0c4905a6d7c8ed08 100644 --- a/libxx/libxx_cxa_atexit.cxx +++ b/libxx/libxx_cxa_atexit.cxx @@ -41,7 +41,7 @@ #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions @@ -83,7 +83,7 @@ extern "C" // //************************************************************************* -#if CONFIG_SCHED_ONEXIT +#ifdef CONFIG_SCHED_ONEXIT static void __cxa_callback(int exitcode, FAR void *arg) { FAR struct __cxa_atexit_s *alloc = (FAR struct __cxa_atexit_s *)arg; @@ -118,7 +118,7 @@ extern "C" int __cxa_atexit(__cxa_exitfunc_t func, FAR void *arg, FAR void *dso_handle) { -#if CONFIG_SCHED_ONEXIT +#ifdef CONFIG_SCHED_ONEXIT // Allocate memory to hold the marshaled __cxa_exitfunc_t call // information. diff --git a/libxx/libxx_cxa_guard.cxx b/libxx/libxx_cxa_guard.cxx new file mode 100644 index 0000000000000000000000000000000000000000..47e9c4ea8db34039bf435f2d5f9f47e1e46fe271 --- /dev/null +++ b/libxx/libxx_cxa_guard.cxx @@ -0,0 +1,87 @@ +//*************************************************************************** +// libxx/libxx_cxa_guard.cxx +// +// Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. +// Author: Paul Alexander Patience +// +// 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. +// +//*************************************************************************** + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include + +//*************************************************************************** +// Pre-processor Definitions +//*************************************************************************** + +//*************************************************************************** +// Private Types +//*************************************************************************** + +__extension__ typedef int __guard __attribute__((mode(__DI__))); + +//*************************************************************************** +// Private Data +//*************************************************************************** + +//*************************************************************************** +// Public Functions +//*************************************************************************** + +extern "C" +{ + //************************************************************************* + // Name: __cxa_guard_acquire + //************************************************************************* + + int __cxa_guard_acquire(FAR __guard *g) + { + return !*g; + } + + //************************************************************************* + // Name: __cxa_guard_release + //************************************************************************* + + void __cxa_guard_release(FAR __guard *g) + { + *g = 1; + } + + //************************************************************************* + // Name: __cxa_guard_abort + //************************************************************************* + + void __cxa_guard_abort(FAR __guard *) + { + } +} diff --git a/libxx/libxx_delete.cxx b/libxx/libxx_delete.cxx index 9eb46a0100f1b6f22ac2f1a219390c135d21081c..dec28a85c24f9372bf00df89cfc73422446ce33c 100644 --- a/libxx/libxx_delete.cxx +++ b/libxx/libxx_delete.cxx @@ -39,7 +39,7 @@ #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions diff --git a/libxx/libxx_deletea.cxx b/libxx/libxx_deletea.cxx index c99c18dfde21c6b2d23c4af68a3f1507eebed4b5..174049efc2f07f61f9858f2183a0443451af5532 100644 --- a/libxx/libxx_deletea.cxx +++ b/libxx/libxx_deletea.cxx @@ -39,7 +39,7 @@ #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions diff --git a/libxx/libxx_eabi_atexit.cxx b/libxx/libxx_eabi_atexit.cxx index 25f8306a847e7ce33e839af09c8a706a7dcf62f0..eea296c696d95c9d13f81756cd9002ddea526f8e 100644 --- a/libxx/libxx_eabi_atexit.cxx +++ b/libxx/libxx_eabi_atexit.cxx @@ -40,7 +40,7 @@ #include #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions diff --git a/libxx/libxx_new.cxx b/libxx/libxx_new.cxx index 710528abe3524bb9b7c71619dd1c32470abae478..a4575519ab414111c8f113f0095a3715fa1d64bf 100644 --- a/libxx/libxx_new.cxx +++ b/libxx/libxx_new.cxx @@ -41,7 +41,7 @@ #include #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions diff --git a/libxx/libxx_newa.cxx b/libxx/libxx_newa.cxx index 8d42c628c79021e228bf7c637399abc7e87759bd..c1e4dfa95d9a2fff445544eeee189fdc739a9e7a 100644 --- a/libxx/libxx_newa.cxx +++ b/libxx/libxx_newa.cxx @@ -41,7 +41,7 @@ #include #include -#include "libxx_internal.hxx" +#include "libxx.hxx" //*************************************************************************** // Pre-processor Definitions diff --git a/mm/README.txt b/mm/README.txt index 0e9a4e7d228f78e12e4a7a8efb11e683a300676a..f33cf49c80ec1cc064c532a22aadb27d10182a59 100644 --- a/mm/README.txt +++ b/mm/README.txt @@ -15,7 +15,7 @@ This directory contains the NuttX memory management logic. This include: mm_memalign.c, mm_free.c o Less-Standard Interfaces: mm_zalloc.c, mm_mallinfo.c o Internal Implementation: mm_initialize.c mm_sem.c mm_addfreechunk.c - mm_size2ndx.c mm_shrinkchunk.c, mm_internal.h + mm_size2ndx.c mm_shrinkchunk.c o Build and Configuration files: Kconfig, Makefile Memory Models: diff --git a/mm/kmm_heap/kmm_addregion.c b/mm/kmm_heap/kmm_addregion.c index cccb202699e4c775ee8a3af1547617076be74bcf..41884fa7c35f98b1d13309031c2775c550438c8c 100644 --- a/mm/kmm_heap/kmm_addregion.c +++ b/mm/kmm_heap/kmm_addregion.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/kmm_heap/kmm_addregion.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,27 +43,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/************************************************************************ - * Pre-processor definition - ************************************************************************/ - -/************************************************************************ - * Private Types - ************************************************************************/ - -/************************************************************************ - * Public Data - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_addregion * * Description: @@ -76,7 +60,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void kmm_addregion(FAR void *heap_start, size_t heap_size) { diff --git a/mm/kmm_heap/kmm_brkaddr.c b/mm/kmm_heap/kmm_brkaddr.c index a04032e83208675317a341ed523f2b3ebb3d6141..4329a0cf875990e7ae972f062ac33ab7e1dc2107 100644 --- a/mm/kmm_heap/kmm_brkaddr.c +++ b/mm/kmm_heap/kmm_brkaddr.c @@ -45,10 +45,6 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_calloc.c b/mm/kmm_heap/kmm_calloc.c index 2da8e815c885a2291ebd72af593b530082b0fa40..4c3f1bc8e21ed760fd192f2d215e86ed2698e007 100644 --- a/mm/kmm_heap/kmm_calloc.c +++ b/mm/kmm_heap/kmm_calloc.c @@ -43,10 +43,6 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_extend.c b/mm/kmm_heap/kmm_extend.c index 0a05ccd8d60b2f4e40e003fe42942c50a56a7607..256c84d24d98af0ab919f5e83f36ab6d18c58db4 100644 --- a/mm/kmm_heap/kmm_extend.c +++ b/mm/kmm_heap/kmm_extend.c @@ -43,10 +43,6 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_free.c b/mm/kmm_heap/kmm_free.c index 1b300158b39397d928dd490cd9f3d951aabbd319..c9016788188a24bc775222abd836726bb7c90b34 100644 --- a/mm/kmm_heap/kmm_free.c +++ b/mm/kmm_heap/kmm_free.c @@ -46,19 +46,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_free * * Description: @@ -71,7 +63,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void kmm_free(FAR void *mem) { diff --git a/mm/kmm_heap/kmm_heapmember.c b/mm/kmm_heap/kmm_heapmember.c index d872288721f9ad282624c99afc8d0e73815b90d1..b96a6f7ada7691fe8c93de40a0f5268527f93a98 100644 --- a/mm/kmm_heap/kmm_heapmember.c +++ b/mm/kmm_heap/kmm_heapmember.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/kmm_heap/kmm_heapmember.c * * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,27 +45,11 @@ #if defined(CONFIG_MM_KERNEL_HEAP) && defined(CONFIG_DEBUG) -/************************************************************************ - * Pre-processor definition - ************************************************************************/ - -/************************************************************************ - * Private Types - ************************************************************************/ - -/************************************************************************ - * Public Data - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_heapmember * * Description: @@ -79,7 +63,7 @@ * not. If the address is not a member of the kernel heap, then it * must be a member of the user-space heap (unchecked) * - ************************************************************************/ + ****************************************************************************/ bool kmm_heapmember(FAR void *mem) { diff --git a/mm/kmm_heap/kmm_initialize.c b/mm/kmm_heap/kmm_initialize.c index ed4cbc926a87b82c868fb071f0b770d70ba2b1ab..03baba81203434cd5da82417ae3135bb2659af34 100644 --- a/mm/kmm_heap/kmm_initialize.c +++ b/mm/kmm_heap/kmm_initialize.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/kmm_heap/kmm_initialize.c * * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,31 +43,19 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/************************************************************************ - * Pre-processor definition - ************************************************************************/ - -/************************************************************************ - * Private Types - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Data - ************************************************************************/ + ****************************************************************************/ /* This is the kernel heap */ struct mm_heap_s g_kmmheap; -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_initialize * * Description: @@ -81,7 +69,7 @@ struct mm_heap_s g_kmmheap; * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void kmm_initialize(FAR void *heap_start, size_t heap_size) { diff --git a/mm/kmm_heap/kmm_kernel.c b/mm/kmm_heap/kmm_kernel.c index 4ab8e1b2bc1cf5e9642aaaa51ceb52af178a6e99..4a2231dd01fda3a1f8cf355f1c94421c405c9258 100644 --- a/mm/kmm_heap/kmm_kernel.c +++ b/mm/kmm_heap/kmm_kernel.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/kmm_heap/kmm_kernel.c * * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,27 +46,11 @@ #if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \ defined(CONFIG_BUILD_KERNEL)) && defined(CONFIG_MM_KERNEL_HEAP) -/************************************************************************ - * Pre-processor definition - ************************************************************************/ - -/************************************************************************ - * Private Types - ************************************************************************/ - -/************************************************************************ - * Public Data - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_heapmember * * Description: @@ -80,7 +64,7 @@ * not. If the address is not a member of the kernel heap, then it * must be a member of the user-space heap (unchecked) * - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_DEBUG bool kmm_heapmember(FAR void *mem) diff --git a/mm/kmm_heap/kmm_mallinfo.c b/mm/kmm_heap/kmm_mallinfo.c index 2ad3d26df6c2d4048534146d1acf1cd784c42e0b..9f812bad2b9ccbfd462ded5c228bd9f522491233 100644 --- a/mm/kmm_heap/kmm_mallinfo.c +++ b/mm/kmm_heap/kmm_mallinfo.c @@ -45,18 +45,6 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_malloc.c b/mm/kmm_heap/kmm_malloc.c index a92e5e54496404aa3fa806520f43c37318f9af43..06bed81c50110f49ab096aacc03fd93ac5c63bcc 100644 --- a/mm/kmm_heap/kmm_malloc.c +++ b/mm/kmm_heap/kmm_malloc.c @@ -43,31 +43,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_malloc * * Description: @@ -79,7 +59,7 @@ * Return Value: * The address of the allocated memory (NULL on failure to allocate) * - ************************************************************************/ + ****************************************************************************/ FAR void *kmm_malloc(size_t size) { diff --git a/mm/kmm_heap/kmm_memalign.c b/mm/kmm_heap/kmm_memalign.c index 40327e1d828f721c26f4ac7e108d7c4af5a0ba58..2ca1465bf02a3e2c8415db3718b917dee976aaa4 100644 --- a/mm/kmm_heap/kmm_memalign.c +++ b/mm/kmm_heap/kmm_memalign.c @@ -45,19 +45,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_memalign * * Description: @@ -70,7 +62,7 @@ * Return Value: * The address of the re-allocated memory (NULL on failure to allocate) * - ************************************************************************/ + ****************************************************************************/ FAR void *kmm_memalign(size_t alignment, size_t size) { diff --git a/mm/kmm_heap/kmm_realloc.c b/mm/kmm_heap/kmm_realloc.c index 3f553c0716908ba909d5d23b9d3907c786cca8a9..477e2b70b1864930e2e0ad145bc1569f98a793ac 100644 --- a/mm/kmm_heap/kmm_realloc.c +++ b/mm/kmm_heap/kmm_realloc.c @@ -43,14 +43,6 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_sbrk.c b/mm/kmm_heap/kmm_sbrk.c index 3cee21b4261817284d1a7c05d36b02e811ff65cb..4d4b95746f9d5c2fb6c124aa6a7c9425b94cfe6e 100644 --- a/mm/kmm_heap/kmm_sbrk.c +++ b/mm/kmm_heap/kmm_sbrk.c @@ -43,10 +43,6 @@ #if defined(CONFIG_BUILD_KERNEL) && defined(__KERNEL__) -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/kmm_heap/kmm_sem.c b/mm/kmm_heap/kmm_sem.c index 47fce18d41ab90cc0826d2f82b2dbfc146e69a91..2ba019f6732468d6d9ba9b7bdac8d7a349f06e85 100644 --- a/mm/kmm_heap/kmm_sem.c +++ b/mm/kmm_heap/kmm_sem.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/kmm_heap/kmm_sem.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,27 +43,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/************************************************************************ - * Pre-processor definition - ************************************************************************/ - -/************************************************************************ - * Private Types - ************************************************************************/ - -/************************************************************************ - * Public Data - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_trysemaphore * * Description: @@ -75,14 +59,14 @@ * Return Value: * OK on success; a negated errno on failure * - ************************************************************************/ + ****************************************************************************/ int kmm_trysemaphore(void) { return mm_trysemaphore(&g_kmmheap); } -/************************************************************************ +/**************************************************************************** * Name: kmm_givesemaphore * * Description: @@ -94,7 +78,7 @@ int kmm_trysemaphore(void) * Return Value: * OK on success; a negated errno on failure * - ************************************************************************/ + ****************************************************************************/ void kmm_givesemaphore(void) { diff --git a/mm/kmm_heap/kmm_zalloc.c b/mm/kmm_heap/kmm_zalloc.c index c09f3290457e6e1c7734eb073142f574cfadac60..19bea29f15983320443ceaa0a5d68ba7a16a176c 100644 --- a/mm/kmm_heap/kmm_zalloc.c +++ b/mm/kmm_heap/kmm_zalloc.c @@ -43,15 +43,11 @@ #ifdef CONFIG_MM_KERNEL_HEAP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kmm_zalloc * * Description: @@ -63,7 +59,7 @@ * Return Value: * The address of the allocated memory (NULL on failure to allocate) * - ************************************************************************/ + ****************************************************************************/ FAR void *kmm_zalloc(size_t size) { diff --git a/mm/mm_gran/mm_granalloc.c b/mm/mm_gran/mm_granalloc.c index f66e5168bce4401d4590ec71911a8397a2554b53..79044ca3a16e52c1a9548fdda9a1916c6fa256e1 100644 --- a/mm/mm_gran/mm_granalloc.c +++ b/mm/mm_gran/mm_granalloc.c @@ -47,10 +47,6 @@ #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -253,7 +249,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size) } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/mm/mm_gran/mm_grancritical.c b/mm/mm_gran/mm_grancritical.c index ae16a39844aaab0d48bda0859abe5ff76680b112..fd8485c4112a088189236ea09dc6ce1dc2d9fe5a 100644 --- a/mm/mm_gran/mm_grancritical.c +++ b/mm/mm_gran/mm_grancritical.c @@ -1,7 +1,7 @@ /**************************************************************************** * mm/mm_gran/mm_grancritical.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,25 +43,13 @@ #include #include -#include +#include #include #include "mm_gran/mm_gran.h" #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -83,7 +71,7 @@ void gran_enter_critical(FAR struct gran_s *priv) { #ifdef CONFIG_GRAN_INTR - priv->irqstate = irqsave(); + priv->irqstate = enter_critical_section(); #else int ret; @@ -104,7 +92,7 @@ void gran_enter_critical(FAR struct gran_s *priv) void gran_leave_critical(FAR struct gran_s *priv) { #ifdef CONFIG_GRAN_INTR - irqrestore(priv->irqstate); + leave_critical_section(priv->irqstate); #else sem_post(&priv->exclsem); #endif diff --git a/mm/mm_gran/mm_granfree.c b/mm/mm_gran/mm_granfree.c index d2df5cd4d4096a959eb4f2be6f004883ebd12f51..a1b9db991717f63967299041661e64a72cb63e7c 100644 --- a/mm/mm_gran/mm_granfree.c +++ b/mm/mm_gran/mm_granfree.c @@ -137,7 +137,7 @@ static inline void gran_common_free(FAR struct gran_s *priv, } /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/mm/mm_gran/mm_graninit.c b/mm/mm_gran/mm_graninit.c index 0d4bf18b7f2bd6ec23db5ecde6f8ea94b1b06b69..03cde59b117080bdcbcfea6f39795aef43a22332 100644 --- a/mm/mm_gran/mm_graninit.c +++ b/mm/mm_gran/mm_graninit.c @@ -49,10 +49,6 @@ #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -127,7 +123,7 @@ gran_common_initialize(FAR void *heapstart, size_t heapsize, uint8_t log2gran, * correct size. */ - priv = ( FAR struct gran_s *)kmm_zalloc(SIZEOF_GRAN_S(ngranules)); + priv = (FAR struct gran_s *)kmm_zalloc(SIZEOF_GRAN_S(ngranules)); if (priv) { /* Initialize non-zero elements of the granules heap info structure */ diff --git a/mm/mm_gran/mm_granmark.c b/mm/mm_gran/mm_granmark.c index 91bfdb0971951ee2e5f80dcd9e2d265cf545a123..7466d91c738c2b5395024e8b52adf6bd6c57123b 100644 --- a/mm/mm_gran/mm_granmark.c +++ b/mm/mm_gran/mm_granmark.c @@ -47,14 +47,6 @@ #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -100,7 +92,7 @@ void gran_mark_allocated(FAR struct gran_s *priv, uintptr_t alloc, { /* Mark bits in the first GAT entry */ - gatmask =0xffffffff << gatbit; + gatmask = 0xffffffff << gatbit; DEBUGASSERT((priv->gat[gatidx] & gatmask) == 0); priv->gat[gatidx] |= gatmask; diff --git a/mm/mm_gran/mm_granrelease.c b/mm/mm_gran/mm_granrelease.c index bb5084da40a052789181614fcdabce9ebf220fa2..38fc354ced71d61c5cb903ac22a0054e2d3224b0 100644 --- a/mm/mm_gran/mm_granrelease.c +++ b/mm/mm_gran/mm_granrelease.c @@ -49,10 +49,6 @@ #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/mm/mm_gran/mm_granreserve.c b/mm/mm_gran/mm_granreserve.c index 6becbd0f00f00f17bbb444dc43d0cfbf32258d38..99581279690a78ca9942501e14873ec1f9bbfc9b 100644 --- a/mm/mm_gran/mm_granreserve.c +++ b/mm/mm_gran/mm_granreserve.c @@ -47,10 +47,6 @@ #ifdef CONFIG_GRAN -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/mm/mm_gran/mm_pgalloc.c b/mm/mm_gran/mm_pgalloc.c index 6f7b33acdf20d744321b231d377d91c15f68d652..474d9e0f4ea8972a6a0b97d7b4d295e8179d0e81 100644 --- a/mm/mm_gran/mm_pgalloc.c +++ b/mm/mm_gran/mm_pgalloc.c @@ -61,7 +61,7 @@ * * Dependencies: CONFIG_ARCH_USE_MMU and CONFIG_GRAN */ - + /* Debug */ #ifdef CONFIG_CPP_HAVE_VARARGS @@ -208,9 +208,9 @@ uintptr_t mm_pgalloc(unsigned int npages) void mm_pgfree(uintptr_t paddr, unsigned int npages) { #ifdef CONFIG_GRAN_SINGLE - gran_free((FAR void*)paddr, (size_t)npages << MM_PGSHIFT); + gran_free((FAR void *)paddr, (size_t)npages << MM_PGSHIFT); #else - gran_free(g_pgalloc, (FAR void*)paddr, (size_t)npages << MM_PGSHIFT); + gran_free(g_pgalloc, (FAR void *)paddr, (size_t)npages << MM_PGSHIFT); #endif } diff --git a/mm/mm_heap/mm_addfreechunk.c b/mm/mm_heap/mm_addfreechunk.c index 64b503dd749e7cd0afb58c3db822b0cae5a270e9..e2defc09082c8b99249e236b7fd1b03f5e53ac57 100644 --- a/mm/mm_heap/mm_addfreechunk.c +++ b/mm/mm_heap/mm_addfreechunk.c @@ -42,15 +42,7 @@ #include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** diff --git a/mm/mm_heap/mm_brkaddr.c b/mm/mm_heap/mm_brkaddr.c index 1d7b22680c98732ed8b24622d631d6f0c6b2343c..38aa113efa7e9a532f421f0131072c29a39c9ef9 100644 --- a/mm/mm_heap/mm_brkaddr.c +++ b/mm/mm_heap/mm_brkaddr.c @@ -43,10 +43,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/mm_heap/mm_calloc.c b/mm/mm_heap/mm_calloc.c index fe94ff0338e16d65ccac945551274dc7ba212dfa..43d06e2e31a111886888c2d555355bbf13793aae 100644 --- a/mm/mm_heap/mm_calloc.c +++ b/mm/mm_heap/mm_calloc.c @@ -41,10 +41,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c index ae0f50d3c744a28824f39e7b06b0247af1b39faa..57cb867f8dec58a569f29f2307cfbb3d0c66fb00 100644 --- a/mm/mm_heap/mm_free.c +++ b/mm/mm_heap/mm_free.c @@ -44,14 +44,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -88,12 +80,12 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) /* Map the memory chunk into a free node */ - node = (FAR struct mm_freenode_s *)((char*)mem - SIZEOF_MM_ALLOCNODE); + node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE); node->preceding &= ~MM_ALLOC_BIT; /* Check if the following node is free and, if so, merge it */ - next = (FAR struct mm_freenode_s *)((char*)node + node->size); + next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size); if ((next->preceding & MM_ALLOC_BIT) == 0) { FAR struct mm_allocnode_s *andbeyond; @@ -103,7 +95,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) * index past the tail chunk because it is always allocated. */ - andbeyond = (FAR struct mm_allocnode_s*)((char*)next + next->size); + andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + next->size); /* Remove the next node. There must be a predecessor, * but there may not be a successor node. @@ -127,7 +119,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem) * it with this node */ - prev = (FAR struct mm_freenode_s *)((char*)node - node->preceding); + prev = (FAR struct mm_freenode_s *)((FAR char *)node - node->preceding); if ((prev->preceding & MM_ALLOC_BIT) == 0) { /* Remove the node. There must be a predecessor, but there may diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index f2d02d64bd74750ca528b526099e9f15f0a9d252..bd9d4f524a4cb15c817a4cb288d91db193540999 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -45,18 +45,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c index 9b97760dd8b72fd19ae6a6ccd3eba8744749db5d..f3c8775ba6323ec0abba371c3a580aa71968172d 100644 --- a/mm/mm_heap/mm_mallinfo.c +++ b/mm/mm_heap/mm_mallinfo.c @@ -45,18 +45,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -71,7 +59,7 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info) { - struct mm_allocnode_s *node; + FAR struct mm_allocnode_s *node; size_t mxordblk = 0; int ordblks = 0; /* Number of non-inuse chunks */ size_t uordblks = 0; /* Total allocated space */ @@ -98,7 +86,7 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info) for (node = heap->mm_heapstart[region]; node < heap->mm_heapend[region]; - node = (struct mm_allocnode_s *)((char*)node + node->size)) + node = (FAR struct mm_allocnode_s *)((FAR char *)node + node->size)) { mvdbg("region=%d node=%p size=%p preceding=%p (%c)\n", region, node, node->size, (node->preceding & ~MM_ALLOC_BIT), diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index 9890e5712c70be6aeb3b1f759edec2e5607b6067..3f9db86a336463b514bf6fa66045dbb0d79699e6 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -49,25 +49,9 @@ ****************************************************************************/ #ifndef NULL -# define NULL ((void*)0) +# define NULL ((void *)0) #endif -/**************************************************************************** - * Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -164,11 +148,11 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) { /* Get a pointer to the next node in physical memory */ - next = (FAR struct mm_freenode_s*)(((char*)node) + node->size); + next = (FAR struct mm_freenode_s *)(((FAR char *)node) + node->size); /* Create the remainder node */ - remainder = (FAR struct mm_freenode_s*)(((char*)node) + size); + remainder = (FAR struct mm_freenode_s *)(((FAR char *)node) + size); remainder->size = remaining; remainder->preceding = size; @@ -190,7 +174,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) /* Handle the case of an exact size match */ node->preceding |= MM_ALLOC_BIT; - ret = (void*)((char*)node + SIZEOF_MM_ALLOCNODE); + ret = (void *)((FAR char *)node + SIZEOF_MM_ALLOCNODE); } mm_givesemaphore(heap); diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c index aa7971c0cb830bbf397c4224a666a541b2fcf092..bd8abb8c056340fb870994e9423586cc17915057 100644 --- a/mm/mm_heap/mm_memalign.c +++ b/mm/mm_heap/mm_memalign.c @@ -43,14 +43,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -119,7 +111,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, * the allocation. */ - node = (FAR struct mm_allocnode_s*)(rawchunk - SIZEOF_MM_ALLOCNODE); + node = (FAR struct mm_allocnode_s *)(rawchunk - SIZEOF_MM_ALLOCNODE); /* Find the aligned subregion */ @@ -135,7 +127,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, /* Get the node the next node after the allocation. */ - next = (FAR struct mm_allocnode_s*)((char*)node + node->size); + next = (FAR struct mm_allocnode_s *)((FAR char *)node + node->size); /* Make sure that there is space to convert the preceding mm_allocnode_s * into an mm_freenode_s. I think that this should always be true @@ -143,7 +135,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, DEBUGASSERT(alignedchunk >= rawchunk + 8); - newnode = (FAR struct mm_allocnode_s*)(alignedchunk - SIZEOF_MM_ALLOCNODE); + newnode = (FAR struct mm_allocnode_s *)(alignedchunk - SIZEOF_MM_ALLOCNODE); /* Preceding size is full size of the new 'node,' including * SIZEOF_MM_ALLOCNODE @@ -162,7 +154,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, if (precedingsize < SIZEOF_MM_FREENODE) { alignedchunk += alignment; - newnode = (FAR struct mm_allocnode_s*)(alignedchunk - SIZEOF_MM_ALLOCNODE); + newnode = (FAR struct mm_allocnode_s *)(alignedchunk - SIZEOF_MM_ALLOCNODE); precedingsize = (size_t)newnode - (size_t)node; } @@ -210,5 +202,5 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, } mm_givesemaphore(heap); - return (FAR void*)alignedchunk; + return (FAR void *)alignedchunk; } diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index 5778975f50b6d198234a403ed4fe32b530c6d548..bf28ff62dfc345be0b8b10eb6f01d1d2015c47fa 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -46,14 +46,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -115,7 +107,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Map the memory chunk into an allocated node structure */ - oldnode = (FAR struct mm_allocnode_s *)((FAR char*)oldmem - SIZEOF_MM_ALLOCNODE); + oldnode = (FAR struct mm_allocnode_s *)((FAR char *)oldmem - SIZEOF_MM_ALLOCNODE); /* We need to hold the MM semaphore while we muck with the nodelist. */ @@ -146,13 +138,13 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, * best decision */ - next = (FAR struct mm_freenode_s *)((FAR char*)oldnode + oldnode->size); + next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldnode->size); if ((next->preceding & MM_ALLOC_BIT) == 0) { nextsize = next->size; } - prev = (FAR struct mm_freenode_s *)((FAR char*)oldnode - (oldnode->preceding & ~MM_ALLOC_BIT)); + prev = (FAR struct mm_freenode_s *)((FAR char *)oldnode - (oldnode->preceding & ~MM_ALLOC_BIT)); if ((prev->preceding & MM_ALLOC_BIT) == 0) { prevsize = prev->size; @@ -240,7 +232,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Extend the node into the previous free chunk */ - newnode = (FAR struct mm_allocnode_s *)((FAR char*)oldnode - takeprev); + newnode = (FAR struct mm_allocnode_s *)((FAR char *)oldnode - takeprev); /* Did we consume the entire preceding chunk? */ @@ -258,10 +250,6 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Return the previous free node to the nodelist (with the new size) */ mm_addfreechunk(heap, prev); - - /* Now we want to return newnode */ - - oldnode = newnode; } else { @@ -272,6 +260,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, next->preceding = newnode->size | (next->preceding & MM_ALLOC_BIT); } + /* Now we want to return newnode */ + oldnode = newnode; oldsize = newnode->size; @@ -279,7 +269,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, * should be save for this. */ - newmem = (FAR void*)((FAR char*)newnode + SIZEOF_MM_ALLOCNODE); + newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE); memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE); } @@ -294,7 +284,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, * chunk) */ - andbeyond = (FAR struct mm_allocnode_s*)((char*)next + nextsize); + andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize); /* Remove the next node. There must be a predecessor, but there * may not be a successor node. @@ -310,7 +300,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Extend the node into the next chunk */ oldnode->size = oldsize + takenext; - newnode = (FAR struct mm_freenode_s *)((char*)oldnode + oldnode->size); + newnode = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldnode->size); /* Did we consume the entire preceding chunk? */ @@ -349,7 +339,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, */ mm_givesemaphore(heap); - newmem = (FAR void*)mm_malloc(heap, size); + newmem = (FAR void *)mm_malloc(heap, size); if (newmem) { memcpy(newmem, oldmem, oldsize); diff --git a/mm/mm_heap/mm_sbrk.c b/mm/mm_heap/mm_sbrk.c index a0f868012eb18457a698866fafa829f92198b94f..774d5d3f1118b239c5d3e082e438145354e395cc 100644 --- a/mm/mm_heap/mm_sbrk.c +++ b/mm/mm_heap/mm_sbrk.c @@ -49,10 +49,6 @@ #ifdef CONFIG_BUILD_KERNEL -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -75,7 +71,7 @@ * heap - A reference to the data structure that defines this heap. * incr - Specifies the number of bytes to add or to remove from the * space allocated for the process. - maxbreak - The maximum permissible break address. + * maxbreak - The maximum permissible break address. * * Returned Value: * Upon successful completion, sbrk() returns the prior break value. diff --git a/mm/mm_heap/mm_sem.c b/mm/mm_heap/mm_sem.c index 4be65b623c2f37faedc3835ae0f1ef76f5069e08..ae00b0b80fe68e4cc995f04e83c66a5a7d45f391 100644 --- a/mm/mm_heap/mm_sem.c +++ b/mm/mm_heap/mm_sem.c @@ -67,10 +67,6 @@ # endif #endif -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -86,7 +82,7 @@ void mm_seminitialize(FAR struct mm_heap_s *heap) { /* Initialize the MM semaphore to one (to support one-at-a-time access to - * private data sets. + * private data sets). */ (void)sem_init(&heap->mm_semaphore, 0, 1); @@ -220,4 +216,3 @@ void mm_givesemaphore(FAR struct mm_heap_s *heap) ASSERT(sem_post(&heap->mm_semaphore) == 0); } } - diff --git a/mm/mm_heap/mm_shrinkchunk.c b/mm/mm_heap/mm_shrinkchunk.c index 05fc3a7a0db07d798c1919aee68f254360119d70..8ce1c7c333d668d7b00d13dfb2e7709f51f905ae 100644 --- a/mm/mm_heap/mm_shrinkchunk.c +++ b/mm/mm_heap/mm_shrinkchunk.c @@ -44,11 +44,7 @@ #include /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -73,7 +69,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap, /* Get a reference to the next node */ - next = (FAR struct mm_freenode_s*)((char*)node + node->size); + next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size); /* Check if it is free */ @@ -84,7 +80,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap, /* Get the chunk next the next node (which could be the tail chunk) */ - andbeyond = (FAR struct mm_allocnode_s*)((char*)next + next->size); + andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + next->size); /* Remove the next node. There must be a predecessor, but there may * not be a successor node. @@ -101,7 +97,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap, * tailing memory from the aligned chunk. */ - newnode = (FAR struct mm_freenode_s*)((char*)node + size); + newnode = (FAR struct mm_freenode_s *)((FAR char *)node + size); /* Set up the size of the new node */ @@ -127,7 +123,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap, * tailing memory from the aligned chunk. */ - newnode = (FAR struct mm_freenode_s*)((char*)node + size); + newnode = (FAR struct mm_freenode_s *)((FAR char *)node + size); /* Set up the size of the new node */ diff --git a/mm/mm_heap/mm_size2ndx.c b/mm/mm_heap/mm_size2ndx.c index e3273767e95792fff735c2e72714cc123a7ffa58..841dea368731f3294e80452d4b899e10f74d6081 100644 --- a/mm/mm_heap/mm_size2ndx.c +++ b/mm/mm_heap/mm_size2ndx.c @@ -41,10 +41,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/mm_heap/mm_zalloc.c b/mm/mm_heap/mm_zalloc.c index deb3408d673b7e60c52175c74af8f2fe13185bb8..a9d5af9525b4d7a6ede7c55fc546008b2eca58b5 100644 --- a/mm/mm_heap/mm_zalloc.c +++ b/mm/mm_heap/mm_zalloc.c @@ -43,10 +43,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/shm/shm_initialize.c b/mm/shm/shm_initialize.c index b57d3e8f9a3dc9a1398fb402f9ae1c5509a072ce..a25bc8fd1997dabbc69d71dc0d6dd627598f69d5 100644 --- a/mm/shm/shm_initialize.c +++ b/mm/shm/shm_initialize.c @@ -52,14 +52,6 @@ #ifdef CONFIG_MM_SHM -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -68,10 +60,6 @@ struct shm_info_s g_shminfo; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/shm/shmat.c b/mm/shm/shmat.c index 3a9bc4c089eec784129a3b283cd62495a99ea544..b3658a38fad95f1dce62e57bbe51f961d3742a44 100644 --- a/mm/shm/shmat.c +++ b/mm/shm/shmat.c @@ -50,22 +50,6 @@ #ifdef CONFIG_MM_SHM -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/shm/shmctl.c b/mm/shm/shmctl.c index 0c2dc6cb86ec789aa819e6c51c9597aaf7572c50..6ba3a33f1af4466031681c69859a1e96d88a4aaf 100644 --- a/mm/shm/shmctl.c +++ b/mm/shm/shmctl.c @@ -55,22 +55,6 @@ #ifdef CONFIG_MM_SHM -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/mm/shm/shmdt.c b/mm/shm/shmdt.c index 0ecee2ab3014d8187ee15b7b414a3d1daf0417e3..201e944b6561a9073f79174c52df38c4d399a2a9 100644 --- a/mm/shm/shmdt.c +++ b/mm/shm/shmdt.c @@ -50,22 +50,6 @@ #ifdef CONFIG_MM_SHM -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -87,7 +71,7 @@ * of the attached shared memory segment and return 0. * * Otherwise, the shared memory segment will not be detached, shmdt() - & will return -1, and errno will be set to indicate the error. + * will return -1, and errno will be set to indicate the error. * * - EINVAL * The value of shmaddr is not the data segment start address of a diff --git a/mm/shm/shmget.c b/mm/shm/shmget.c index 35bb7c26ac443cefd2ef8952ffd5c7f7f1324718..e3f020846099caf7f7f7e98c7e5dddf6c66dbb9a 100644 --- a/mm/shm/shmget.c +++ b/mm/shm/shmget.c @@ -53,18 +53,6 @@ #ifdef CONFIG_MM_SHM -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/mm/umm_heap/umm_addregion.c b/mm/umm_heap/umm_addregion.c index 3aaa890aa232d230da2242be18aac522683ba855..00e5372ee8bce1b7b8db613f9048261885ce8f91 100644 --- a/mm/umm_heap/umm_addregion.c +++ b/mm/umm_heap/umm_addregion.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/umm_heap/umm_addregion.c * * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,11 +43,11 @@ #include "umm_heap/umm_heap.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: umm_addregion * * Description: @@ -62,7 +62,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void umm_addregion(FAR void *heap_start, size_t heap_size) { diff --git a/mm/umm_heap/umm_globals.c b/mm/umm_heap/umm_globals.c index 8242769c0ccece78279dd447267f563a02ca1c15..012aac76315d938153f7d2e1b60fe07cdb95faa1 100644 --- a/mm/umm_heap/umm_globals.c +++ b/mm/umm_heap/umm_globals.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/umm_heap/umm_globals.c * * Copyright (C) 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,9 +43,9 @@ #include "umm_heap/umm_heap.h" -/************************************************************************ +/**************************************************************************** * Public Data - ************************************************************************/ + ****************************************************************************/ #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) /* In the kernel build, there a multiple user heaps; one for each task diff --git a/mm/umm_heap/umm_initialize.c b/mm/umm_heap/umm_initialize.c index f4d319844a6185728f2df64a9ce3dce658b7b8c7..04e045e0730499ca60d2bf990697765dc1ff94f9 100644 --- a/mm/umm_heap/umm_initialize.c +++ b/mm/umm_heap/umm_initialize.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/umm_heap/umm_initialize.c * * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,11 +45,11 @@ #include "umm_heap/umm_heap.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: umm_initialize * * Description: @@ -92,7 +92,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void umm_initialize(FAR void *heap_start, size_t heap_size) { diff --git a/mm/umm_heap/umm_mallinfo.c b/mm/umm_heap/umm_mallinfo.c index f7a5b9dc07f018690dc0d9a67dfe1e960329db4a..a6c1aaa847782f881175cdd5d115247209af4e73 100644 --- a/mm/umm_heap/umm_mallinfo.c +++ b/mm/umm_heap/umm_mallinfo.c @@ -69,7 +69,7 @@ struct mallinfo mallinfo(void) #else -int mallinfo(struct mallinfo *info) +int mallinfo(FAR struct mallinfo *info) { return mm_mallinfo(USR_HEAP, info); } diff --git a/mm/umm_heap/umm_malloc.c b/mm/umm_heap/umm_malloc.c index 19dfa89918e27a90b8b2345f469fa12b771941e9..7832af4e2938f962905554da18a744bccef4d4bc 100644 --- a/mm/umm_heap/umm_malloc.c +++ b/mm/umm_heap/umm_malloc.c @@ -50,7 +50,7 @@ * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: malloc * * Description: @@ -62,7 +62,7 @@ * Return Value: * The address of the allocated memory (NULL on failure to allocate) * - ************************************************************************/ + ****************************************************************************/ FAR void *malloc(size_t size) { diff --git a/mm/umm_heap/umm_sem.c b/mm/umm_heap/umm_sem.c index f8cf11b6c8a010f80d60009a7fe583d9c719361b..a9012e542c2bfbc6d2f106eff20685fd35356a48 100644 --- a/mm/umm_heap/umm_sem.c +++ b/mm/umm_heap/umm_sem.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * mm/umm_heap/umm_sem.c * * Copyright (C) 2013-2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,11 +43,11 @@ #include "umm_heap/umm_heap.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: umm_trysemaphore * * Description: @@ -61,14 +61,14 @@ * Return Value: * OK on success; a negated errno on failure * - ************************************************************************/ + ****************************************************************************/ int umm_trysemaphore(void) { return mm_trysemaphore(USR_HEAP); } -/************************************************************************ +/**************************************************************************** * Name: umm_givesemaphore * * Description: @@ -82,7 +82,7 @@ int umm_trysemaphore(void) * Return Value: * OK on success; a negated errno on failure * - ************************************************************************/ + ****************************************************************************/ void umm_givesemaphore(void) { diff --git a/mm/umm_heap/umm_zalloc.c b/mm/umm_heap/umm_zalloc.c index 95080427cf68b5de678657e6a39f1f37f6172321..7103e3233b66b3811bf25c51329663f98732546a 100644 --- a/mm/umm_heap/umm_zalloc.c +++ b/mm/umm_heap/umm_zalloc.c @@ -50,7 +50,7 @@ * Public Functions ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: zalloc * * Description: @@ -62,7 +62,7 @@ * Return Value: * The address of the allocated memory (NULL on failure to allocate) * - ************************************************************************/ + ****************************************************************************/ FAR void *zalloc(size_t size) { diff --git a/net/6lowpan/6lowpan.h b/net/6lowpan/6lowpan.h new file mode 100644 index 0000000000000000000000000000000000000000..657b04c75b48ee697ed7e02107f4d21cd5b96982 --- /dev/null +++ b/net/6lowpan/6lowpan.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * net/6lowpan/6lowpan.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __NET_6LOWPAN_6LOWPAN_H +#define __NET_6LOWPAN_6LOWPAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_NET_6LOWPAN + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* CONFIG_NET_6LOWPAN */ +#endif /* __NET_6LOWPAN_6LOWPAN_H */ diff --git a/net/6lowpan/Kconfig b/net/6lowpan/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..e72e42268b4aa33cc2c11fb34010db3058a01a2c --- /dev/null +++ b/net/6lowpan/Kconfig @@ -0,0 +1,39 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig NET_6LOWPAN + bool "IEEE 802.15.4 6LoWPAN support" + default n + depends on EXPERIMENTAL && NET_IPv6 + ---help--- + Enable support for IEEE 802.15.4 Low power Wireless Personal Area + Networking (6LoWPAN). + +if NET_6LOWPAN + +config NET_6LOWPAN_MTU + int "6LoWPAN packet buffer size (MTU)" + default 1294 + range 590 1518 + ---help--- + Packet buffer size. This size includes the TCP/UDP payload plus the + size of TCP/UDP header, the IP header, and data link layer headers. + This value is normally referred to as the MTU (Maximum Transmission + Unit); the payload is the MSS (Maximum Segment Size). + + IPv6 hosts are required to be able to handle an MSS of 1220 octets, + resulting in a minimum buffer size of of 1220+20+40+xx = xx. REVISIT! + +config NET_6LOWPAN_TCP_RECVWNDO + int "6LoWPAN TCP receive window size" + default 1220 + depends on NET_TCP + ---help--- + The size of the advertised receiver's window. Should be set low + (i.e., to the size of the MSS) if the application is slow to process + incoming data, or high (32768 bytes) if the application processes + data quickly. REVISIT! + +endif # NET_6LOWPAN diff --git a/net/6lowpan/Make.defs b/net/6lowpan/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..e52060673af92e35ac4e3382444966d88d8f5f38 --- /dev/null +++ b/net/6lowpan/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# net/6lowpan/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# IEEE 802.15.4 support + +ifeq ($(CONFIG_NET_6LOWPAN),y) + +# Include IEEE 802.15.4 file in the build + +# NET_CSRCS += + +# Include the 6lowpan directory in the build + +DEPPATH += --dep-path 6lowpan +VPATH += :6lowpan + +endif # CONFIG_NET_6LOWPAN diff --git a/net/Kconfig b/net/Kconfig index 3c91e020d052c91c6971b65f50463cc9118ae069..a69a42e3d1a0681f2a8383edca70340352a05909 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -24,10 +24,12 @@ config NET_NOINTS bool "Not interrupt driven" default n ---help--- - NET_NOINT indicates that uIP is not called from the interrupt level. - If NET_NOINTS is defined, critical sections will be managed with semaphores; - Otherwise, it assumed that uIP will be called from interrupt level handling - and critical sections will be managed by enabling and disabling interrupts. + NET_NOINT indicates that network layer is not called from the + interrupt level. If NET_NOINTS is defined, critical sections + will be managed with semaphores; Otherwise, it assumed that + network layer will be called from interrupt level handling + and critical sections will be managed by enabling and disabling + interrupts. config NET_PROMISCUOUS bool "Promiscuous mode" @@ -42,12 +44,12 @@ config NET_MULTIBUFFER bool "Use multiple device-side I/O buffers" default n ---help--- - Traditionally, uIP has used a single buffer for all incoming and - outgoing traffic. If this configuration is selected, then the - driver can manage multiple I/O buffers and can, for example, - be filling one input buffer while sending another output buffer. - Or, as another example, the driver may support queuing of concurrent - input/ouput and output transfers for better performance. + Traditionally, the uIP stacl has used a single buffer for all + incoming and outgoing traffic. If this configuration is selected, + then the driver can manage multiple I/O buffers and can, for + example, be filling one input buffer while sending another output + buffer. Or, as another example, the driver may support queuing of + concurrent input/ouput and output transfers for better performance. config NET_ETH_MTU int "Ethernet packet buffer size (MTU)" @@ -85,12 +87,25 @@ config NET_SLIP_MTU depends on NET_SLIP range 296 1518 ---help--- - Packet buffer size. This size includes the TCP/UDP payload plus the - size of TCP/UDP header and the IP header. This value is normally - referred to as the MTU (Maximum Transmission Unit); the payload - payload is the MSS (Maximum Segment Size). SLIP is required to - support at lest 256+20+20 = 296. Values other than 296 are not - recommended. + Provides the size of the SLIP packet buffers. This size includes + the TCP/UDP payload plus the size of TCP/UDP header and the IP header. + This value is normally referred to as the MTU (Maximum Transmission Unit); + the payload payload is the MSS (Maximum Segment Size). + + SLIP is required to support at lest 256+20+20 = 296. Values other than + 296 are not recommended. + + The Linux slip module hard-codes its MTU size to 296 (40 bytes for + the IP+TPC headers plus 256 bytes of data). So you might as well + set CONFIG_NET_SLIP_MTU to 296 as well. + + There may be an issue with this setting, however. I see that Linux + uses a MTU of 296 and window of 256, but actually only sends 168 + bytes of data: 40 + 128. I believe that is to allow for the 2x + worst cast packet expansion. Ideally we would like to advertise the + 256 MSS, but restrict transfers to 128 bytes (possibly by modifying + the MSS value in the TCP connection structure). + config NET_SLIP_TCP_RECVWNDO int "SLIP TCP receive window size" @@ -143,28 +158,38 @@ config NET_ETHERNET bool "Ethernet support" default y if !NET_SLIP default n if NET_SLIP - select NETDEV_MULTINIC if NET_SLIP - select NET_MULTILINK if NET_SLIP + select NETDEV_MULTINIC if NET_LOOPBACK || NET_SLIP || NET_TUN + select NET_MULTILINK if NET_LOOPBACK || NET_SLIP || NET_TUN ---help--- If NET_SLIP is not selected, then Ethernet will be used (there is no need to define anything special in the configuration file to use Ethernet -- it is the default). +config NET_LOOPBACK + bool "Local loopback" + default n + select NETDEV_MULTINIC if NET_ETHERNET || NET_SLIP || NET_TUN + select NET_MULTILINK if NET_ETHERNET || NET_SLIP || NET_TUN + ---help--- + Add support for the local network loopback device, lo. Any additional + networking devices that are enabled must be compatible with + CONFIG_NET_NOINTS. + config NET_SLIP bool "SLIP support" default n - select NETDEV_MULTINIC if NET_ETHERNET - select NET_MULTILINK if NET_ETHERNET + select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_TUN + select NET_MULTILINK if NET_ETHERNET || NET_LOOPBACK || NET_TUN ---help--- Enables building of the SLIP driver. SLIP requires at least one IP protocol selected and the following additional network settings: NET_NOINTS and NET_MULTIBUFFER. SLIP supports point-to-point IP communications over a serial port. - The default data link layer for uIP is Ethernet. If NET_SLIP is - defined in the NuttX configuration file, then SLIP will be supported. - The basic differences between the SLIP and Ethernet configurations is - that when SLIP is selected: + The default data link layer for network layer is Ethernet. If + NET_SLIP is defined in the NuttX configuration file, then SLIP will + be supported. The basic differences between the SLIP and Ethernet + configurations is that when SLIP is selected: * The link level header (that comes before the IP header) is omitted. * All MAC address processing is suppressed. @@ -201,6 +226,9 @@ endif # NET_SLIP config NET_TUN bool "TUN Virtual Network Device support" default n + select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_SLIP + select NET_MULTILINK if NET_ETHERNET || NET_LOOPBACK || NET_SLIP + select ARCH_HAVE_NETDEV_STATISTICS if NET_TUN @@ -227,13 +255,15 @@ config NET_IPv4 ---help--- Build in support for IPv4. -config NET_IPv6 +menuconfig NET_IPv6 bool "IPv6" default n ---help--- Build in support for IPv6. source "net/neighbor/Kconfig" +source "net/6lowpan/Kconfig" + endmenu # Internet Protocol Selection source "net/socket/Kconfig" @@ -245,14 +275,16 @@ source "net/icmp/Kconfig" source "net/icmpv6/Kconfig" source "net/igmp/Kconfig" source "net/arp/Kconfig" +source "net/loopback/Kconfig" source "net/iob/Kconfig" +source "net/procfs/Kconfig" source "net/utils/Kconfig" config NET_STATISTICS bool "Collect network statistics" default n ---help--- - uIP statistics on or off + Network layer statistics on or off source "net/route/Kconfig" diff --git a/net/Makefile b/net/Makefile index ce3faf0f3ab9dafc77305285ab0f06046517c2a4..5cfc2349e28ae01477d51ddf0fb2e9e03c4550f5 100644 --- a/net/Makefile +++ b/net/Makefile @@ -67,8 +67,11 @@ include pkt/Make.defs include local/Make.defs include tcp/Make.defs include udp/Make.defs +include 6lowpan/Make.defs include devif/Make.defs +include loopback/Make.defs include route/Make.defs +include procfs/Make.defs include utils/Make.defs endif diff --git a/net/README.txt b/net/README.txt index db0a59452a7a8aa3f95c07bc6cd90ab038c65916..0f93c075813a33803fb9adbb499500eb16541d67 100644 --- a/net/README.txt +++ b/net/README.txt @@ -14,6 +14,7 @@ Directory Structure +- icmpv6 - Internet Control Message Protocol (IPv6) +- iob - I/O buffering logic +- local - Unix domain (local) sockets + +- loopback - Local loopback +- neighbor - Neighbor Discovery Protocol (IPv6) +- netdev - Socket network device interface +- pkt - "Raw" packet socket support diff --git a/net/arp/Make.defs b/net/arp/Make.defs index acbe39d5ae1975cd2cc17b53b3bc06c62a0fea23..36001d9957b852ccfda4ee2346d3d16cf005e781 100644 --- a/net/arp/Make.defs +++ b/net/arp/Make.defs @@ -36,7 +36,7 @@ # ARP support is available for Ethernet only ifeq ($(CONFIG_NET_ARP),y) -NET_CSRCS +=arp_arpin.c arp_out.c arp_format.c arp_table.c arp_timer.c +NET_CSRCS += arp_arpin.c arp_out.c arp_format.c arp_table.c arp_timer.c ifeq ($(CONFIG_NET_ARP_IPIN),y) NET_CSRCS += arp_ipin.c diff --git a/net/arp/arp.h b/net/arp/arp.h index c4526a65f4d6ba11db2341892ce273750bd36706..b32490b4111909f7dee7de6e44f85abaec8228b0 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/arp/arp.h * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -176,7 +176,7 @@ struct arp_notify_s * Public Function Prototypes ****************************************************************************/ - #ifdef CONFIG_NET_ARP +#ifdef CONFIG_NET_ARP /**************************************************************************** * Name: arp_reset * @@ -420,15 +420,41 @@ FAR struct arp_entry *arp_find(in_addr_t ipaddr); * address of an existing association. * * Input parameters: + * ipaddr - The IP address as an inaddr_t + * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] + * + * Returned Value: + * Zero (OK) if the ARP table entry was successfully modified. A negated + * errno value is returned on any error. + * + * Assumptions + * The network is locked to assure exclusive access to the ARP table + * + ****************************************************************************/ + +int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr); + +/**************************************************************************** + * Name: arp_hdr_update + * + * Description: + * Add the IP/HW address mapping to the ARP table -OR- change the IP + * address of an existing association. + * + * Input parameters: * pipaddr - Refers to an IP address uint16_t[2] in network order * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] * + * Returned Value: + * Zero (OK) if the ARP table entry was successfully modified. A negated + * errno value is returned on any error. + * * Assumptions - * Interrupts are disabled to assure exclusive access to the ARP table. + * The network is locked to assure exclusive access to the ARP table * ****************************************************************************/ -void arp_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr); +void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr); /**************************************************************************** * Name: arp_dump @@ -467,6 +493,7 @@ void arp_dump(FAR struct arp_hdr_s *arp); # define arp_find(i) (NULL) # define arp_delete(i) # define arp_update(i,m); +# define arp_hdr_update(i,m); # define arp_dump(arp) #endif /* CONFIG_NET_ARP */ diff --git a/net/arp/arp_arpin.c b/net/arp/arp_arpin.c index a94bbb9fa0cd14376de425af0f5da25e89acd0e5..6945ff666abd4536ff81b285a0054ba79bfc265f 100644 --- a/net/arp/arp_arpin.c +++ b/net/arp/arp_arpin.c @@ -62,18 +62,6 @@ #define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0]) #define ARPBUF ((struct arp_hdr_s *)&dev->d_buf[ETH_HDRLEN]) -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -116,7 +104,7 @@ void arp_arpin(FAR struct net_driver_s *dev) dev->d_len = 0; ipaddr = net_ip4addr_conv32(arp->ah_dipaddr); - switch(arp->ah_opcode) + switch (arp->ah_opcode) { case HTONS(ARP_REQUEST): nllvdbg("ARP request for IP %04lx\n", (long)ipaddr); @@ -132,7 +120,7 @@ void arp_arpin(FAR struct net_driver_s *dev) * with this host in the future. */ - arp_update(arp->ah_sipaddr, arp->ah_shwaddr); + arp_hdr_update(arp->ah_sipaddr, arp->ah_shwaddr); arp->ah_opcode = HTONS(ARP_REPLY); memcpy(arp->ah_dhwaddr, arp->ah_shwaddr, ETHER_ADDR_LEN); @@ -161,7 +149,7 @@ void arp_arpin(FAR struct net_driver_s *dev) { /* Yes... Insert the address mapping in the ARP table */ - arp_update(arp->ah_sipaddr, arp->ah_shwaddr); + arp_hdr_update(arp->ah_sipaddr, arp->ah_shwaddr); /* Then notify any logic waiting for the ARP result */ diff --git a/net/arp/arp_dump.c b/net/arp/arp_dump.c index 9c796863f7c47cfff2ce0b3cf6ecba6304dde093..50ea5a27e5a236fba6371f63d323a4e06985d3b1 100644 --- a/net/arp/arp_dump.c +++ b/net/arp/arp_dump.c @@ -49,22 +49,6 @@ #ifdef CONFIG_NET_ARP_DUMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -86,7 +70,7 @@ void arp_dump(FAR struct arp_hdr_s *arp) { nlldbg(" HW type: %04x Protocol: %04x\n", - arp->ah_hwtype, arp->ah_protocol);\ + arp->ah_hwtype, arp->ah_protocol); nlldbg(" HW len: %02x Proto len: %02x Operation: %04x\n", arp->ah_hwlen, arp->ah_protolen, arp->ah_opcode); nlldbg(" Sender MAC: %02x:%02x:%02x:%02x:%02x:%02x IP: %d.%d.%d.%d\n", diff --git a/net/arp/arp_format.c b/net/arp/arp_format.c index 21cd99d20fed3fafa69de62423c7ea4f6e68dbda..4b0af255d59c0594254a612befd3441ee7a04c58 100644 --- a/net/arp/arp_format.c +++ b/net/arp/arp_format.c @@ -62,18 +62,6 @@ #define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0]) #define ARPBUF ((struct arp_hdr_s *)&dev->d_buf[ETH_HDRLEN]) -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/arp/arp_ipin.c b/net/arp/arp_ipin.c index 558af73f3ae2b82aa8c797f439ee52ce9341f8f1..870e9a0a088e5c0e74f031c4286145214fc12cbb 100644 --- a/net/arp/arp_ipin.c +++ b/net/arp/arp_ipin.c @@ -59,18 +59,6 @@ #define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0]) #define IPBUF ((struct arp_iphdr_s *)&dev->d_buf[ETH_HDRLEN]) -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -101,7 +89,7 @@ void arp_ipin(FAR struct net_driver_s *dev) srcipaddr = net_ip4addr_conv32(IPBUF->eh_srcipaddr); if (net_ipv4addr_maskcmp(srcipaddr, dev->d_ipaddr, dev->d_netmask)) { - arp_update(IPBUF->eh_srcipaddr, ETHBUF->src); + arp_hdr_update(IPBUF->eh_srcipaddr, ETHBUF->src); } } diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index e5a1559502b9ee5aa8c81cba3020c252c34251a6..727d765651ca425b4f201f884a4ccc1c7d063c89 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -48,20 +48,12 @@ #include #include -#include +#include #include "arp/arp.h" #ifdef CONFIG_NET_ARP_SEND -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -70,10 +62,6 @@ static FAR struct arp_notify_s *g_arp_waiters; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -104,10 +92,10 @@ void arp_wait_setup(in_addr_t ipaddr, FAR struct arp_notify_s *notify) /* Add the wait structure to the list with interrupts disabled */ - flags = irqsave(); + flags = enter_critical_section(); notify->nt_flink = g_arp_waiters; g_arp_waiters = notify; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -134,7 +122,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) * head of the list). */ - flags = irqsave(); + flags = enter_critical_section(); for (prev = NULL, curr = g_arp_waiters; curr && curr != notify; prev = curr, curr = curr->nt_flink); @@ -154,7 +142,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); (void)sem_destroy(¬ify->nt_sem); return ret; } @@ -184,7 +172,7 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) * enabled while we wait. */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); abstime.tv_sec += timeout->tv_sec; @@ -220,7 +208,7 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) /* Re-enable interrupts and return the result of the wait */ - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index a50e9dee68347ad2478bfcf4770518f3d602861e..563d601337d5e67eb193964c5f61b4c6ae900ae7 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -62,10 +62,6 @@ #define ARPBUF ((struct arp_hdr_s *)&dev->d_buf[ETH_HDRLEN]) #define IPBUF ((struct arp_iphdr_s *)&dev->d_buf[ETH_HDRLEN]) -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -73,8 +69,16 @@ /* Support for broadcast address */ static const struct ether_addr g_broadcast_ethaddr = - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; -static const uint16_t g_broadcast_ipaddr[2] = {0xffff, 0xffff}; +{ + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + } +}; + +static const uint16_t g_broadcast_ipaddr[2] = +{ + 0xffff, 0xffff +}; /* Support for IGMP multicast addresses. * @@ -93,13 +97,12 @@ static const uint16_t g_broadcast_ipaddr[2] = {0xffff, 0xffff}; */ #ifdef CONFIG_NET_IGMP -static const uint8_t g_multicast_ethaddr[3] = {0x01, 0x00, 0x5e}; +static const uint8_t g_multicast_ethaddr[3] = +{ + 0x01, 0x00, 0x5e +}; #endif -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -178,15 +181,15 @@ void arp_out(FAR struct net_driver_s *dev) * addresses=0xff (ff00::/8.) */ - else if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 && - NTOHS(pip->eh_destipaddr[0]) <= 0xefff) + else if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 && + NTOHS(pip->eh_destipaddr[0]) <= 0xefff) { /* Build the well-known IPv4 IGMP Ethernet address. The first * three bytes are fixed; the final three variable come from the * last three bytes of the IP address. */ - FAR const uint8_t *ip = ((uint8_t*)pip->eh_destipaddr) + 1; + FAR const uint8_t *ip = ((FAR uint8_t *)pip->eh_destipaddr) + 1; memcpy(peth->dest, g_multicast_ethaddr, 3); memcpy(&peth->dest[3], ip, 3); } diff --git a/net/arp/arp_poll.c b/net/arp/arp_poll.c index 85cc2b38c0f9f1ee3abc15341499b3c7d7e4a882..424d0fe2e79e3595107b403b6c739431b02eb3e0 100644 --- a/net/arp/arp_poll.c +++ b/net/arp/arp_poll.c @@ -48,14 +48,6 @@ #ifdef CONFIG_NET_ARP_SEND -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index fbb6bdd6aef665d23d86ae3a50c921fc18fba0b3..b6431582b1fd8fc805aace7c85851786cbc31553 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -69,14 +69,6 @@ #define CONFIG_ARP_SEND_DELAYNSEC \ ((CONFIG_ARP_SEND_DELAYMSEC - 1000*CONFIG_ARP_SEND_DELAYSEC) * 1000000) -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -221,7 +213,7 @@ int arp_send(in_addr_t ipaddr) * addresses=0xff (ff00::/8.) */ - if (NTOHL(ipaddr) >= 0xe0000000 && NTOHL(ipaddr) <= 0xefffffff) + if (NTOHL(ipaddr) >= 0xe0000000 && NTOHL(ipaddr) <= 0xefffffff) { /* We don't need to send the ARP request */ diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index a9e201c73384ecd62108758efdd0a43a171fd2e5..bdb27ad79dd9280f73ad680e1195be20cc851f65 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -62,14 +62,6 @@ #ifdef CONFIG_NET_ARP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -79,10 +71,6 @@ static struct arp_entry g_arptable[CONFIG_NET_ARPTAB_SIZE]; static uint8_t g_arptime; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -142,18 +130,21 @@ void arp_timer(void) * address of an existing association. * * Input parameters: - * pipaddr - Refers to an IP address uint16_t[2] + * ipaddr - The IP address as an inaddr_t * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] * + * Returned Value: + * Zero (OK) if the ARP table entry was successfully modified. A negated + * errno value is returned on any error. + * * Assumptions - * Interrupts are disabled + * The network is locked to assure exclusive access to the ARP table * ****************************************************************************/ -void arp_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) +int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr) { struct arp_entry *tabptr = NULL; - in_addr_t ipaddr = net_ip4addr_conv32(pipaddr); int i; /* Walk through the ARP mapping table and try to find an entry to @@ -179,13 +170,12 @@ void arp_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); tabptr->at_time = g_arptime; - return; + return OK; } } } /* If we get here, no existing ARP table entry was found, so we create one. */ - /* First, we try to find an unused entry in the ARP table. */ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) @@ -227,6 +217,36 @@ void arp_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) tabptr->at_ipaddr = ipaddr; memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); tabptr->at_time = g_arptime; + return OK; +} + +/**************************************************************************** + * Name: arp_hdr_update + * + * Description: + * Add the IP/HW address mapping to the ARP table -OR- change the IP + * address of an existing association. + * + * Input parameters: + * pipaddr - Refers to an IP address uint16_t[2] in network order + * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] + * + * Returned Value: + * Zero (OK) if the ARP table entry was successfully modified. A negated + * errno value is returned on any error. + * + * Assumptions + * The network is locked to assure exclusive access to the ARP table + * + ****************************************************************************/ + +void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr) +{ + in_addr_t ipaddr = net_ip4addr_conv32(pipaddr); + + /* Update the ARP table */ + + (void)arp_update(ipaddr, ethaddr); } /**************************************************************************** diff --git a/net/arp/arp_timer.c b/net/arp/arp_timer.c index c1b23c4bcd8ae7f84efa9f24469bf968412a68cd..cec202ae413122ab1884a3fcef19260112009776 100644 --- a/net/arp/arp_timer.c +++ b/net/arp/arp_timer.c @@ -88,7 +88,7 @@ static WDOG_ID g_arptimer; /* ARP timer */ * ****************************************************************************/ -static void arptimer_poll(int argc, uint32_t arg, ...) +static void arptimer_poll(int argc, wdparm_t arg, ...) { /* Call the ARP timer function every 10 seconds. */ @@ -126,7 +126,7 @@ void arp_timer_initialize(void) /* Create and start the ARP timer */ g_arptimer = wd_create(); - (void)wd_start(g_arptimer, ARPTIMER_WDINTERVAL, arptimer_poll, 0); + (void)wd_start(g_arptimer, ARPTIMER_WDINTERVAL, arptimer_poll, 0); } #endif /* CONFIG_NET_ARP */ diff --git a/net/devif/devif.h b/net/devif/devif.h index d4ecdd023f529c148fd2aaec08fe0bc16a06cd3d..2251ffcad0e00bfa8219a06d7ebdbc8a142e01d4 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/devif/devif.h * - * Copyright (C) 2007-2009, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This logic was leveraged from uIP which also has a BSD-style license: @@ -51,6 +51,7 @@ #include #include +#include #include /**************************************************************************** @@ -256,6 +257,10 @@ extern uint16_t g_ipid; extern uint8_t g_reassembly_timer; #endif +/* Time of last poll */ + +extern systime_t g_polltime; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -291,7 +296,7 @@ void devif_initialize(void); * Configure the pre-allocated callback structures into a free list. * * Assumptions: - * This function is called with interrupts disabled. + * This function must be called with the network locked. * ****************************************************************************/ @@ -309,7 +314,7 @@ void devif_callback_init(void); * callback. * * Assumptions: - * This function is called with the network locked. + * This function must be called with the network locked. * ****************************************************************************/ @@ -331,7 +336,7 @@ FAR struct devif_callback_s * * The callback structure will be freed in any event. * * Assumptions: - * This function is called with the network locked. + * This function must be called with the network locked. * ****************************************************************************/ @@ -355,7 +360,7 @@ void devif_conn_callback_free(FAR struct net_driver_s *dev, * The callback structure will be freed in any event. * * Assumptions: - * This function is called with the network locked. + * This function must be called with the network locked. * ****************************************************************************/ @@ -381,7 +386,7 @@ void devif_dev_callback_free(FAR struct net_driver_s *dev, * The updated flags as modified by the callback functions. * * Assumptions: - * This function is called with the network locked. + * This function must be called with the network locked. * ****************************************************************************/ @@ -406,7 +411,7 @@ uint16_t devif_conn_event(FAR struct net_driver_s *dev, FAR void *pvconn, * The updated flags as modified by the callback functions. * * Assumptions: - * This function is called with the network locked. + * This function must be called with the network locked. * ****************************************************************************/ @@ -423,8 +428,8 @@ uint16_t devif_dev_event(FAR struct net_driver_s *dev, void *pvconn, * The amount of data that actually is sent out after a call to this * function is determined by the maximum amount of data TCP allows. uIP * will automatically crop the data so that only the appropriate - * amount of data is sent. The function tcp_mss() can be used to query - * uIP for the amount of data that actually will be sent. + * amount of data is sent. The mss field of the TCP connection structure + * can be used to determine the amount of data that actually will be sent. * * Note: This function does not guarantee that the sent data will * arrive at the destination. If the data is lost in the network, the @@ -450,8 +455,7 @@ void devif_send(FAR struct net_driver_s *dev, FAR const void *buf, int len); * in an I/O buffer chain, rather than a flat buffer. * * Assumptions: - * Called from the interrupt level or, at a minimum, with interrupts - * disabled. + * This function must be called with the network locked. * ****************************************************************************/ @@ -473,8 +477,7 @@ void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf, * no header on the data. * * Assumptions: - * Called from the interrupt level or, at a minimum, with interrupts - * disabled. + * This function must be called with the network locked. * ****************************************************************************/ diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index a72b15b4bfdc6037bf64674949a38162699eef1a..fc89eaf7d593adb159ed83c8cf325d6ba4377922 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -226,7 +226,7 @@ FAR struct devif_callback_s * /* Add the newly allocated instance to the head of the device event * list. */ - + if (dev) { /* Verify that the device pointer is valid, i.e., that it still diff --git a/net/devif/devif_initialize.c b/net/devif/devif_initialize.c index 58fcd8cd03eb786dbaf767f0fb6480502a5aafe3..4142019e2c8e58146498f0a219a1dd9c080f4032 100644 --- a/net/devif/devif_initialize.c +++ b/net/devif/devif_initialize.c @@ -46,6 +46,7 @@ #include +#include #include #include @@ -56,7 +57,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* IP/TCP/UDP/ICMP statistics for all network interfaces */ @@ -139,14 +140,6 @@ const struct ether_addr g_ipv6_ethallrouters = /* All link local routers */ #endif /* CONFIG_NET_ICMPv6_AUTOCONF || CONFIG_NET_ICMPv6_ROUTER */ #endif /* CONFIG_NET_IPv4 */ -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -167,6 +160,10 @@ const struct ether_addr g_ipv6_ethallrouters = /* All link local routers */ void devif_initialize(void) { + /* Initialize the time of the last timer poll */ + + g_polltime = clock_systimer(); + /* Initialize callback support */ devif_callback_init(); diff --git a/net/devif/devif_iobsend.c b/net/devif/devif_iobsend.c index d05109f90fe973ca3be9b7985e27efe2736776ac..66194aca91684bf38ac2ed94c0ad527808f39972 100644 --- a/net/devif/devif_iobsend.c +++ b/net/devif/devif_iobsend.c @@ -65,7 +65,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -73,7 +73,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/net/devif/devif_pktsend.c b/net/devif/devif_pktsend.c index 8cfd091c0d896e5c0accda5cf630335c38f88356..7e6c83a2097673b24b31b27a033feae580781650 100644 --- a/net/devif/devif_pktsend.c +++ b/net/devif/devif_pktsend.c @@ -64,7 +64,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -72,7 +72,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c index 67f7e05c02f0baf12c0fee53b180aa6f884450d5..3ec68be4f394e36ec4550d4361b053040b62aeb5 100644 --- a/net/devif/devif_poll.c +++ b/net/devif/devif_poll.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/devif/devif_poll.c * - * Copyright (C) 2007-2010, 2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2012, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ #include +#include #include #include @@ -56,9 +57,13 @@ #include "igmp/igmp.h" /**************************************************************************** - * Private Data + * Public Data ****************************************************************************/ +/* Time of last poll */ + +systime_t g_polltime; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -258,12 +263,13 @@ static inline int devif_poll_tcp_connections(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_TCP static inline int devif_poll_tcp_timer(FAR struct net_driver_s *dev, - devif_poll_callback_t callback, int hsec) + devif_poll_callback_t callback, + int hsec) { FAR struct tcp_conn_s *conn = NULL; int bstop = 0; - /* Traverse all of the active TCP connections and perform the poll action */ + /* Traverse all of the active TCP connections and perform the poll action. */ while (!bstop && (conn = tcp_nextconn(conn))) { @@ -414,97 +420,69 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback) * ****************************************************************************/ -int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback, - int hsec) +int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback) { + systime_t now; + systime_t elapsed; int bstop = false; - /* Increment the timer used by the IP reassembly logic */ + /* Get the elapsed time since the last poll in units of half seconds + * (truncating). + */ -#if defined(CONFIG_NET_TCP_REASSEMBLY) && defined(CONFIG_NET_IPv4) - if (g_reassembly_timer != 0 && - g_reassembly_timer < CONFIG_NET_TCP_REASS_MAXAGE) - { - g_reassembly_timer += hsec; - } -#endif + now = clock_systimer(); + elapsed = now - g_polltime; -#ifdef CONFIG_NET_IPv6 - /* Perform ageing on the entries in the Neighbor Table */ + /* Process time-related events only when more than one half second elapses. */ - neighbor_periodic(); -#endif + if (elapsed >= TICK_PER_HSEC) + { + /* Calculate the elpased time in units of half seconds (truncating to + * number of whole half seconds). + */ - /* Traverse all of the active packet connections and perform the poll - * action. - */ + int hsec = (int)(elapsed / TICK_PER_HSEC); -#ifdef CONFIG_NET_ARP_SEND - /* Check for pending ARP requests */ + /* Update the current poll time (truncating to the last half second + * boundary to avoid error build-up). + */ - bstop = arp_poll(dev, callback); - if (!bstop) -#endif -#ifdef CONFIG_NET_PKT - { - /* Check for pending packet socket transfer */ + g_polltime += (TICK_PER_HSEC * (systime_t)hsec); - bstop = devif_poll_pkt_connections(dev, callback); - } + /* Perform periodic activitives that depend on hsec > 0 */ - if (!bstop) +#if defined(CONFIG_NET_TCP_REASSEMBLY) && defined(CONFIG_NET_IPv4) + /* Increment the timer used by the IP reassembly logic */ + + if (g_reassembly_timer != 0 && + g_reassembly_timer < CONFIG_NET_TCP_REASS_MAXAGE) + { + g_reassembly_timer += hsec; + } #endif -#ifdef CONFIG_NET_IGMP - { - /* Check for pending IGMP messages */ - bstop = devif_poll_igmp(dev, callback); - } +#ifdef CONFIG_NET_IPv6 + /* Perform aging on the entries in the Neighbor Table */ - if (!bstop) + neighbor_periodic(hsec); #endif + #ifdef CONFIG_NET_TCP - { /* Traverse all of the active TCP connections and perform the * timer action. */ bstop = devif_poll_tcp_timer(dev, callback, hsec); - } - - if (!bstop) -#endif -#ifdef CONFIG_NET_UDP - { - /* Traverse all of the allocated UDP connections and perform - * the timer action. - */ - - bstop = devif_poll_udp_connections(dev, callback); - } - - if (!bstop) #endif -#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) - { - /* Traverse all of the tasks waiting to send an ICMP ECHO request. */ - - bstop = devif_poll_icmp(dev, callback); } - if (!bstop) -#endif -#if defined(CONFIG_NET_ICMPv6) && defined(CONFIG_NET_ICMPv6_PING) - { - /* Traverse all of the tasks waiting to send an ICMP ECHO request. */ - - bstop = devif_poll_icmpv6(dev, callback); - } + /* If possible, continue with a normal poll checking for pending + * network driver actions. + */ if (!bstop) -#endif { - /* Nothing to do */ + bstop = devif_poll(dev, callback); } return bstop; diff --git a/net/devif/devif_send.c b/net/devif/devif_send.c index d2299ebdc5557546acdf40082bc559b80e868515..8bcfedb0b01b0340be6aa3325be09f3aad70493b 100644 --- a/net/devif/devif_send.c +++ b/net/devif/devif_send.c @@ -64,7 +64,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** @@ -72,7 +72,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c index 919471a3e557787155d9ea33b32f205902242af6..1b3caf5087fbaf336492876f6ca3b632e635bc4b 100644 --- a/net/devif/ipv4_input.c +++ b/net/devif/ipv4_input.c @@ -130,7 +130,9 @@ static uint8_t g_reassembly_buffer[TCP_REASS_BUFSIZE]; static uint8_t g_reassembly_bitmap[TCP_REASS_BUFSIZE / (8 * 8)]; static const uint8_t g_bitmap_bits[8] = - {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; +{ + 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 +}; static uint16_t g_reassembly_len; static uint8_t g_reassembly_flags; @@ -202,93 +204,97 @@ static uint8_t devif_reassembly(void) memcpy(&g_reassembly_buffer[IPv4_HDRLEN + offset], (char *)pbuf + (int)((pbuf->vhl & 0x0f) * 4), len); - /* Update the bitmap. */ - - if (offset / (8 * 8) == (offset + len) / (8 * 8)) - { - /* If the two endpoints are in the same byte, we only update that byte. */ - - g_reassembly_bitmap[offset / (8 * 8)] |= - g_bitmap_bits[(offset / 8 ) & 7] & ~g_bitmap_bits[((offset + len) / 8 ) & 7]; - - } - else - { - /* If the two endpoints are in different bytes, we update the bytes - * in the endpoints and fill the stuff inbetween with 0xff. - */ - - g_reassembly_bitmap[offset / (8 * 8)] |= g_bitmap_bits[(offset / 8 ) & 7]; - for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) - { - g_reassembly_bitmap[i] = 0xff; - } - - g_reassembly_bitmap[(offset + len) / (8 * 8)] |= - ~g_bitmap_bits[((offset + len) / 8 ) & 7]; - } - - /* If this fragment has the More Fragments flag set to zero, we know that - * this is the last fragment, so we can calculate the size of the entire - * packet. We also set the IP_REASS_FLAG_LASTFRAG flag to indicate that - * we have received the final fragment. - */ - - if ((pbuf->ipoffset[0] & IP_MF) == 0) - { - g_reassembly_flags |= TCP_REASS_LASTFRAG; - g_reassembly_len = offset + len; - } - - /* Finally, we check if we have a full packet in the buffer. We do this - * by checking if we have the last fragment and if all bits in the bitmap - * are set. - */ - - if (g_reassembly_flags & TCP_REASS_LASTFRAG) - { - /* Check all bytes up to and including all but the last byte in - * the bitmap. - */ - - for (i = 0; i < g_reassembly_len / (8 * 8) - 1; ++i) - { - if (g_reassembly_bitmap[i] != 0xff) - { - goto nullreturn; - } - } - - /* Check the last byte in the bitmap. It should contain just the - * right amount of bits. - */ - - if (g_reassembly_bitmap[g_reassembly_len / (8 * 8)] != (uint8_t)~g_bitmap_bits[g_reassembly_len / 8 & 7]) - { - goto nullreturn; - } - - /* If we have come this far, we have a full packet in the buffer, - * so we allocate a pbuf and copy the packet into it. We also reset - * the timer. - */ - - g_reassembly_timer = 0; - memcpy(pbuf, pfbuf, g_reassembly_len); - - /* Pretend to be a "normal" (i.e., not fragmented) IP packet from - * now on. - */ - - pbuf->ipoffset[0] = pbuf->ipoffset[1] = 0; - pbuf->len[0] = g_reassembly_len >> 8; - pbuf->len[1] = g_reassembly_len & 0xff; - pbuf->ipchksum = 0; - pbuf->ipchksum = ~(ipv4_chksum(dev)); - - return g_reassembly_len; - } - } + /* Update the bitmap. */ + + if (offset / (8 * 8) == (offset + len) / (8 * 8)) + { + /* If the two endpoints are in the same byte, we only update that byte. */ + + g_reassembly_bitmap[offset / (8 * 8)] |= + g_bitmap_bits[(offset / 8) & 7] & + ~g_bitmap_bits[((offset + len) / 8) & 7]; + + } + else + { + /* If the two endpoints are in different bytes, we update the bytes + * in the endpoints and fill the stuff inbetween with 0xff. + */ + + g_reassembly_bitmap[offset / (8 * 8)] |= + g_bitmap_bits[(offset / 8) & 7]; + + for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) + { + g_reassembly_bitmap[i] = 0xff; + } + + g_reassembly_bitmap[(offset + len) / (8 * 8)] |= + ~g_bitmap_bits[((offset + len) / 8) & 7]; + } + + /* If this fragment has the More Fragments flag set to zero, we know that + * this is the last fragment, so we can calculate the size of the entire + * packet. We also set the IP_REASS_FLAG_LASTFRAG flag to indicate that + * we have received the final fragment. + */ + + if ((pbuf->ipoffset[0] & IP_MF) == 0) + { + g_reassembly_flags |= TCP_REASS_LASTFRAG; + g_reassembly_len = offset + len; + } + + /* Finally, we check if we have a full packet in the buffer. We do this + * by checking if we have the last fragment and if all bits in the bitmap + * are set. + */ + + if (g_reassembly_flags & TCP_REASS_LASTFRAG) + { + /* Check all bytes up to and including all but the last byte in + * the bitmap. + */ + + for (i = 0; i < g_reassembly_len / (8 * 8) - 1; ++i) + { + if (g_reassembly_bitmap[i] != 0xff) + { + goto nullreturn; + } + } + + /* Check the last byte in the bitmap. It should contain just the + * right amount of bits. + */ + + if (g_reassembly_bitmap[g_reassembly_len / (8 * 8)] != + (uint8_t)~g_bitmap_bits[g_reassembly_len / 8 & 7]) + { + goto nullreturn; + } + + /* If we have come this far, we have a full packet in the buffer, + * so we allocate a pbuf and copy the packet into it. We also reset + * the timer. + */ + + g_reassembly_timer = 0; + memcpy(pbuf, pfbuf, g_reassembly_len); + + /* Pretend to be a "normal" (i.e., not fragmented) IP packet from + * now on. + */ + + pbuf->ipoffset[0] = pbuf->ipoffset[1] = 0; + pbuf->len[0] = g_reassembly_len >> 8; + pbuf->len[1] = g_reassembly_len & 0xff; + pbuf->ipchksum = 0; + pbuf->ipchksum = ~(ipv4_chksum(dev)); + + return g_reassembly_len; + } + } nullreturn: return 0; @@ -379,11 +385,11 @@ int ipv4_input(FAR struct net_driver_s *dev) } #if defined(CONFIG_NET_BROADCAST) && defined(CONFIG_NET_UDP) - /* If IP broadcast support is configured, we check for a broadcast - * UDP packet, which may be destined to us (even if there is no IP - * address yet assigned to the device as is the case when we are - * negotiating over DHCP for an address). - */ + /* If IP broadcast support is configured, we check for a broadcast + * UDP packet, which may be destined to us (even if there is no IP + * address yet assigned to the device as is the case when we are + * negotiating over DHCP for an address). + */ if (pbuf->proto == IP_PROTO_UDP && net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr), @@ -392,34 +398,15 @@ int ipv4_input(FAR struct net_driver_s *dev) return udp_ipv4_input(dev); } - /* In most other cases, the device must be assigned a non-zero IP - * address. Another exception is when CONFIG_NET_PINGADDRCONF is - * enabled... - */ + /* In other cases, the device must be assigned a non-zero IP address. */ else #endif #ifdef CONFIG_NET_ICMP if (net_ipv4addr_cmp(dev->d_ipaddr, INADDR_ANY)) { -#ifdef CONFIG_NET_PINGADDRCONF - /* If we are configured to use ping IP address configuration and - * hasn't been assigned an IP address yet, we accept all ICMP - * packets. - */ - - if (pbuf->proto == IP_PROTO_ICMP) - { - nlldbg("Possible ping config packet received\n"); - icmp_input(dev); - goto drop; - } - else -#endif - { - nlldbg("No IP address assigned\n"); - goto drop; - } + nlldbg("No IP address assigned\n"); + goto drop; } /* Check if the packet is destined for out IP address */ diff --git a/net/devif/ipv6_input.c b/net/devif/ipv6_input.c index 7b878ac4aba30beb570f3d73a28e6dd1f836ceca..f5be1751f0840ab4359414ce9c31d3b9e6954a92 100644 --- a/net/devif/ipv6_input.c +++ b/net/devif/ipv6_input.c @@ -191,11 +191,11 @@ int ipv6_input(FAR struct net_driver_s *dev) goto drop; } - /* If IP broadcast support is configured, we check for a broadcast - * UDP packet, which may be destined to us (even if there is no IP - * address yet assigned to the device as is the case when we are - * negotiating over DHCP for an address). - */ + /* If IP broadcast support is configured, we check for a broadcast + * UDP packet, which may be destined to us (even if there is no IP + * address yet assigned to the device as is the case when we are + * negotiating over DHCP for an address). + */ #if defined(CONFIG_NET_BROADCAST) && defined(CONFIG_NET_UDP) if (ipv6->proto == IP_PROTO_UDP && @@ -204,10 +204,7 @@ int ipv6_input(FAR struct net_driver_s *dev) return udp_ipv6_input(dev); } - /* In most other cases, the device must be assigned a non-zero IP - * address. Another exception is when CONFIG_NET_PINGADDRCONF is - * enabled... - */ + /* In other cases, the device must be assigned a non-zero IP address. */ else #endif diff --git a/net/icmp/Kconfig b/net/icmp/Kconfig index 7eb504267f3e9127138ced09e2ab748f790b638a..9f38cef29a8b2b57a3834f7f315a5a391d704f0d 100644 --- a/net/icmp/Kconfig +++ b/net/icmp/Kconfig @@ -18,15 +18,14 @@ if NET_ICMP config NET_ICMP_PING bool "ICMP ping interfaces" default n + depends on BUILD_FLAT ---help--- Provide interfaces to support application level support for for sending ECHO (ping) requests and associating ECHO replies. -config NET_PINGADDRCONF - bool "Ping address configuration" - default n - ---help--- - Use "ping" packet for setting IP address + NOTE: Calling these interfaces from application space is a + violation of the OS/application interface but for historical + reasons, is permitted in the flat build. endif # NET_ICMP endmenu # ICMP Networking Support diff --git a/net/icmp/icmp.h b/net/icmp/icmp.h index 3e55d4c51ac1d4b458b8ecddfb949060deb260a0..9750d88539bc5ad7bd6813eba7f18ca82c6f2fa1 100644 --- a/net/icmp/icmp.h +++ b/net/icmp/icmp.h @@ -48,14 +48,6 @@ #ifdef CONFIG_NET_ICMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Type Definitions - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/net/icmp/icmp_input.c b/net/icmp/icmp_input.c index 8afbc1e6f1babbdac1fddbd2de1154ea4eeef411..2d919b8f7634038a5a74a919a74b6a0df1fe0c76 100644 --- a/net/icmp/icmp_input.c +++ b/net/icmp/icmp_input.c @@ -68,18 +68,6 @@ #define ICMPBUF ((struct icmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -117,18 +105,6 @@ void icmp_input(FAR struct net_driver_s *dev) if (picmp->type == ICMP_ECHO_REQUEST) { - /* If we are configured to use ping IP address assignment, we use - * the destination IP address of this ping packet and assign it to - * ourself. - */ - -#ifdef CONFIG_NET_PINGADDRCONF - if (dev->d_ipaddr == 0) - { - dev->d_ipaddr = picmp->destipaddr; - } -#endif - /* Change the ICMP type */ picmp->type = ICMP_ECHO_REPLY; diff --git a/net/icmp/icmp_ping.c b/net/icmp/icmp_ping.c index d350d0c35cc4c96a86b3b9e25fa2486d2a4f8277..337968bf8435d4ba1ea587c2fafa41b7d39cab76 100644 --- a/net/icmp/icmp_ping.c +++ b/net/icmp/icmp_ping.c @@ -83,8 +83,8 @@ struct icmp_ping_s FAR struct devif_callback_s *png_cb; /* Reference to callback instance */ sem_t png_sem; /* Use to manage the wait for the response */ - uint32_t png_time; /* Start time for determining timeouts */ - uint32_t png_ticks; /* System clock ticks to wait */ + systime_t png_time; /* Start time for determining timeouts */ + systime_t png_ticks; /* System clock ticks to wait */ int png_result; /* 0: success; <0:negated errno on fail */ in_addr_t png_addr; /* The peer to be ping'ed */ uint16_t png_id; /* Used to match requests with replies */ @@ -93,14 +93,6 @@ struct icmp_ping_s bool png_sent; /* true... the PING request has been sent */ }; -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -124,7 +116,7 @@ struct icmp_ping_s static inline int ping_timeout(FAR struct icmp_ping_s *pstate) { - uint32_t elapsed = clock_systimer() - pstate->png_time; + systime_t elapsed = clock_systimer() - pstate->png_time; if (elapsed >= pstate->png_ticks) { return TRUE; @@ -345,7 +337,7 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen, #ifdef CONFIG_NET_ARP_SEND int ret; #endif - + /* Get the device that will be used to route this ICMP ECHO request */ #ifdef CONFIG_NETDEV_MULTINIC @@ -390,7 +382,7 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen, if (state.png_cb) { state.png_cb->flags = (ICMP_POLL | ICMP_ECHOREPLY | NETDEV_DOWN); - state.png_cb->priv = (void*)&state; + state.png_cb->priv = (FAR void *)&state; state.png_cb->event = ping_interrupt; state.png_result = -EINTR; /* Assume sem-wait interrupted by signal */ diff --git a/net/icmp/icmp_poll.c b/net/icmp/icmp_poll.c index 06ccb8cd198319a25020f13388b3ac3ff730f5fb..9a5eed1d08ced808c036b517dddc79a5ddaf0d5e 100644 --- a/net/icmp/icmp_poll.c +++ b/net/icmp/icmp_poll.c @@ -49,22 +49,6 @@ #include "devif/devif.h" #include "icmp/icmp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/icmp/icmp_send.c b/net/icmp/icmp_send.c index e96624274059817c81a65f51e2ad146a57b83a73..b92e992704dfa025e7ac66224e9326e2e2254cd9 100644 --- a/net/icmp/icmp_send.c +++ b/net/icmp/icmp_send.c @@ -59,18 +59,6 @@ #define ICMPBUF ((struct icmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/icmpv6/Kconfig b/net/icmpv6/Kconfig index d75172713dcba79856de3ab36388272902fe5fdf..62f4ca89437804fb54d80ada8bbf2ae40a36aa8a 100644 --- a/net/icmpv6/Kconfig +++ b/net/icmpv6/Kconfig @@ -19,10 +19,15 @@ if NET_ICMPv6 config NET_ICMPv6_PING bool "ICMPv6 ping interfaces" default n + depends on BUILD_FLAT ---help--- Provide interfaces to support application level support for for sending ECHO (ping) requests and associating ECHO replies. + NOTE: Calling these interfaces from application space is a + violation of the OS/application interface but for historical + reasons, is permitted in the flat build. + config NET_ICMPv6_NEIGHBOR bool "Solicit destination addresses" default n diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 051542ea57134ddad9dcc34542ceb65798d73047..7899f07451abd1e1df9582eafddc0dfa5f09d06a 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -301,9 +301,9 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev, ret = icmpv6_rwait(notify, &delay); - /* icmpv6_wait will return OK if and only if the matching Router - * Advertisement is received. Otherwise, it will return -ETIMEDOUT. - */ + /* icmpv6_wait will return OK if and only if the matching Router + * Advertisement is received. Otherwise, it will return -ETIMEDOUT. + */ return ret; } @@ -368,9 +368,9 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) /* The interface should be in the down state */ - save = net_lock(); - netdev_ifdown(dev); - net_unlock(save); + save = net_lock(); + netdev_ifdown(dev); + net_unlock(save); /* IPv6 Stateless Autoconfiguration * Reference: http://www.tcpipguide.com/free/t_IPv6AutoconfigurationandRenumbering.htm @@ -398,7 +398,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) */ lladdr[0] = HTONS(0xfe80); /* 10-bit address + 6 zeroes */ - memset(&lladdr[1], 0, 4* sizeof(uint16_t)); /* 64 more zeroes */ + memset(&lladdr[1], 0, 4 * sizeof(uint16_t)); /* 64 more zeroes */ memcpy(&lladdr[5], dev->d_mac.ether_addr_octet, sizeof(struct ether_addr)); /* 48-bit Ethernet address */ @@ -546,9 +546,9 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) * first step. */ - /* On success, the new address was already set (in icmpv_rnotify()). We - * need only to bring the network back to the up state and return success. - */ + /* On success, the new address was already set (in icmpv_rnotify()). We + * need only to bring the network back to the up state and return success. + */ netdev_ifup(dev); net_unlock(save); diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 2302b3b2a30fc28d6469f1a0157bf79c7bcf5458..4185b5a352575529ef51ea066ace1e21ccc34339 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -48,7 +48,7 @@ #include #include -#include +#include #include "icmpv6/icmpv6.h" @@ -105,10 +105,10 @@ void icmpv6_wait_setup(const net_ipv6addr_t ipaddr, /* Add the wait structure to the list with interrupts disabled */ - flags = irqsave(); + flags = enter_critical_section(); notify->nt_flink = g_icmpv6_waiters; g_icmpv6_waiters = notify; - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -136,7 +136,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * head of the list). */ - flags = irqsave(); + flags = enter_critical_section(); for (prev = NULL, curr = g_icmpv6_waiters; curr && curr != notify; prev = curr, curr = curr->nt_flink); @@ -156,7 +156,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); (void)sem_destroy(¬ify->nt_sem); return ret; } @@ -186,7 +186,7 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, * be re-enabled while we wait. */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); abstime.tv_sec += timeout->tv_sec; @@ -197,9 +197,9 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, abstime.tv_nsec -= 1000000000; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ + /* REVISIT: If net_timedwait() is awakened with signal, we will return + * the wrong error code. + */ (void)net_timedwait(¬ify->nt_sem, &abstime); ret = notify->nt_result; @@ -212,7 +212,7 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, /* Re-enable interrupts and return the result of the wait */ - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_ping.c b/net/icmpv6/icmpv6_ping.c index 333b708072ca5b030dcffc01a3444016ff553d8c..0e9ac3b691394d6903294e258f24054396bacc25 100644 --- a/net/icmpv6/icmpv6_ping.c +++ b/net/icmpv6/icmpv6_ping.c @@ -86,8 +86,8 @@ struct icmpv6_ping_s FAR struct devif_callback_s *png_cb; /* Reference to callback instance */ sem_t png_sem; /* Use to manage the wait for the response */ - uint32_t png_time; /* Start time for determining timeouts */ - uint32_t png_ticks; /* System clock ticks to wait */ + systime_t png_time; /* Start time for determining timeouts */ + systime_t png_ticks; /* System clock ticks to wait */ int png_result; /* 0: success; <0:negated errno on fail */ net_ipv6addr_t png_addr; /* The peer to be ping'ed */ uint16_t png_id; /* Used to match requests with replies */ @@ -97,11 +97,11 @@ struct icmpv6_ping_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -127,7 +127,7 @@ struct icmpv6_ping_s static inline int ping_timeout(FAR struct icmpv6_ping_s *pstate) { - uint32_t elapsed = clock_systimer() - pstate->png_time; + systime_t elapsed = clock_systimer() - pstate->png_time; if (elapsed >= pstate->png_ticks) { return TRUE; @@ -456,7 +456,7 @@ int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno, if (state.png_cb) { state.png_cb->flags = (ICMPv6_POLL | ICMPv6_ECHOREPLY); - state.png_cb->priv = (void*)&state; + state.png_cb->priv = (FAR void *)&state; state.png_cb->event = ping_interrupt; state.png_result = -EINTR; /* Assume sem-wait interrupted by signal */ diff --git a/net/icmpv6/icmpv6_poll.c b/net/icmpv6/icmpv6_poll.c index a87f42161c5c242bb77b9dfb82d1b43657d17164..6cf00532fbbe48b20e92893282c0a38a5fec2404 100644 --- a/net/icmpv6/icmpv6_poll.c +++ b/net/icmpv6/icmpv6_poll.c @@ -55,11 +55,11 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index 9a1767719755ca193e8d4124c206ebad6ff9a62e..c8e38e3d633ace937592451789ba698b1f15bb42 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -49,7 +49,7 @@ #include #include -#include +#include #include "netdev/netdev.h" #include "utils/utils.h" @@ -170,10 +170,10 @@ void icmpv6_rwait_setup(FAR struct net_driver_s *dev, /* Add the wait structure to the list with interrupts disabled */ - flags = irqsave(); + flags = enter_critical_section(); notify->rn_flink = g_icmpv6_rwaiters; g_icmpv6_rwaiters = notify; - irqrestore(flags); + leave_critical_section(flags); #else /* If there is only a single network device, then there can be only a @@ -218,7 +218,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) * head of the list). */ - flags = irqsave(); + flags = enter_critical_section(); for (prev = NULL, curr = g_icmpv6_rwaiters; curr && curr != notify; prev = curr, curr = curr->rn_flink); @@ -238,7 +238,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); (void)sem_destroy(¬ify->rn_sem); return ret; @@ -282,7 +282,7 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, * be re-enabled while we wait. */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); abstime.tv_sec += timeout->tv_sec; @@ -293,9 +293,9 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, abstime.tv_nsec -= 1000000000; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ + /* REVISIT: If net_timedwait() is awakened with signal, we will return + * the wrong error code. + */ (void)net_timedwait(¬ify->rn_sem, &abstime); ret = notify->rn_result; @@ -308,7 +308,7 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, /* Re-enable interrupts and return the result of the wait */ - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_solicit.c b/net/icmpv6/icmpv6_solicit.c index 05486200209be50fd2b6ef349446bc963f1837c2..7e84ccf7d50160d6b0e65ec10e1a431f4896882a 100644 --- a/net/icmpv6/icmpv6_solicit.c +++ b/net/icmpv6/icmpv6_solicit.c @@ -126,7 +126,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev, icmp->destipaddr[7] = ipaddr[7]; /* Add out IPv6 address as the source address */ - + net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr); /* Set up the ICMPv6 Neighbor Solicitation message */ @@ -174,7 +174,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev, * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map * to the Ethernet MAC address 33:33:00:01:00:03. - * + * * NOTES: This appears correct for the ICMPv6 Router Solicitation * Message, but the ICMPv6 Neighbor Solicitation message seems to * use 33:33:ff:01:00:03. diff --git a/net/igmp/igmp.h b/net/igmp/igmp.h index ae785e5af74f617c92514881b576edcf711876f2..5af1594a2e1212331b1181652e9e78fe2bbaf589 100644 --- a/net/igmp/igmp.h +++ b/net/igmp/igmp.h @@ -81,10 +81,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Type Definitions ****************************************************************************/ diff --git a/net/igmp/igmp_group.c b/net/igmp/igmp_group.c index 3f33207f97d05d6099008b52e30c32187286b163..92b34427b40636263d9a9d7b729f233c502f188f 100644 --- a/net/igmp/igmp_group.c +++ b/net/igmp/igmp_group.c @@ -126,10 +126,6 @@ static struct igmp_group_s g_preallocgrps[CONFIG_PREALLOC_IGMPGROUPS]; static FAR sq_queue_t g_freelist; #endif -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -265,7 +261,7 @@ FAR struct igmp_group_s *igmp_grpalloc(FAR struct net_driver_s *dev, /* Add the group structure to the list in the device structure */ - sq_addfirst((FAR sq_entry_t*)group, &dev->grplist); + sq_addfirst((FAR sq_entry_t *)group, &dev->grplist); net_unlock(flags); } @@ -363,7 +359,7 @@ void igmp_grpfree(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group) /* Remove the group structure from the group list in the device structure */ - sq_rem((FAR sq_entry_t*)group, &dev->grplist); + sq_rem((FAR sq_entry_t *)group, &dev->grplist); /* Destroy the wait semaphore */ @@ -381,7 +377,7 @@ void igmp_grpfree(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group) if (IS_PREALLOCATED(group->flags)) { grplldbg("Put back on free list\n"); - sq_addlast((FAR sq_entry_t*)group, &g_freelist); + sq_addlast((FAR sq_entry_t *)group, &g_freelist); net_unlock(flags); } else diff --git a/net/igmp/igmp_input.c b/net/igmp/igmp_input.c index f2f7363d7f763630ec8040fefb160dffcb3595b4..c2b3c870a38d04bc520f2f105e0ee285dd4af7f7 100644 --- a/net/igmp/igmp_input.c +++ b/net/igmp/igmp_input.c @@ -64,10 +64,6 @@ #define IGMPBUF ((struct igmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -134,14 +130,14 @@ void igmp_input(struct net_driver_s *dev) /* Calculate and check the IGMP checksum */ - if (net_chksum((uint16_t*)&IGMPBUF->type, IGMP_HDRLEN) != 0) + if (net_chksum((FAR uint16_t *)&IGMPBUF->type, IGMP_HDRLEN) != 0) { IGMP_STATINCR(g_netstats.igmp.chksum_errors); nlldbg("Checksum error\n"); return; } - /* Find the group (or create a new one) using the incoming IP address*/ + /* Find the group (or create a new one) using the incoming IP address */ destipaddr = net_ip4addr_conv32(IGMPBUF->destipaddr); group = igmp_grpallocfind(dev, &destipaddr); diff --git a/net/igmp/igmp_join.c b/net/igmp/igmp_join.c index 2eb454d1dc68df9ddac412eca6cf48e9442e55a2..83ef65a0f88eea2a6be6317a1aa0c25ead652934 100644 --- a/net/igmp/igmp_join.c +++ b/net/igmp/igmp_join.c @@ -58,14 +58,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/igmp/igmp_leave.c b/net/igmp/igmp_leave.c index 20a36ef004b8c725c2756f68b2fdbd2f5ef07848..4035358e8f6e767ab544482f6c32f4a5d91d937f 100644 --- a/net/igmp/igmp_leave.c +++ b/net/igmp/igmp_leave.c @@ -60,14 +60,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/igmp/igmp_mcastmac.c b/net/igmp/igmp_mcastmac.c index ceee9101bff5bb2663fdca867dd36d933b287832..2172a281ec9b89ac6b47b91a9bbc5fb56d83107d 100644 --- a/net/igmp/igmp_mcastmac.c +++ b/net/igmp/igmp_mcastmac.c @@ -55,10 +55,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/net/igmp/igmp_msg.c b/net/igmp/igmp_msg.c index d680541d95ddf96307164c1a28b506a675832b3f..3fd56fc3814ddb19d870191df5f742437a7e9c9b 100644 --- a/net/igmp/igmp_msg.c +++ b/net/igmp/igmp_msg.c @@ -55,14 +55,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/igmp/igmp_poll.c b/net/igmp/igmp_poll.c index 6beb8a31e61e4c31906839edd5d019c640fbb43f..e7dfd1068399b0dcfcb95c2ef596e48c110db9b5 100644 --- a/net/igmp/igmp_poll.c +++ b/net/igmp/igmp_poll.c @@ -56,10 +56,6 @@ #ifdef CONFIG_NET_IGMP -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/net/igmp/igmp_send.c b/net/igmp/igmp_send.c index ad1fe8f8e67747f538679593ecc7f6dc0352c103..d40301495a0b73e91bc8a42220aca43c4f006142 100644 --- a/net/igmp/igmp_send.c +++ b/net/igmp/igmp_send.c @@ -78,21 +78,13 @@ #define RASIZE (4) #define IGMPBUF ((struct igmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen) { - uint16_t sum = net_chksum((FAR uint16_t*)buffer, buflen); + uint16_t sum = net_chksum((FAR uint16_t *)buffer, buflen); return sum ? sum : 0xffff; } diff --git a/net/iob/iob.h b/net/iob/iob.h index 49222bec4eab0417dbe5c1624aef064f523f4848..cbef08ddc0fc5e105477e2c8ec08ca7e13e271e0 100644 --- a/net/iob/iob.h +++ b/net/iob/iob.h @@ -46,13 +46,7 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ +#ifdef CONFIG_NET_IOB /**************************************************************************** * Public Data @@ -78,10 +72,6 @@ extern sem_t g_throttle_sem; /* Counts available I/O buffers when throttled */ extern sem_t g_qentry_sem; /* Counts free I/O buffer queue containers */ #endif -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -132,4 +122,5 @@ FAR struct iob_s *iob_tryalloc(bool throttled); FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq); +#endif /* CONFIG_NET_IOB */ #endif /* __NET_IOB_IOB_H */ diff --git a/net/iob/iob_add_queue.c b/net/iob/iob_add_queue.c index c3da0dd68fa6a6f93e228c35ef32eb37a9597260..bc7e0adb8e48442d9dcdb199d9fbd349bd41bf47 100644 --- a/net/iob/iob_add_queue.c +++ b/net/iob/iob_add_queue.c @@ -150,7 +150,7 @@ int iob_tryadd_queue(FAR struct iob_s *iob, FAR struct iob_queue_s *iobq) qentry = iob_tryalloc_qentry(); if (!qentry) { - ndbg("ERROR: Failed to allocate a container\n"); + nlldbg("ERROR: Failed to allocate a container\n"); return -ENOMEM; } diff --git a/net/iob/iob_alloc.c b/net/iob/iob_alloc.c index 9fd2c0e13ea6e111640a8f9355a6b43916582cf0..e5483a2c3e68365caf75ba1a58f954e9316faaee 100644 --- a/net/iob/iob_alloc.c +++ b/net/iob/iob_alloc.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/iob/iob_alloc.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,28 +48,14 @@ #include #include +#include +#include #include #include #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -104,7 +90,7 @@ static FAR struct iob_s *iob_allocwait(bool throttled) * we are waiting for I/O buffers to become free. */ - flags = irqsave(); + flags = enter_critical_section(); do { /* Try to get an I/O buffer. If successful, the semaphore count @@ -121,18 +107,59 @@ static FAR struct iob_s *iob_allocwait(bool throttled) */ ret = sem_wait(sem); - - /* When we wake up from wait, an I/O buffer was returned to - * the free list. However, if there are concurrent allocations - * from interrupt handling, then I suspect that there is a - * race condition. But no harm, we will just wait again in - * that case. - */ + if (ret < 0) + { + int errcode = get_errno(); + + /* EINTR is not an error! EINTR simply means that we were + * awakened by a signal and we should try again. + * + * REVISIT: Many end-user interfaces are required to return + * with an error if EINTR is set. Most uses of this function + * is in internal, non-user logic. But are there cases where + * the error should be returned. + */ + + if (errcode == EINTR) + { + /* Force a success indication so that we will continue + * looping. + */ + + ret = 0; + } + else + { + /* Stop the loop and return a error */ + + DEBUGASSERT(errcode > 0); + ret = -errcode; + } + } + else + { + /* When we wake up from wait successfully, an I/O buffer was + * returned to the free list. However, if there are concurrent + * allocations from interrupt handling, then I suspect that + * there is a race condition. But no harm, we will just wait + * again in that case. + * + * We need release our count so that it is available to + * iob_tryalloc(), perhaps allowing another thread to take our + * count. In that event, iob_tryalloc() will fail above and + * we will have to wait again. + * + * TODO: Consider a design modification to permit us to + * complete the allocation without losing our count. + */ + + sem_post(sem); + } } } - while (ret == OK && !iob); + while (ret == OK && iob == NULL); - irqrestore(flags); + leave_critical_section(flags); return iob; } @@ -193,7 +220,7 @@ FAR struct iob_s *iob_tryalloc(bool throttled) * to protect the free list: We disable interrupts very briefly. */ - flags = irqsave(); + flags = enter_critical_section(); #if CONFIG_IOB_THROTTLE > 0 /* If there are free I/O buffers for this allocation */ @@ -231,7 +258,7 @@ FAR struct iob_s *iob_tryalloc(bool throttled) g_throttle_sem.semcount--; DEBUGASSERT(g_throttle_sem.semcount >= -CONFIG_IOB_THROTTLE); #endif - irqrestore(flags); + leave_critical_section(flags); /* Put the I/O buffer in a known state */ @@ -243,6 +270,6 @@ FAR struct iob_s *iob_tryalloc(bool throttled) } } - irqrestore(flags); + leave_critical_section(flags); return NULL; } diff --git a/net/iob/iob_alloc_qentry.c b/net/iob/iob_alloc_qentry.c index 64efefa93d9fc2417a578b552b84cd326ecfc639..c1a9f54a97364ee13a59d32490472c88746904c9 100644 --- a/net/iob/iob_alloc_qentry.c +++ b/net/iob/iob_alloc_qentry.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/iob/iob_alloc_qentry.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,7 +48,9 @@ #include #include +#include +#include #include #include @@ -56,22 +58,6 @@ #if CONFIG_IOB_NCHAINS > 0 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -98,7 +84,7 @@ static FAR struct iob_qentry_s *iob_allocwait_qentry(void) * re-enabled while we are waiting for I/O buffers to become free. */ - flags = irqsave(); + flags = enter_critical_section(); do { /* Try to get an I/O buffer chain container. If successful, the @@ -115,18 +101,59 @@ static FAR struct iob_qentry_s *iob_allocwait_qentry(void) */ ret = sem_wait(&g_qentry_sem); - - /* When we wake up from wait, an I/O buffer chain container was - * returned to the free list. However, if there are concurrent - * allocations from interrupt handling, then I suspect that there - * is a race condition. But no harm, we will just wait again in - * that case. - */ + if (ret < 0) + { + int errcode = get_errno(); + + /* EINTR is not an error! EINTR simply means that we were + * awakened by a signal and we should try again. + * + * REVISIT: Many end-user interfaces are required to return + * with an error if EINTR is set. Most uses of this function + * is in internal, non-user logic. But are there cases where + * the error should be returned. + */ + + if (errcode == EINTR) + { + /* Force a success indication so that we will continue + * looping. + */ + + ret = 0; + } + else + { + /* Stop the loop and return a error */ + + DEBUGASSERT(errcode > 0); + ret = -errcode; + } + } + else + { + /* When we wake up from wait successfully, an I/O buffer chain + * container was returned to the free list. However, if there + * are concurrent allocations from interrupt handling, then I + * suspect that there is a race condition. But no harm, we + * will just wait again in that case. + * + * We need release our count so that it is available to + * iob_tryalloc_qentry(), perhaps allowing another thread to + * take our count. In that event, iob_tryalloc_qentry() will + * fail above and we will have to wait again. + * + * TODO: Consider a design modification to permit us to + * complete the allocation without losing our count. + */ + + sem_post(&g_qentry_sem); + } } } while (ret == OK && !qentry); - irqrestore(flags); + leave_critical_section(flags); return qentry; } @@ -181,7 +208,7 @@ FAR struct iob_qentry_s *iob_tryalloc_qentry(void) * to protect the free list: We disable interrupts very briefly. */ - flags = irqsave(); + flags = enter_critical_section(); iobq = g_iob_freeqlist; if (iobq) { @@ -207,7 +234,7 @@ FAR struct iob_qentry_s *iob_tryalloc_qentry(void) iobq->qe_head = NULL; /* Nothing is contained */ } - irqrestore(flags); + leave_critical_section(flags); return iobq; } diff --git a/net/iob/iob_clone.c b/net/iob/iob_clone.c index 1162b87dd8276932f8cf3b2a567abb548c43b0e6..db29abde2421070e35d869a3d9c312b23c6ebe01 100644 --- a/net/iob/iob_clone.c +++ b/net/iob/iob_clone.c @@ -63,18 +63,6 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_concat.c b/net/iob/iob_concat.c index ecaa33b87eb464d45c372e512e9d9385ada09d2f..b543d63e6cc55915d882e54b5171a2eb8d86e896 100644 --- a/net/iob/iob_concat.c +++ b/net/iob/iob_concat.c @@ -52,22 +52,6 @@ #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -83,7 +67,7 @@ void iob_concat(FAR struct iob_s *iob1, FAR struct iob_s *iob2) { /* Find the last buffer in the iob1 buffer chain */ - + while (iob1->io_flink) { iob1 = iob1->io_flink; diff --git a/net/iob/iob_contig.c b/net/iob/iob_contig.c index 9c3a6306ba549afffd8c856ed6e0d904790e6e7b..749e72a0c76399def0fd298bb9803ec905524ec0 100644 --- a/net/iob/iob_contig.c +++ b/net/iob/iob_contig.c @@ -63,18 +63,6 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_copyin.c b/net/iob/iob_copyin.c index 924c0a6459e1dc5a257f80d5e81bb5db073150ad..c5030c91c56dc28762dea1348dbbbde9196de1ae 100644 --- a/net/iob/iob_copyin.c +++ b/net/iob/iob_copyin.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/iob/iob_copyin.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -70,14 +70,6 @@ typedef CODE struct iob_s *(*iob_alloc_t)(bool throttled); -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -89,17 +81,21 @@ typedef CODE struct iob_s *(*iob_alloc_t)(bool throttled); * Copy data 'len' bytes from a user buffer into the I/O buffer chain, * starting at 'offset', extending the chain as necessary. * + * Returned Value: + * The number of uncopied bytes left if >= 0 OR a negative error code. + * ****************************************************************************/ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src, unsigned int len, unsigned int offset, - bool throttled, iob_alloc_t allocator) + bool throttled, bool can_block) { FAR struct iob_s *head = iob; FAR struct iob_s *next; FAR uint8_t *dest; unsigned int ncopy; unsigned int avail; + unsigned int total = len; nllvdbg("iob=%p len=%u offset=%u\n", iob, len, offset); DEBUGASSERT(iob && src); @@ -207,13 +203,25 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src, if (len > 0 && !next) { - /* Yes.. allocate a new buffer */ + /* Yes.. allocate a new buffer. + * + * Copy as many bytes as possible. If we have successfully copied + * any already don't block, otherwise block if we're allowed. + */ + + if (!can_block || len < total) + { + next = iob_tryalloc(throttled); + } + else + { + next = iob_alloc(throttled); + } - next = allocator(throttled); if (next == NULL) { ndbg("ERROR: Failed to allocate I/O buffer\n"); - return -ENOMEM; + return len; } /* Add the new, empty I/O buffer to the end of the buffer chain. */ @@ -226,7 +234,7 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src, offset = 0; } - return OK; + return 0; } /**************************************************************************** @@ -245,7 +253,7 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src, int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src, unsigned int len, unsigned int offset, bool throttled) { - return iob_copyin_internal(iob, src, len, offset, throttled, iob_alloc); + return len - iob_copyin_internal(iob, src, len, offset, throttled, true); } /**************************************************************************** @@ -261,6 +269,12 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src, int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src, unsigned int len, unsigned int offset, bool throttled) { - return iob_copyin_internal(iob, src, len, offset, throttled, iob_tryalloc); + if (iob_copyin_internal(iob, src, len, offset, throttled, false) == 0) + { + return OK; + } + else + { + return -ENOMEM; + } } - diff --git a/net/iob/iob_copyout.c b/net/iob/iob_copyout.c index 300b63df81f5acb54387eff0ab8e45e592545166..2cb0a10be6248f0176cc0f52d17c1fdc07c1ca98 100644 --- a/net/iob/iob_copyout.c +++ b/net/iob/iob_copyout.c @@ -62,18 +62,6 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -101,6 +89,12 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob, { offset -= iob->io_len; iob = iob->io_flink; + if (iob == NULL) + { + /* We have no requested data in iob chain */ + + return 0; + } } /* Then loop until all of the I/O data is copied to the user buffer */ diff --git a/net/iob/iob_dump.c b/net/iob/iob_dump.c index c9ffc7f4ab5643dad7c836da6727e0e4dc18b0e8..a34dc1ca2aea3510598eb983c90560501dc6319a 100644 --- a/net/iob/iob_dump.c +++ b/net/iob/iob_dump.c @@ -50,7 +50,7 @@ * Pre-processor definitions ****************************************************************************/ - #ifndef MIN +#ifndef MIN # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif diff --git a/net/iob/iob_free.c b/net/iob/iob_free.c index 984287600d92d49efd3f704f9beeee50604b4a9a..53d8f6fb1de636d35f45031bb852da29adf2a3ba 100644 --- a/net/iob/iob_free.c +++ b/net/iob/iob_free.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/iob/iob_free.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,27 +50,12 @@ #include #include +#include #include #include #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -128,7 +113,7 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) * protect the free list: We disable interrupts very briefly. */ - flags = irqsave(); + flags = enter_critical_section(); iob->io_flink = g_iob_freelist; g_iob_freelist = iob; @@ -138,7 +123,7 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) #if CONFIG_IOB_THROTTLE > 0 sem_post(&g_throttle_sem); #endif - irqrestore(flags); + leave_critical_section(flags); /* And return the I/O buffer after the one that was freed */ diff --git a/net/iob/iob_free_chain.c b/net/iob/iob_free_chain.c index 2534bde100668bf77866c489f02b1f0ccba4a089..810622e8288ff9c9c098325a2a734dcb402de729 100644 --- a/net/iob/iob_free_chain.c +++ b/net/iob/iob_free_chain.c @@ -51,22 +51,6 @@ #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_free_qentry.c b/net/iob/iob_free_qentry.c index f93f16f8f6323ca839912a2f0ad450dfb1e9d2d6..e663d8a2ea2baf75e6c675463a8b18f1c0e9f56c 100644 --- a/net/iob/iob_free_qentry.c +++ b/net/iob/iob_free_qentry.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/iob/iob_free_qentry.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -56,22 +57,6 @@ #if CONFIG_IOB_NCHAINS > 0 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -95,14 +80,14 @@ FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq) * measures to protect the free list: We disable interrupts very briefly. */ - flags = irqsave(); + flags = enter_critical_section(); iobq->qe_flink = g_iob_freeqlist; g_iob_freeqlist = iobq; /* Signal that an I/O buffer chain container is available */ sem_post(&g_qentry_sem); - irqrestore(flags); + leave_critical_section(flags); /* And return the I/O buffer chain container after the one that was freed */ diff --git a/net/iob/iob_free_queue.c b/net/iob/iob_free_queue.c index cf7ffff0c411dad16e32fb2f7668a23ca032cc85..91ded4f42c4b23ee2e9dfaf25a82f52ecd0f3a7d 100644 --- a/net/iob/iob_free_queue.c +++ b/net/iob/iob_free_queue.c @@ -58,22 +58,10 @@ * Pre-processor Definitions ****************************************************************************/ -/**************************************************************************** - * Private Types - ****************************************************************************/ - #ifndef NULL # define NULL ((FAR void *)0) #endif -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_initialize.c b/net/iob/iob_initialize.c index 647eb0649c922d77351bdaeff9292236b363d972..d63d957219fcd4c90fe99c4208d796784d9557bc 100644 --- a/net/iob/iob_initialize.c +++ b/net/iob/iob_initialize.c @@ -53,14 +53,6 @@ #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ diff --git a/net/iob/iob_pack.c b/net/iob/iob_pack.c index 4765e8e594aa65cbb996377f21ef87ff7bb1cab2..660b31d4a85e33449966cb437ff2f27233eca609 100644 --- a/net/iob/iob_pack.c +++ b/net/iob/iob_pack.c @@ -60,18 +60,6 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_test.c b/net/iob/iob_test.c index 5c58852cff15f6be69fb3b1580d87502a548f9b8..0e13fab793cc6209fbb15390116ab46749013646 100644 --- a/net/iob/iob_test.c +++ b/net/iob/iob_test.c @@ -49,24 +49,12 @@ #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ -uint8_t buffer1[16384]; -uint8_t buffer2[16384]; - -/**************************************************************************** - * Public Data - ****************************************************************************/ +static uint8_t buffer1[16384]; +static uint8_t buffer2[16384]; /**************************************************************************** * Private Functions @@ -77,7 +65,7 @@ static void dump_chain(struct iob_s *iob) struct iob_s *head = iob; unsigned int pktlen; int n; - + printf("=========================================================\n"); printf("pktlen: %d\n", iob->io_pktlen); @@ -199,10 +187,10 @@ int main(int argc, char **argv) void my_assert(bool value) { - if (!value) - { - fprintf(stderr, "Assertion failed\n"); + if (!value) + { + fprintf(stderr, "Assertion failed\n"); - abort(); - } + abort(); + } } diff --git a/net/iob/iob_trimhead.c b/net/iob/iob_trimhead.c index ffb1bc8b731dde349860f107ef897dd1f8bf03cf..70a5359603f09aceaae1fc8e6a0867ded4e306ae 100644 --- a/net/iob/iob_trimhead.c +++ b/net/iob/iob_trimhead.c @@ -61,18 +61,6 @@ # define NULL ((FAR void *)0) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_trimhead_queue.c b/net/iob/iob_trimhead_queue.c index 9315b8d3fe707cc28cc8565702fa73bd8874d43e..24b98783215e6292f54bc606591f642282b48163 100644 --- a/net/iob/iob_trimhead_queue.c +++ b/net/iob/iob_trimhead_queue.c @@ -63,18 +63,6 @@ # define NULL ((FAR void *)0) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/iob/iob_trimtail.c b/net/iob/iob_trimtail.c index 36eebb26f8111570841c58d7c220c1ab704dc1fd..6965fe3da5f1c7bc05513fb5dd35440f26b2420e 100644 --- a/net/iob/iob_trimtail.c +++ b/net/iob/iob_trimtail.c @@ -53,22 +53,6 @@ #include "iob.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -143,7 +127,7 @@ FAR struct iob_s *iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen) penultimate->io_flink = NULL; } - + else { /* No, then just take what we need from this I/O buffer and diff --git a/net/local/local_accept.c b/net/local/local_accept.c index 0c393dcf210fd4128dea1434ef9cae136827ecd0..d26fc74813d920caed5cbd35f5f313527ea02437 100644 --- a/net/local/local_accept.c +++ b/net/local/local_accept.c @@ -133,7 +133,7 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr, /* Loop as necessary if we have to wait for a connection */ - for (;;) + for (; ; ) { /* Are there pending connections. Remove the client from the * head of the waiting list. diff --git a/net/local/local_conn.c b/net/local/local_conn.c index c45b49832f66b8ce6d441024cf7599b568a97666..a369f04b7cb08d0cc7d5c19a0c6b589b4d4b3d71 100644 --- a/net/local/local_conn.c +++ b/net/local/local_conn.c @@ -64,7 +64,7 @@ * ****************************************************************************/ - void local_initialize(void) +void local_initialize(void) { #ifdef CONFIG_NET_LOCAL_STREAM dq_init(&g_local_listeners); diff --git a/net/local/local_connect.c b/net/local/local_connect.c index 99ea989edfa7a89113af19a780e8fe23c13c78ff..1eab7220835e9c4a35b9b1306876d8b430227665 100644 --- a/net/local/local_connect.c +++ b/net/local/local_connect.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/local/local_connnect.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -97,7 +97,7 @@ static inline void _local_semtake(sem_t *sem) * the wait was awakened by a signal. */ - ASSERT(*get_errno_ptr() == EINTR); + DEBUGASSERT(get_errno() == EINTR); } } @@ -143,7 +143,7 @@ int inline local_stream_connect(FAR struct local_conn_s *client, return -ECONNREFUSED; } - /* Increment the number of pending server connection s*/ + /* Increment the number of pending server connection s */ server->u.server.lc_pending++; DEBUGASSERT(server->u.server.lc_pending != 0); @@ -271,7 +271,7 @@ int psock_local_connect(FAR struct socket *psock, /* Find the matching server connection */ state = net_lock(); - for(conn = (FAR struct local_conn_s *)g_local_listeners.head; + for (conn = (FAR struct local_conn_s *)g_local_listeners.head; conn; conn = (FAR struct local_conn_s *)dq_next(&conn->lc_node)) { diff --git a/net/local/local_recvfrom.c b/net/local/local_recvfrom.c index 1197285e5ab8cccae10afcb471060a1ca69ff322..bf5dc45c16fb296b6e3870d2a134b710e95483f0 100644 --- a/net/local/local_recvfrom.c +++ b/net/local/local_recvfrom.c @@ -94,7 +94,7 @@ static int psock_fifo_read(FAR struct socket *psock, FAR void *buf, * eventually be reported as ENOTCONN. */ - psock->s_flags &= ~(_SF_CONNECTED |_SF_CLOSED); + psock->s_flags &= ~(_SF_CONNECTED | _SF_CLOSED); conn->lc_state = LOCAL_STATE_DISCONNECTED; /* Did we receive any data? */ @@ -115,7 +115,7 @@ static int psock_fifo_read(FAR struct socket *psock, FAR void *buf, return ret; } } - + return OK; } @@ -351,7 +351,7 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, close(conn->lc_infd); conn->lc_infd = -1; - /* Release our reference to the half duplex FIFO*/ + /* Release our reference to the half duplex FIFO */ (void)local_release_halfduplex(conn); @@ -375,7 +375,7 @@ errout_with_infd: conn->lc_infd = -1; errout_with_halfduplex: - /* Release our reference to the half duplex FIFO*/ + /* Release our reference to the half duplex FIFO */ (void)local_release_halfduplex(conn); return ret; diff --git a/net/local/local_sendto.c b/net/local/local_sendto.c index a4761413ef2fbb314dccd7b3101e01234a8f7451..8142110c0837588d0bb926691117efb7a8671e17 100644 --- a/net/local/local_sendto.c +++ b/net/local/local_sendto.c @@ -168,7 +168,7 @@ ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf, conn->lc_outfd = -1; errout_with_halfduplex: - /* Release our reference to the half duplex FIFO*/ + /* Release our reference to the half duplex FIFO */ (void)local_release_halfduplex(conn); return nsent; diff --git a/net/loopback/Kconfig b/net/loopback/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f72f3c094ce4c8f031445c514c343376e4e79e75 --- /dev/null +++ b/net/loopback/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/net/loopback/Make.defs b/net/loopback/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..097be782f9b857f8cee042d5e452412f394b9685 --- /dev/null +++ b/net/loopback/Make.defs @@ -0,0 +1,47 @@ +############################################################################ +# net/loopback/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_NET_LOOPBACK),y) + +# Local loopback support + +NETDEV_CSRCS += lo_globals.c + +# Include routing table build support + +DEPPATH += --dep-path loopback +VPATH += :loopback + +endif diff --git a/net/loopback/lo_globals.c b/net/loopback/lo_globals.c new file mode 100644 index 0000000000000000000000000000000000000000..270fdb0b91bcd506dba73f8f9beadcd30fd7326c --- /dev/null +++ b/net/loopback/lo_globals.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * net/loopback/lo_globals.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "loopback/loopback.h" + +#ifdef CONFIG_NET_LOOPBACK + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Local loopback hostname */ + +const char g_lo_hostname[] = "localhost"; + +/* Local loopback addresses */ + +const in_addr_t g_lo_ipv4addr = HTONL(0x7f000001); +const in_addr_t g_lo_ipv4mask = HTONL(0xff000000); +const net_ipv6addr_t g_lo_ipv6addr = +{ + HTONS(0), HTONS(0), HTONS(0), HTONS(0), + HTONS(0), HTONS(0), HTONS(0), HTONS(1) +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_NET_LOOPBACK */ diff --git a/net/loopback/loopback.h b/net/loopback/loopback.h new file mode 100644 index 0000000000000000000000000000000000000000..8529fdbd1cef367f7ad8ea6fac3d810581cd3ff8 --- /dev/null +++ b/net/loopback/loopback.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * net/route/route.h + * + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __NET_LOOPBACK_LOOBACK_H +#define __NET_LOOPBACK_LOOBACK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_NET_LOOPBACK + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + + /**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* CONFIG_NET_LOOPBACK */ +#endif /* __NET_LOOPBACK_LOOBACK_H */ diff --git a/net/neighbor/neighbor.h b/net/neighbor/neighbor.h index 087f1a414c22d6835fa995f17646d0b85de58979..a8317f6d36283fcb508d0b541f42145a5bf204b6 100644 --- a/net/neighbor/neighbor.h +++ b/net/neighbor/neighbor.h @@ -49,6 +49,7 @@ #include +#include #include #ifdef CONFIG_NET_IPv6 @@ -70,7 +71,7 @@ struct neighbor_addr_s { -#if CONFIG_NET_IPv6_NEIGHBOR_ADDRTYPE +#ifdef CONFIG_NET_IPv6_NEIGHBOR_ADDRTYPE CONFIG_NET_IPv6_NEIGHBOR_ADDRTYPE na_addr; #else struct ether_addr na_addr; @@ -98,16 +99,12 @@ struct neighbor_entry extern struct neighbor_entry g_neighbors[CONFIG_NET_IPv6_NCONF_ENTRIES]; -/* This is the time, in clock ticks, of the last poll */ - -extern uint32_t g_neighbor_polltime; - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ /**************************************************************************** - * Name: neighbor_setup + * Name: neighbor_initialize * * Description: * Initialize Neighbor table data structures. This function is called @@ -123,26 +120,6 @@ extern uint32_t g_neighbor_polltime; * ****************************************************************************/ -void neighbor_setup(void); - -/**************************************************************************** - * Name: neighbor_initialize - * - * Description: - * Initialize Neighbor ageing. This function is called from the OS - * initialization logic at power-up reset AFTER initialization of hardware - * facilities such as timers and interrupts. This logic completes the - * initialization started by neighbor_setup. - * - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - void neighbor_initialize(void); /**************************************************************************** @@ -225,14 +202,14 @@ void neighbor_update(const net_ipv6addr_t ipaddr); * entries in the Neighbor Table * * Input Parameters: - * None + * hsec - Elapsed time in half seconds since the last check * * Returned Value: * None * ****************************************************************************/ -void neighbor_periodic(void); +void neighbor_periodic(int hsec); #endif /* CONFIG_NET_IPv6 */ #endif /* __NET_NEIGHBOR_NEIGHBOR_H */ diff --git a/net/neighbor/neighbor_initialize.c b/net/neighbor/neighbor_initialize.c index ce4ebdb562f3b0ea1223e22770abcdab250e409b..d25fb782f3365000a041fc0199016db0a9f2b921 100644 --- a/net/neighbor/neighbor_initialize.c +++ b/net/neighbor/neighbor_initialize.c @@ -56,16 +56,12 @@ struct neighbor_entry g_neighbors[CONFIG_NET_IPv6_NCONF_ENTRIES]; -/* This is the time, in clock ticks, of the last poll */ - -uint32_t g_neighbor_polltime; - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: neighbor_setup + * Name: neighbor_initialize * * Description: * Initialize Neighbor table data structures. This function is called @@ -81,7 +77,7 @@ uint32_t g_neighbor_polltime; * ****************************************************************************/ -void neighbor_setup(void) +void neighbor_initialize(void) { int i; @@ -90,28 +86,3 @@ void neighbor_setup(void) g_neighbors[i].ne_time = NEIGHBOR_MAXTIME; } } - -/**************************************************************************** - * Name: neighbor_initialize - * - * Description: - * Initialize Neighbor ageing. This function is called from the OS - * initialization logic at power-up reset AFTER initialization of hardware - * facilities such as timers and interrupts. This logic completes the - * initialization started by neighbor_setup. - * - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -void neighbor_initialize(void) -{ - /* Initialize the time of the last poll */ - - g_neighbor_polltime = clock_systimer(); -} diff --git a/net/neighbor/neighbor_out.c b/net/neighbor/neighbor_out.c index 3a6e471988f92ec119414999e98f16d4d847dfbb..061a45518dc5e08b3267c90d3c985fd9c56dd19d 100644 --- a/net/neighbor/neighbor_out.c +++ b/net/neighbor/neighbor_out.c @@ -67,7 +67,11 @@ /* Support for broadcast address */ static const struct ether_addr g_broadcast_ethaddr = - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; +{ + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + } +}; /* Support for IGMP multicast addresses. * @@ -86,7 +90,10 @@ static const struct ether_addr g_broadcast_ethaddr = */ #ifdef CONFIG_NET_IGMP -static const uint8_t g_multicast_ethaddr[3] = {0x01, 0x00, 0x5e}; +static const uint8_t g_multicast_ethaddr[3] = +{ + 0x01, 0x00, 0x5e +}; #endif /**************************************************************************** diff --git a/net/neighbor/neighbor_periodic.c b/net/neighbor/neighbor_periodic.c index 2a9f0d99fddad283305eecb83a10f401187d3dd8..2ca0a5b3ca9e430a19b6fdc53e37c4bbd8d478c4 100644 --- a/net/neighbor/neighbor_periodic.c +++ b/net/neighbor/neighbor_periodic.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/neighbor/neighbor_periodic.c * - * Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * A leverage of logic from uIP which also has a BSD style license @@ -42,18 +42,9 @@ ****************************************************************************/ #include -#include #include "neighbor/neighbor.h" -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#define USEC_PER_HSEC 500000 -#define TICK_PER_HSEC (USEC_PER_HSEC / USEC_PER_TICK) /* Truncates! */ -#define TICK2HSEC(tick) (((tick)+(TICK_PER_HSEC/2))/TICK_PER_HSEC) /* Rounds */ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -66,42 +57,34 @@ * entries in the Neighbor Table * * Input Parameters: - * None + * hsec - Elapsed time in half seconds since the last check * * Returned Value: * None * ****************************************************************************/ -void neighbor_periodic(void) +void neighbor_periodic(int hsec) { - uint32_t now; - uint32_t ticks; - uint32_t hsecs; int i; - /* Get the elapsed time in units of half seconds */ - - now = clock_systimer(); - ticks = now - g_neighbor_polltime; - hsecs = TICK2HSEC(ticks); + /* Only perform the aging when more than a half second has elapsed */ - /* Reset the time of the last poll */ - - g_neighbor_polltime = now; - - /* Add the elapsed half seconds from each activate entry in the - * Neighbor table. - */ - - for (i = 0; i < CONFIG_NET_IPv6_NCONF_ENTRIES; ++i) + if (hsec > 0) { - uint32_t newtime = g_neighbors[i].ne_time + hsecs; - if (newtime > NEIGHBOR_MAXTIME) + /* Add the elapsed half seconds from each activate entry in the + * Neighbor table. + */ + + for (i = 0; i < CONFIG_NET_IPv6_NCONF_ENTRIES; ++i) { - newtime = NEIGHBOR_MAXTIME; - } + uint32_t newtime = g_neighbors[i].ne_time + hsec; + if (newtime > NEIGHBOR_MAXTIME) + { + newtime = NEIGHBOR_MAXTIME; + } - g_neighbors[i].ne_time = newtime; + g_neighbors[i].ne_time = newtime; + } } } diff --git a/net/net_initialize.c b/net/net_initialize.c index 99090c650afb501e9c7f0de790ee57757a0f336d..df3a72226d32a2b696d4a5a380b7079ab59fd552 100644 --- a/net/net_initialize.c +++ b/net/net_initialize.c @@ -67,11 +67,11 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -118,7 +118,7 @@ void net_setup(void) #ifdef CONFIG_NET_IPv6 /* Initialize the Neighbor Table data structures */ - neighbor_setup(); + neighbor_initialize(); #endif #ifdef CONFIG_NET_IOB @@ -197,12 +197,6 @@ void net_setup(void) void net_initialize(void) { -#ifdef CONFIG_NET_IPv6 - /* Configure Neighbor Table ageing */ - - neighbor_initialize(); -#endif - /* Initialize the periodic ARP timer */ arp_timer_initialize(); diff --git a/net/netdev/Make.defs b/net/netdev/Make.defs index 955745945cd088cf41a10d535e08703a10f7b768..c5262a1aaccb535fca9fb71a9d32701e3e127d73 100644 --- a/net/netdev/Make.defs +++ b/net/netdev/Make.defs @@ -36,9 +36,9 @@ # Support for operations on network devices NETDEV_CSRCS += netdev_register.c netdev_ioctl.c netdev_txnotify.c -NETDEV_CSRCS += netdev_findbyname.c netdev_findbyaddr.c netdev_count.c -NETDEV_CSRCS += netdev_foreach.c netdev_unregister.c netdev_carrier.c -NETDEV_CSRCS += netdev_default.c netdev_verify.c +NETDEV_CSRCS += netdev_findbyname.c netdev_findbyaddr.c netdev_findbyindex.c +NETDEV_CSRCS += netdev_count.c netdev_foreach.c netdev_unregister.c +NETDEV_CSRCS += netdev_carrier.c netdev_default.c netdev_verify.c ifeq ($(CONFIG_NET_RXAVAIL),y) NETDEV_CSRCS += netdev_rxnotify.c diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h index 9e055effd02000362ee96e9b6f4c74d1e2b3f72e..19955d3951068e4da754151b3c4bf0c16a331858 100644 --- a/net/netdev/netdev.h +++ b/net/netdev/netdev.h @@ -47,14 +47,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Type Definitions - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -188,6 +180,30 @@ FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t ripaddr); #endif #endif +/**************************************************************************** + * Function: netdev_findbyindex + * + * Description: + * Find a previously registered network device by its position in the + * list of registered devices. NOTE that this function is not a safe way + * to enumerate network devices: There could be changes to the list of + * registered device causing a given index to be meaningless (unless, of + * course, the caller keeps the network locked). + * + * Parameters: + * index - the index of the interface to file + * + * Returned Value: + * Pointer to driver on success; NULL on failure. This function can only + * fail if there are fewer registered interfaces than could be indexed. + * + * Assumptions: + * Called from normal user mode + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyindex(int index); + /**************************************************************************** * Function: netdev_default * diff --git a/net/netdev/netdev_carrier.c b/net/netdev/netdev_carrier.c index 397ca4cb8837cae572babf49cc9196a56bd6cb38..8c422033282d98e83fe4268c8e14f17c68f8dabb 100644 --- a/net/netdev/netdev_carrier.c +++ b/net/netdev/netdev_carrier.c @@ -54,26 +54,6 @@ #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_count.c b/net/netdev/netdev_count.c index d036339c5460216abb38be98c274857faafdd442..73ff960f3d84740689cd1188341db27014802073 100644 --- a/net/netdev/netdev_count.c +++ b/net/netdev/netdev_count.c @@ -48,26 +48,6 @@ #include "utils/utils.h" #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_default.c b/net/netdev/netdev_default.c index addb67dcc70a217cb30310a3b311c871abc43c4a..24884259a7da42bfbcc58e51d40073a23a7f79ea 100644 --- a/net/netdev/netdev_default.c +++ b/net/netdev/netdev_default.c @@ -45,30 +45,6 @@ #include "utils/utils.h" #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Function: netdev_maskcmp - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_findbyaddr.c b/net/netdev/netdev_findbyaddr.c index 041189842ab960437d1f4afa26515c0070f2d767..54cf1cee35ad13bfe4dcf681b7e81e84ddc8777c 100644 --- a/net/netdev/netdev_findbyaddr.c +++ b/net/netdev/netdev_findbyaddr.c @@ -55,22 +55,6 @@ #include "route/route.h" #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -289,12 +273,12 @@ FAR struct net_driver_s *netdev_findby_ipv4addr(in_addr_t ripaddr) */ #ifndef CONFIG_NETDEV_MULTINIC - /* If there is only a single, registered network interface, then the - * decision is pretty easy. Use that device and its default router - * address. - */ + /* If there is only a single, registered network interface, then the + * decision is pretty easy. Use that device and its default router + * address. + */ - dev = g_netdevices; + dev = g_netdevices; #endif /* If we will did not find the network device, then we might as well fail @@ -407,12 +391,12 @@ FAR struct net_driver_s *netdev_findby_ipv6addr(const net_ipv6addr_t ripaddr) */ #ifndef CONFIG_NETDEV_MULTINIC - /* If there is only a single, registered network interface, then the - * decision is pretty easy. Use that device and its default router - * address. - */ + /* If there is only a single, registered network interface, then the + * decision is pretty easy. Use that device and its default router + * address. + */ - dev = g_netdevices; + dev = g_netdevices; #endif /* If we will did not find the network device, then we might as well fail diff --git a/net/netdev/netdev_findbyindex.c b/net/netdev/netdev_findbyindex.c new file mode 100644 index 0000000000000000000000000000000000000000..74ccba04c843322c50086f37400ea2cbb8485949 --- /dev/null +++ b/net/netdev/netdev_findbyindex.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * net/netdev/netdev_findbyindex.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 + +#include +#include + +#include + +#include "utils/utils.h" +#include "netdev/netdev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: netdev_findbyindex + * + * Description: + * Find a previously registered network device by its position in the + * list of registered devices. NOTE that this function is not a safe way + * to enumerate network devices: There could be changes to the list of + * registered device causing a given index to be meaningless (unless, of + * course, the caller keeps the network locked). + * + * Parameters: + * index - the index of the interface to file + * + * Returned Value: + * Pointer to driver on success; NULL on failure. This function can only + * fail if there are fewer registered interfaces than could be indexed. + * + * Assumptions: + * Called from normal user mode + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyindex(int index) +{ +#ifdef CONFIG_NETDEV_MULTINIC + FAR struct net_driver_s *dev; + net_lock_t save; + int i; + + save = net_lock(); + for (i = 0, dev = g_netdevices; dev; i++, dev = dev->flink) + { + if (i == index) + { + net_unlock(save); + return dev; + } + } + + net_unlock(save); + return NULL; +#else + return (index == 0) ? g_netdevices : NULL; +#endif +} + +#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */ diff --git a/net/netdev/netdev_findbyname.c b/net/netdev/netdev_findbyname.c index 93f90a9aabcba07bd84a26e58d13f2fe7088b2be..04c20b27c8e844b40cfb8be33e9a076b93af1080 100644 --- a/net/netdev/netdev_findbyname.c +++ b/net/netdev/netdev_findbyname.c @@ -48,26 +48,6 @@ #include "utils/utils.h" #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_foreach.c b/net/netdev/netdev_foreach.c index 8098dfd12eade3dfb7bb53646c8e9b8fa0099e32..99d6a8c061f487f9ab41c362d2f4a83a602066b4 100644 --- a/net/netdev/netdev_foreach.c +++ b/net/netdev/netdev_foreach.c @@ -46,26 +46,6 @@ #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 627d8025c88b0b83bcd461aa1fc5085917a795c7..c4a1a650d03418fde71d65e483ddd5bef871a18c 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/netdev/netdev_ioctl.c * - * Copyright (C) 2007-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -57,12 +57,14 @@ #include #include +#include #ifdef CONFIG_NET_IGMP # include "sys/sockio.h" # include "nuttx/net/igmp.h" #endif +#include "arp/arp.h" #include "socket/socket.h" #include "netdev/netdev.h" #include "devif/devif.h" @@ -674,13 +676,6 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, } break; -#ifdef CONFIG_NET_ARPIOCTLS - case SIOCSARP: /* Set a ARP mapping */ - case SIOCDARP: /* Delete an ARP mapping */ - case SIOCGARP: /* Get an ARP mapping */ -# error "IOCTL Commands not implemented" -#endif - #ifdef CONFIG_NETDEV_PHY_IOCTL #ifdef CONFIG_ARCH_PHY_INTERRUPT case SIOCMIINOTIFY: /* Set up for PHY event notifications */ @@ -713,7 +708,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, { ret = -ENOTTY; } - break;; + break; } return ret; @@ -808,6 +803,129 @@ static int netdev_imsfioctl(FAR struct socket *psock, int cmd, } #endif +/**************************************************************************** + * Name: netdev_arpioctl + * + * Description: + * Perform ARP table specific operations. + * + * Parameters: + * psock Socket structure + * dev Ethernet driver device structure + * cmd The ioctl command + * req The argument of the ioctl cmd + * + * Return: + * >=0 on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ARP +static int netdev_arpioctl(FAR struct socket *psock, int cmd, + FAR struct arpreq *req) +{ + int ret; + + /* Execute the command */ + + switch (cmd) + { + case SIOCSARP: /* Set an ARP mapping */ + { + if (req != NULL && + req->arp_pa.sa_family == AF_INET && + req->arp_ha.sa_family == ARPHRD_ETHER) + { + FAR struct sockaddr_in *addr = + (FAR struct sockaddr_in *)&req->arp_pa; + + /* Update any existing ARP table entry for this protocol + * address -OR- add a new ARP table entry if there is not. + */ + + ret = arp_update(addr->sin_addr.s_addr, + (FAR uint8_t *)req->arp_ha.sa_data); + } + else + { + ret = -EINVAL; + } + } + break; + + case SIOCDARP: /* Delete an ARP mapping */ + { + if (req != NULL && req->arp_pa.sa_family == AF_INET) + { + FAR struct sockaddr_in *addr = + (FAR struct sockaddr_in *)&req->arp_pa; + + /* Find the existing ARP table entry for this protocol address. */ + + FAR struct arp_entry *entry = arp_find(addr->sin_addr.s_addr); + if (entry != NULL) + { + /* The ARP table is fixed size; an entry is deleted + * by nullifying its protocol address. + */ + + entry->at_ipaddr = 0; + ret = OK; + } + else + { + ret = -ENOENT; + } + } + else + { + ret = -EINVAL; + } + } + break; + + case SIOCGARP: /* Get an ARP mapping */ + { + if (req != NULL && req->arp_pa.sa_family == AF_INET) + { + FAR struct sockaddr_in *addr = + (FAR struct sockaddr_in *)&req->arp_pa; + + /* Find the existing ARP table entry for this protocol address. */ + + FAR struct arp_entry *entry = arp_find(addr->sin_addr.s_addr); + if (entry != NULL) + { + /* Return the mapped hardware address. */ + + req->arp_ha.sa_family = ARPHRD_ETHER; + memcpy(req->arp_ha.sa_data, + entry->at_ethaddr.ether_addr_octet, + ETHER_ADDR_LEN); + ret = OK; + } + else + { + ret = -ENOENT; + } + } + else + { + ret = -EINVAL; + } + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif + /**************************************************************************** * Name: netdev_rtioctl * @@ -964,18 +1082,32 @@ int netdev_ioctl(int sockfd, int cmd, unsigned long arg) /* Execute the command */ - ret = netdev_ifrioctl(psock, cmd, (FAR struct ifreq*)((uintptr_t)arg)); + ret = netdev_ifrioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg)); + #ifdef CONFIG_NET_IGMP + /* Check for address filtering commands */ + if (ret == -ENOTTY) { + ret = netdev_imsfioctl(psock, cmd, (FAR struct ip_msfilter *)((uintptr_t)arg)); + } +#endif - ret = netdev_imsfioctl(psock, cmd, (FAR struct ip_msfilter*)((uintptr_t)arg)); +#ifdef CONFIG_NET_ARP + /* Check for ARP table IOCTL commands */ + + if (ret == -ENOTTY) + { + ret = netdev_arpioctl(psock, cmd, (FAR struct arpreq *)((uintptr_t)arg)); } #endif + #ifdef CONFIG_NET_ROUTE + /* Check for Routing table IOCTL commands */ + if (ret == -ENOTTY) { - ret = netdev_rtioctl(psock, cmd, (FAR struct rtentry*)((uintptr_t)arg)); + ret = netdev_rtioctl(psock, cmd, (FAR struct rtentry *)((uintptr_t)arg)); } #endif diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c index 524f6cb2d4bbedb2cc7fbb0994794795b61a146d..11982d9eeb14b129d365b9829717367e46ab0bb7 100644 --- a/net/netdev/netdev_register.c +++ b/net/netdev/netdev_register.c @@ -61,20 +61,22 @@ * Pre-processor Definitions ****************************************************************************/ -#define NETDEV_SLIP_FORMAT "sl%d" -#define NETDEV_ETH_FORMAT "eth%d" -#define NETDEV_TUN_FORMAT "tun%d" +#define NETDEV_ETH_FORMAT "eth%d" +#define NETDEV_LO_FORMAT "lo" +#define NETDEV_WPAN_FORMAT "wpan%d" +#define NETDEV_SLIP_FORMAT "sl%d" +#define NETDEV_TUN_FORMAT "tun%d" #if defined(CONFIG_NET_SLIP) # define NETDEV_DEFAULT_FORMAT NETDEV_SLIP_FORMAT -#else /* if defined(CONFIG_NET_ETHERNET) */ +#elif defined(CONFIG_NET_ETHERNET) # define NETDEV_DEFAULT_FORMAT NETDEV_ETH_FORMAT +#elif defined(CONFIG_NET_6LOWPAN) +# define NETDEV_DEFAULT_FORMAT NETDEV_WPAN_FORMAT +#else /* if defined(CONFIG_NET_LOOPBACK) */ +# define NETDEV_DEFAULT_FORMAT NETDEV_LO_FORMAT #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -159,7 +161,7 @@ static int find_devnum(FAR const char *devfmt) * * Parameters: * dev - The device driver structure to be registered. - * lltype - Link level protocol used by the driver (Ethernet, SLIP, PPP, ... + * lltype - Link level protocol used by the driver (Ethernet, SLIP, TUN, ... * ... * * Returned Value: @@ -190,8 +192,19 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) switch (lltype) { +#ifdef CONFIG_NET_LOOPBACK + case NET_LL_LOOPBACK: /* Local loopback */ + dev->d_llhdrlen = 0; + dev->d_mtu = NET_LO_MTU; +#ifdef CONFIG_NET_TCP + dev->d_recvwndo = NET_LO_TCP_RECVWNDO; +#endif + devfmt = NETDEV_LO_FORMAT; + break; +#endif + #ifdef CONFIG_NET_ETHERNET - case NET_LL_ETHERNET: /* Ethernet */ + case NET_LL_ETHERNET: /* Ethernet */ dev->d_llhdrlen = ETH_HDRLEN; dev->d_mtu = CONFIG_NET_ETH_MTU; #ifdef CONFIG_NET_TCP @@ -201,8 +214,19 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) break; #endif +#ifdef CONFIG_NET_6LOWPAN + case NET_LL_6LOWPAN: /* IEEE 802.15.4 */ + dev->d_llhdrlen = 0; /* REVISIT */ + dev->d_mtu = CONFIG_NET_6LOWPAN_MTU; +#ifdef CONFIG_NET_TCP + dev->d_recvwndo = CONFIG_NET_6LOWPAN_TCP_RECVWNDO; +#endif + devfmt = NETDEV_WPAN_FORMAT; + break; +#endif + #ifdef CONFIG_NET_SLIP - case NET_LL_SLIP: /* Serial Line Internet Protocol (SLIP) */ + case NET_LL_SLIP: /* Serial Line Internet Protocol (SLIP) */ dev->d_llhdrlen = 0; dev->d_mtu = CONFIG_NET_SLIP_MTU; #ifdef CONFIG_NET_TCP @@ -213,7 +237,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) #endif #ifdef CONFIG_NET_TUN - case NET_LL_TUN: /* Virtual Network Device (TUN) */ + case NET_LL_TUN: /* Virtual Network Device (TUN) */ dev->d_llhdrlen = 0; dev->d_mtu = CONFIG_NET_TUN_MTU; #ifdef CONFIG_NET_TCP @@ -223,17 +247,6 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) break; #endif -#if 0 /* REVISIT: Not yet supported */ - case NET_LL_PPP: /* Point-to-Point Protocol (PPP) */ - dev->d_llhdrlen = 0; - dev->d_mtu = CONFIG_NET_PPP_MTU; -#ifdef CONFIG_NET_TCP - dev->d_recvwndo = CONFIG_NET_PPP_TCP_RECVWNDO; -#endif - devfmt = NETDEV_PPP_FORMAT; - break; -#endif - default: nlldbg("ERROR: Unrecognized link type: %d\n", lltype); return -EINVAL; @@ -254,16 +267,35 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) dev->d_conncb = NULL; dev->d_devcb = NULL; - /* Get the next available device number and sssign a device name to + /* Get the next available device number and assign a device name to * the interface */ save = net_lock(); + #ifdef CONFIG_NET_MULTILINK - devnum = find_devnum(devfmt); +# ifdef CONFIG_NET_LOOPBACK + /* The local loopback device is a special case: There can be only one + * local loopback device so it is unnumbered. + */ + + if (lltype == NET_LL_LOOPBACK) + { + devnum = 0; + } + else +# endif + { + devnum = find_devnum(devfmt); + } #else + /* There is only a single link type. Finding the next network device + * number is simple. + */ + devnum = g_next_devnum++; #endif + #ifdef CONFIG_NET_USER_DEVFMT if (*dev->d_ifname) { @@ -272,7 +304,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) } #endif - snprintf(dev->d_ifname, IFNAMSIZ, devfmt, devnum ); + snprintf(dev->d_ifname, IFNAMSIZ, devfmt, devnum); /* Add the device to the list of known network devices */ diff --git a/net/netdev/netdev_rxnotify.c b/net/netdev/netdev_rxnotify.c index 824c78f89c5ef132ace0cb64a4edfc4d690d0064..be7aed64d0198becab46328aef6ce22af1433e10 100644 --- a/net/netdev/netdev_rxnotify.c +++ b/net/netdev/netdev_rxnotify.c @@ -50,26 +50,6 @@ #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -79,7 +59,7 @@ * * Description: * Notify the device driver that forwards the IPv4 address that the - * application waits for RX data. + * application waits for RX data. * * Parameters: * lipaddr - The local board IPv6 address of the socket @@ -124,7 +104,7 @@ void netdev_ipv4_rxnotify(in_addr_t ripaddr) * * Description: * Notify the device driver that forwards the IPv6 address that the - * application waits for RX data. + * application waits for RX data. * * Parameters: * lipaddr - The local board IPv6 address of the socket diff --git a/net/netdev/netdev_txnotify.c b/net/netdev/netdev_txnotify.c index bbf4e9dec38a11806d96f2565f1c30f76c54b7ad..3d0c85203c9fa0ad0507eeab3da07aa69931192a 100644 --- a/net/netdev/netdev_txnotify.c +++ b/net/netdev/netdev_txnotify.c @@ -50,26 +50,6 @@ #include "netdev/netdev.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/netdev/netdev_unregister.c b/net/netdev/netdev_unregister.c index 9dad59c22269d0385aed8fc25caf2742dbd0e6b7..fc326dcf318d90fed4fda69f21499faa8f4f0d73 100644 --- a/net/netdev/netdev_unregister.c +++ b/net/netdev/netdev_unregister.c @@ -65,22 +65,6 @@ # define NETDEV_FORMAT "eth%d" #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/pkt/pkt.h b/net/pkt/pkt.h index 12138d4aa37525550092758f9e4e9dcbf4f5e91e..295c40b07ed68e5c6cb147ea5bef21a0ce7f0897 100644 --- a/net/pkt/pkt.h +++ b/net/pkt/pkt.h @@ -61,7 +61,7 @@ * Public Type Definitions ****************************************************************************/ -/* Representation of a uIP packet socket connection */ +/* Representation of a packet socket connection */ struct devif_callback_s; /* Forward reference */ @@ -94,7 +94,7 @@ extern "C" * Public Function Prototypes ****************************************************************************/ - struct eth_hdr_s; /* Forward reference */ +struct eth_hdr_s; /* Forward reference */ /* Defined in pkt_conn.c ****************************************************/ /**************************************************************************** diff --git a/net/pkt/pkt_callback.c b/net/pkt/pkt_callback.c index cc66f6d47a681dcc13e79b44774b9ad7f803302b..5376b4ce224ecf7c228f28084bd1fb6059f8708c 100644 --- a/net/pkt/pkt_callback.c +++ b/net/pkt/pkt_callback.c @@ -49,14 +49,6 @@ #include "devif/devif.h" #include "pkt/pkt.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/pkt/pkt_conn.c b/net/pkt/pkt_conn.c index c47eea2d110ebde74e7b5da9b80cc3006af599fb..52345043b4344b1b23cbe5388eea0c303f5902d2 100644 --- a/net/pkt/pkt_conn.c +++ b/net/pkt/pkt_conn.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/pkt/pkt_conn.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Large parts of this file were leveraged from uIP logic: @@ -97,7 +97,7 @@ static inline void _pkt_semtake(sem_t *sem) * the wait was awakened by a signal. */ - ASSERT(*get_errno_ptr() == EINTR); + DEBUGASSERT(get_errno() == EINTR); } } diff --git a/net/pkt/pkt_finddev.c b/net/pkt/pkt_finddev.c index 885f6402b29d0d1768d9d4c0af283c6f00abf5e3..639c894b3bd148e47b10d307e77765c24eec16e6 100644 --- a/net/pkt/pkt_finddev.c +++ b/net/pkt/pkt_finddev.c @@ -45,14 +45,6 @@ #include "netdev/netdev.h" #include "pkt/pkt.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/pkt/pkt_input.c b/net/pkt/pkt_input.c index 733da5596f2a0301e191877d8ec7ce5898ed2025..27b3af4d257a887454f915c686ef9bbf34fb979f 100644 --- a/net/pkt/pkt_input.c +++ b/net/pkt/pkt_input.c @@ -60,18 +60,6 @@ #define PKTBUF ((struct eth_hdr_s *)&dev->d_buf) -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/pkt/pkt_poll.c b/net/pkt/pkt_poll.c index 701ce011765ec1cd4ac68a2ad4f466fd4480174d..dc4f5a92d040e555712fa138d961a47297a7e732 100644 --- a/net/pkt/pkt_poll.c +++ b/net/pkt/pkt_poll.c @@ -54,22 +54,6 @@ #include "devif/devif.h" #include "pkt/pkt.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -114,7 +98,7 @@ void pkt_poll(FAR struct net_driver_s *dev, FAR struct pkt_conn_s *conn) if (dev->d_sndlen > 0) { -// devif_pkt_send(dev, conn); + //devif_pkt_send(dev, conn); return; } } diff --git a/net/pkt/pkt_send.c b/net/pkt/pkt_send.c index f7dbca8c67decda6c62c4a0eeb6dce0892b6886a..1310cb92086ef932dc191917a6a74b7a7d8faa9e 100644 --- a/net/pkt/pkt_send.c +++ b/net/pkt/pkt_send.c @@ -61,10 +61,6 @@ #include "socket/socket.h" #include "pkt/pkt.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -266,7 +262,7 @@ ssize_t psock_pkt_send(FAR struct socket *psock, FAR const void *buf, /* Set up the callback in the connection */ state.snd_cb->flags = PKT_POLL; - state.snd_cb->priv = (void*)&state; + state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = psock_send_interrupt; /* Notify the device driver that new TX data is available. */ diff --git a/net/procfs/Kconfig b/net/procfs/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f72f3c094ce4c8f031445c514c343376e4e79e75 --- /dev/null +++ b/net/procfs/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/net/procfs/Make.defs b/net/procfs/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..90cef533d203dec1224dc6474180bcec7c5e0e0d --- /dev/null +++ b/net/procfs/Make.defs @@ -0,0 +1,57 @@ +############################################################################ +# net/procfs/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +# Network procfs support + +ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) +ifeq ($(CONFIG_FS_PROCFS),y) +ifneq ($(CONFIG_FS_PROCFS_EXCLUDE_NET),y) + +NET_CSRCS += net_procfs.c netdev_statistics.c + +# General network statistics + +ifeq ($(CONFIG_NET_STATISTICS),y) + NET_CSRCS += net_statistics.c +endif + +# Include packet socket build support + +DEPPATH += --dep-path procfs +VPATH += :procfs + +endif # CONFIG_FS_PROCFS_EXCLUDE_NET +endif # CONFIG_FS_PROCFS +endif # CONFIG_DISABLE_MOUNTPOINT diff --git a/net/procfs/net_procfs.c b/net/procfs/net_procfs.c new file mode 100644 index 0000000000000000000000000000000000000000..f65cf040df97d30ffa0026e1ee7c05705e099edb --- /dev/null +++ b/net/procfs/net_procfs.c @@ -0,0 +1,653 @@ +/**************************************************************************** + * net/procfs/net_procfs.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "netdev/netdev.h" +#include "procfs/procfs.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ + !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* File system methods */ + +static int netprocfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int netprocfs_close(FAR struct file *filep); +static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); + +static int netprocfs_dup(FAR const struct file *oldp, + FAR struct file *newp); + +static int netprocfs_opendir(FAR const char *relpath, + FAR struct fs_dirent_s *dir); +static int netprocfs_closedir(FAR struct fs_dirent_s *dir); +static int netprocfs_readdir(FAR struct fs_dirent_s *dir); +static int netprocfs_rewinddir(FAR struct fs_dirent_s *dir); + +static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* See include/nutts/fs/procfs.h + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct procfs_operations net_procfsoperations = +{ + netprocfs_open, /* open */ + netprocfs_close, /* close */ + netprocfs_read, /* read */ + NULL, /* write */ + netprocfs_dup, /* dup */ + + netprocfs_opendir, /* opendir */ + netprocfs_closedir, /* closedir */ + netprocfs_readdir, /* readdir */ + netprocfs_rewinddir, /* rewinddir */ + + netprocfs_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_open + ****************************************************************************/ + +static int netprocfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct netprocfs_file_s *priv; + FAR struct net_driver_s *dev; + + fvdbg("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if (((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) && + (net_procfsoperations.write == NULL)) + { + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "net/stat" is an acceptable value for the relpath only if network layer + * statistics are enabled. + */ + +#ifdef CONFIG_NET_STATISTICS + if (strcmp(relpath, "net/stat") == 0) + { + /* A NULL network device reference is a clue that we are processing + * the network statistics file. + */ + + dev = NULL; + } + else +#endif + { + FAR char *devname; + FAR char *copy; + + /* Otherwise, we need to search the list of registered network devices + * to determine if the name corresponds to a network device. + */ + + copy = strdup(relpath); + if (copy == NULL) + { + fdbg("ERROR: strdup failed\n"); + return -ENOMEM; + } + + devname = basename(copy); + dev = netdev_findbyname(devname); + kmm_free(copy); + + if (dev == NULL) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + } + + /* Allocate the open file structure */ + + priv = (FAR struct netprocfs_file_s *)kmm_zalloc(sizeof(struct netprocfs_file_s)); + if (!priv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Initialize the open-file structure */ + + priv->dev = dev; + + /* Save the open file structure as the open-specific state in + * filep->f_priv. + */ + + filep->f_priv = (FAR void *)priv; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_close + ****************************************************************************/ + +static int netprocfs_close(FAR struct file *filep) +{ + FAR struct netprocfs_file_s *priv; + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct netprocfs_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + /* Release the file attributes structure */ + + kmm_free(priv); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_read + ****************************************************************************/ + +static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct netprocfs_file_s *priv; + ssize_t nreturned; + + fvdbg("buffer=%p buflen=%lu\n", buffer, (unsigned long)buflen); + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct netprocfs_file_s *)filep->f_priv; + DEBUGASSERT(priv); + +#ifdef CONFIG_NET_STATISTICS + /* A NULL device structure reference is the key that we are showing the + * network statistics. + */ + + if (priv->dev == NULL) + { + /* Show the network layer statistics */ + + nreturned = netprocfs_read_netstats(priv, buffer, buflen); + } + else +#endif + { + /* Otherwise, we are showing device-specific statistics */ + + nreturned = netprocfs_read_devstats(priv, buffer, buflen); + } + + /* Update the file offset */ + + if (nreturned > 0) + { + filep->f_pos += nreturned; + } + + return nreturned; +} + +/**************************************************************************** + * Name: netprocfs_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int netprocfs_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct netprocfs_file_s *oldpriv; + FAR struct netprocfs_file_s *newpriv; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldpriv = (FAR struct netprocfs_file_s *)oldp->f_priv; + DEBUGASSERT(oldpriv); + + /* Allocate a new container to hold the task and attribute selection */ + + newpriv = (FAR struct netprocfs_file_s *)kmm_zalloc(sizeof(struct netprocfs_file_s)); + if (!newpriv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attribtes from the old attributes to the new */ + + memcpy(newpriv, oldpriv, sizeof(struct netprocfs_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newpriv; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_opendir + * + * Description: + * Open a directory for read access + * + ****************************************************************************/ + +static int netprocfs_opendir(FAR const char *relpath, + FAR struct fs_dirent_s *dir) +{ + FAR struct netprocfs_level1_s *level1; + int ndevs; + + fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL"); + DEBUGASSERT(relpath && dir && !dir->u.procfs); + + /* "net" is the only value of relpath that is a directory */ + + if (strcmp(relpath, "net") != 0) + { + /* REVISIT: We really need to check if the relpath refers to a network + * device. In that case, we need to return -ENOTDIR. Otherwise, we + * should return -ENOENT. + */ + + fdbg("ERROR: Bad relpath: %s\n", relpath); + return -ENOTDIR; + } + + /* The path refers to the 1st level sbdirectory. Allocate the level1 + * dirent structure. + */ + + level1 = (FAR struct netprocfs_level1_s *) + kmm_zalloc(sizeof(struct netprocfs_level1_s)); + + if (!level1) + { + fdbg("ERROR: Failed to allocate the level1 directory structure\n"); + return -ENOMEM; + } + + /* Count the number of network devices */ + + ndevs = netdev_count(); + + /* Initialze base structure components */ + + level1->base.level = 1; +#ifdef CONFIG_NET_STATISTICS + level1->base.nentries = ndevs + 1; +#else + level1->base.nentries = ndevs; +#endif + level1->base.index = 0; + + dir->u.procfs = (FAR void *) level1; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_closedir + * + * Description: Close the directory listing + * + ****************************************************************************/ + +static int netprocfs_closedir(FAR struct fs_dirent_s *dir) +{ + FAR struct netprocfs_level1_s *priv; + + DEBUGASSERT(dir && dir->u.procfs); + priv = dir->u.procfs; + + if (priv) + { + kmm_free(priv); + } + + dir->u.procfs = NULL; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_readdir + * + * Description: Read the next directory entry + * + ****************************************************************************/ + +static int netprocfs_readdir(FAR struct fs_dirent_s *dir) +{ + FAR struct netprocfs_level1_s *level1; + FAR struct net_driver_s *dev; + int index; + + DEBUGASSERT(dir && dir->u.procfs); + level1 = dir->u.procfs; + DEBUGASSERT(level1->base.level == 1); + + /* Have we reached the end of the directory */ + + index = level1->base.index; + DEBUGASSERT(index <= level1->base.nentries); + + if (index >= level1->base.nentries) + { + /* We signal the end of the directory by returning the special + * error -ENOENT. + */ + + fvdbg("Entry %d: End of directory\n", index); + return -ENOENT; + } + +#ifdef CONFIG_NET_STATISTICS + else if (index == 0) + { + /* Copy the network statistics directory entry */ + + dir->fd_dir.d_type = DTYPE_FILE; + strncpy(dir->fd_dir.d_name, "stat", NAME_MAX + 1); + } + else +#endif + { + int devndx = index; + +#ifdef CONFIG_NET_STATISTICS + /* Subtract one to account for index == 0 which is used for network + * status. + */ + + devndx--; +#endif + + /* Find the device corresponding to this device index */ + + dev = netdev_findbyindex(devndx); + + /* Copy the device statistics file entry */ + + dir->fd_dir.d_type = DTYPE_FILE; + strncpy(dir->fd_dir.d_name, dev->d_ifname, NAME_MAX + 1); + } + + /* Set up the next directory entry offset. NOTE that we could use the + * standard f_pos instead of our own private index. + */ + + level1->base.index = index + 1; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_rewindir + * + * Description: Reset directory read to the first entry + * + ****************************************************************************/ + +static int netprocfs_rewinddir(FAR struct fs_dirent_s *dir) +{ + FAR struct netprocfs_level1_s *priv; + + DEBUGASSERT(dir && dir->u.procfs); + priv = dir->u.procfs; + + priv->base.index = 0; + return OK; +} + +/**************************************************************************** + * Name: netprocfs_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf) +{ + /* Check for the directory "net" */ + + if (strcmp(relpath, "net") == 0) + { + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; + } + else +#ifdef CONFIG_NET_STATISTICS + /* Check for network statistics "net/stat" */ + + if (strcmp(relpath, "net/stat") == 0) + { + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + } + else +#endif + { + FAR struct net_driver_s *dev; + FAR char *devname; + FAR char *copy; + + /* Otherwise, we need to search the list of registered network devices + * to determine if the name corresponds to a network device. + */ + + copy = strdup(relpath); + if (copy == NULL) + { + fdbg("ERROR: strdup failed\n"); + return -ENOMEM; + } + + devname = basename(copy); + dev = netdev_findbyname(devname); + kmm_free(copy); + + if (dev == NULL) + { + fdbg("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + } + + /* File/directory size, access block size */ + + buf->st_size = 0; + buf->st_blksize = 0; + buf->st_blocks = 0; + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_read_linegen + * + * Description: + * Read and format procfs data using a line generation table. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which device status will be + * returned. + * buflen - The size in bytes of the user provided buffer. + * gentab - Table of line generation functions + * nelems - The number of elements in the table + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +ssize_t netprocfs_read_linegen(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen, + FAR const linegen_t *gentab, int nelems) +{ + size_t xfrsize; + ssize_t nreturned; + + fvdbg("buffer=%p buflen=%lu\n", buffer, (unsigned long)buflen); + + /* Is there line data already buffered? */ + + nreturned = 0; + if (priv->linesize > 0) + { + /* Yes, how much can we transfer now? */ + + xfrsize = priv->linesize; + if (xfrsize > buflen) + { + xfrsize = buflen; + } + + /* Transfer the data to the user buffer */ + + memcpy(buffer, &priv->line[priv->offset], xfrsize); + + /* Update pointers, sizes, and offsets */ + + buffer += xfrsize; + buflen -= xfrsize; + + priv->linesize -= xfrsize; + priv->offset += xfrsize; + nreturned = xfrsize; + } + + /* Loop until the user buffer is full or until all of the network + * statistics have been transferred. At this point we know that + * either: + * + * 1. The user buffer is full, and/or + * 2. All of the current line data has been transferred. + */ + + while (buflen > 0 && priv->lineno < nelems) + { + int len; + + /* Read the next line into the working buffer */ + + len = gentab[priv->lineno](priv); + + /* Update line-related information */ + + priv->lineno++; + priv->linesize = len; + priv->offset = 0; + + /* Transfer data to the user buffer */ + + xfrsize = priv->linesize; + if (xfrsize > buflen) + { + xfrsize = buflen; + } + + memcpy(buffer, &priv->line[priv->offset], xfrsize); + + /* Update pointers, sizes, and offsets */ + + buffer += xfrsize; + buflen -= xfrsize; + + priv->linesize -= xfrsize; + priv->offset += xfrsize; + nreturned += xfrsize; + } + + return nreturned; +} + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && + * !CONFIG_FS_PROCFS_EXCLUDE_NET */ diff --git a/net/procfs/net_statistics.c b/net/procfs/net_statistics.c new file mode 100644 index 0000000000000000000000000000000000000000..df35f4a165aea45b9374facffee7cd31ba9d7102 --- /dev/null +++ b/net/procfs/net_statistics.c @@ -0,0 +1,463 @@ +/**************************************************************************** + * net/procfs/net_statistics.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "procfs/procfs.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ + !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) && defined(CONFIG_NET_STATISTICS) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Line generating functions */ + +static int netprocfs_header(FAR struct netprocfs_file_s *netfile); +static int netprocfs_received(FAR struct netprocfs_file_s *netfile); +static int netprocfs_dropped(FAR struct netprocfs_file_s *netfile); +#ifdef CONFIG_NET_IPv4 +static int netprocfs_ipv4_dropped(FAR struct netprocfs_file_s *netfile); +#endif /* CONFIG_NET_IPv4 */ +#ifdef CONFIG_NET_IPv6 +static int netprocfs_ipv6_dropped(FAR struct netprocfs_file_s *netfile); +#endif /* CONFIG_NET_IPv4 */ +static int netprocfs_checksum(FAR struct netprocfs_file_s *netfile); +#ifdef CONFIG_NET_TCP +static int netprocfs_tcp_dropped_1(FAR struct netprocfs_file_s *netfile); +static int netprocfs_tcp_dropped_2(FAR struct netprocfs_file_s *netfile); +#endif /* CONFIG_NET_TCP */ +static int netprocfs_prototype(FAR struct netprocfs_file_s *netfile); +static int netprocfs_sent(FAR struct netprocfs_file_s *netfile); +#ifdef CONFIG_NET_TCP +static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile); +#endif /* CONFIG_NET_TCP */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Line generating functions */ + +static const linegen_t g_linegen[] = +{ + netprocfs_header, + netprocfs_received, + netprocfs_dropped, + +#ifdef CONFIG_NET_IPv4 + netprocfs_ipv4_dropped, +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 + netprocfs_ipv6_dropped, +#endif /* CONFIG_NET_IPv4 */ + + netprocfs_checksum, + +#ifdef CONFIG_NET_TCP + netprocfs_tcp_dropped_1, + netprocfs_tcp_dropped_2, +#endif /* CONFIG_NET_TCP */ + + netprocfs_prototype, + netprocfs_sent + +#ifdef CONFIG_NET_TCP + , netprocfs_retransmissions +#endif /* CONFIG_NET_TCP */ +}; + +#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_header + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_header(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, " "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " IPv4"); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " IPv6"); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " TCP"); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " UDP"); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ICMP"); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ICMPv6"); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_received + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_received(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "Received "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv4.recv); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv6.recv); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.tcp.recv); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.udp.recv); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmp.recv); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmpv6.recv); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_dropped + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_dropped(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "Dropped "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv4.drop); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv6.drop); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.tcp.drop); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.udp.drop); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmp.drop); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmpv6.drop); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_ipv4_dropped + ****************************************************************************/ + +#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_IPv4) +static int netprocfs_ipv4_dropped(FAR struct netprocfs_file_s *netfile) +{ + return snprintf(netfile->line, NET_LINELEN, + " IPv4 VHL: %04x Frg: %04x\n", + g_netstats.ipv4.vhlerr, g_netstats.ipv4.fragerr); +} +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_IPv4 */ + +/**************************************************************************** + * Name: netprocfs_ipv6_dropped + ****************************************************************************/ + +#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_IPv6) +static int netprocfs_ipv6_dropped(FAR struct netprocfs_file_s *netfile) +{ + return snprintf(netfile->line, NET_LINELEN, + " IPv6 VHL: %04x\n", + g_netstats.ipv6.vhlerr); +} +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_IPv6 */ + +/**************************************************************************** + * Name: netprocfs_checksum + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_checksum(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, " Checksum "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv4.chkerr); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.tcp.chkerr); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.udp.chkerr); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_tcp_dropped_1 + ****************************************************************************/ + +#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP) +static int netprocfs_tcp_dropped_1(FAR struct netprocfs_file_s *netfile) +{ + return snprintf(netfile->line, NET_LINELEN, + " TCP ACK: %04x SYN: %04x\n", + g_netstats.tcp.ackerr, g_netstats.tcp.syndrop); +} +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */ + +/**************************************************************************** + * Name: netprocfs_tcp_dropped_2 + ****************************************************************************/ + +#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP) +static int netprocfs_tcp_dropped_2(FAR struct netprocfs_file_s *netfile) +{ + return snprintf(netfile->line, NET_LINELEN, + " RST: %04x %04x\n", + g_netstats.tcp.rst, g_netstats.tcp.synrst); +} +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */ + +/**************************************************************************** + * Name: netprocfs_prototype + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_prototype(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, " Type "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv4.protoerr); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv6.protoerr); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmp.typeerr); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmpv6.typeerr); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_sent + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +static int netprocfs_sent(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "Sent "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv4.sent); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.ipv6.sent); +#endif +#ifdef CONFIG_NET_TCP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.tcp.sent); +#endif +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.udp.sent); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmp.sent); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.icmpv6.sent); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_retransmissions + ****************************************************************************/ + +#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP) +static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile) +{ + int len = 0; + + len += snprintf(&netfile->line[len], NET_LINELEN - len, " Rexmit "); +#ifdef CONFIG_NET_IPv4 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_IPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif + len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x", + g_netstats.tcp.rexmit); +#ifdef CONFIG_NET_UDP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_ICMP + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif +#ifdef CONFIG_NET_ICMPv6 + len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----"); +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} +#endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_read_netstats + * + * Description: + * Read and format network layer statistics. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which network status will be + * returned. + * bulen - The size in bytes of the user provided buffer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen) +{ + return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES); +} + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && + * !CONFIG_FS_PROCFS_EXCLUDE_NET */ diff --git a/net/procfs/netdev_statistics.c b/net/procfs/netdev_statistics.c new file mode 100644 index 0000000000000000000000000000000000000000..80154c91faadc20b94e10ea53e0b9929f8c4f4b9 --- /dev/null +++ b/net/procfs/netdev_statistics.c @@ -0,0 +1,472 @@ +/**************************************************************************** + * net/procfs/netdev_statistics.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include + +#include "netdev/netdev.h" +#include "utils/utils.h" +#include "procfs/procfs.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ + !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile); +static int netprocfs_ipaddresses(FAR struct netprocfs_file_s *netfile); + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_rxstatistics_header(FAR struct netprocfs_file_s *netfile); +static int netprocfs_rxstatistics(FAR struct netprocfs_file_s *netfile); +static int netprocfs_rxpackets_header(FAR struct netprocfs_file_s *netfile); +static int netprocfs_rxpackets(FAR struct netprocfs_file_s *netfile); +static int netprocfs_txstatistics_header(FAR struct netprocfs_file_s *netfile); +static int netprocfs_txstatistics(FAR struct netprocfs_file_s *netfile); +static int netprocfs_errors(FAR struct netprocfs_file_s *netfile); +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Line generating functions */ + +static const linegen_t g_linegen[] = +{ + netprocfs_linklayer, + netprocfs_ipaddresses +#ifdef CONFIG_NETDEV_STATISTICS + , netprocfs_rxstatistics_header, + netprocfs_rxstatistics, + netprocfs_rxpackets_header, + netprocfs_rxpackets, + netprocfs_txstatistics_header, + netprocfs_txstatistics, + netprocfs_errors +#endif /* CONFIG_NETDEV_STATISTICS */ +}; + +#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_linklayer + ****************************************************************************/ + +static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile) +{ + FAR struct net_driver_s *dev; + FAR const char *status; + int len = 0; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + + /* Get the interface status: RUNNING, UP, or DOWN */ + + if ((dev->d_flags & IFF_RUNNING) != 0) + { + status = "RUNNING"; + } + else if ((dev->d_flags & IFF_UP) != 0) + { + status = "UP"; + } + else + { + status = "DOWN"; + } + +#if defined(CONFIG_NET_MULTILINK) + /* If there are multiple link types being supported, then selected the + * output appropriate for the link type associated with this device. + */ + + switch (dev->d_lltype) + { +#ifdef CONFIG_NET_ETHERNET + case NET_LL_ETHERNET: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:Ethernet HWaddr %s", + dev->d_ifname, ether_ntoa(&dev->d_mac)); + break; +#endif + +#ifdef CONFIG_NET_LOOPBACK + case NET_LL_LOOPBACK: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:Local Loopback", + dev->d_ifname); + break; +#endif + +#ifdef CONFIG_NET_SLIP + case NET_LL_SLIP: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:SLIP", dev->d_ifname); + break; +#endif + +#ifdef CONFIG_NET_PPP + case NET_LL_PPP: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:P-t-P", dev->d_ifname); + break; +#endif + +#ifdef CONFIG_NET_TUN + case NET_LL_TUN: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:TUN", dev->d_ifname); + break; +#endif + + default: + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:UNSPEC", dev->d_ifname); + } + + len += snprintf(&netfile->line[len], NET_LINELEN - len, + " at %s\n", status); + +#elif defined(CONFIG_NET_ETHERNET) + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:Ethernet HWaddr %s at %s\n", + dev->d_ifname, ether_ntoa(&dev->d_mac), status); + +#elif defined(CONFIG_NET_LOOPBACK) + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:Local Loopback at %s\n", + dev->d_ifname, status); + +#elif defined(CONFIG_NET_SLIP) + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:SLIP at %s\n", + dev->d_ifname, status); + +#elif defined(CONFIG_NET_PPP) + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:P-t-P at %s\n", + dev->d_ifname, status); + +#elif defined(CONFIG_NET_TUN) + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "%s\tLink encap:TUN at %s\n", + dev->d_ifname, status); +#endif + + return len; +} + +/**************************************************************************** + * Name: netprocfs_ipaddresses + ****************************************************************************/ + +static int netprocfs_ipaddresses(FAR struct netprocfs_file_s *netfile) +{ + FAR struct net_driver_s *dev; +#ifdef CONFIG_NET_IPv4 + struct in_addr addr; +#endif +#ifdef CONFIG_NET_IPv6 + char addrstr[INET6_ADDRSTRLEN]; + uint8_t preflen; +#endif + int len = 0; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + +#ifdef CONFIG_NET_IPv4 + /* Show the IPv4 address */ + + addr.s_addr = dev->d_ipaddr; + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "\tinet addr:%s ", inet_ntoa(addr)); + + /* Show the IPv4 default router address */ + + addr.s_addr = dev->d_draddr; + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "DRaddr:%s ", inet_ntoa(addr)); + + /* Show the IPv4 network mask */ + + addr.s_addr = dev->d_netmask; + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "Mask:%s\n", inet_ntoa(addr)); +#endif + +#ifdef CONFIG_NET_IPv6 + /* Convert the 128 network mask to a human friendly prefix length */ + + preflen = net_ipv6_mask2pref(dev->d_ipv6netmask); + + /* Show the assigned IPv6 address */ + + if (inet_ntop(AF_INET6, dev->d_ipv6addr, addrstr, INET6_ADDRSTRLEN)) + { + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "\tinet6 addr:%s/%d\n", addrstr, preflen); + } + + /* REVISIT: Show the IPv6 default router address */ + + if (inet_ntop(AF_INET6, dev->d_ipv6draddr, addrstr, INET6_ADDRSTRLEN)) + { + len += snprintf(&netfile->line[len], NET_LINELEN - len, + "\tinet6 DRaddr:%s/%d\n", addrstr, preflen); + } +#endif + + len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n"); + return len; +} + +/**************************************************************************** + * Name: netprocfs_rxstatistics_header + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_rxstatistics_header(FAR struct netprocfs_file_s *netfile) +{ + DEBUGASSERT(netfile != NULL); + return snprintf(netfile->line, NET_LINELEN , "\tRX: %-8s %-8s %-8s\n", + "Received", "Fragment", "Errors"); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_rxstatistics + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_rxstatistics(FAR struct netprocfs_file_s *netfile) +{ + FAR struct netdev_statistics_s *stats; + FAR struct net_driver_s *dev; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + stats = &dev->d_statistics; + + return snprintf(netfile->line, NET_LINELEN, "\t %08lx %08lx %08lx\n", + (unsigned long)stats->rx_packets, + (unsigned long)stats->rx_fragments, + (unsigned long)stats->rx_errors); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_rxpackets_header + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_rxpackets_header(FAR struct netprocfs_file_s *netfile) +{ + FAR char *fmt; + + DEBUGASSERT(netfile != NULL); + + fmt = "\t " +#ifdef CONFIG_NET_IPv4 + "%-8s " +#endif +#ifdef CONFIG_NET_IPv6 + "%-8s " +#endif +#ifdef CONFIG_NET_ARP + "%-8s " +#endif + "%-8s\n"; + + return snprintf(netfile->line, NET_LINELEN, fmt +#ifdef CONFIG_NET_IPv4 + , "IPv4" +#endif +#ifdef CONFIG_NET_IPv6 + , "IPv6" +#endif +#ifdef CONFIG_NET_ARP + , "ARP" +#endif + , "Dropped"); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_rxpackets + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_rxpackets(FAR struct netprocfs_file_s *netfile) +{ + FAR struct netdev_statistics_s *stats; + FAR struct net_driver_s *dev; + FAR char *fmt; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + stats = &dev->d_statistics; + + fmt = "\t " +#ifdef CONFIG_NET_IPv4 + "%08lx " +#endif +#ifdef CONFIG_NET_IPv6 + "%08lx " +#endif +#ifdef CONFIG_NET_ARP + "%08lx " +#endif + "%08lx\n"; + + return snprintf(netfile->line, NET_LINELEN, fmt +#ifdef CONFIG_NET_IPv4 + , (unsigned long)stats->rx_ipv4 +#endif +#ifdef CONFIG_NET_IPv6 + , (unsigned long)stats->rx_ipv6 +#endif +#ifdef CONFIG_NET_ARP + , (unsigned long)stats->rx_arp +#endif + , (unsigned long)stats->rx_dropped); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_txstatistics_header + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_txstatistics_header(FAR struct netprocfs_file_s *netfile) +{ + DEBUGASSERT(netfile != NULL); + + return snprintf(netfile->line, NET_LINELEN, "\tTX: %-8s %-8s %-8s %-8s\n", + "Queued", "Sent", "Erorts", "Timeouts"); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_txstatistics + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_txstatistics(FAR struct netprocfs_file_s *netfile) +{ + FAR struct netdev_statistics_s *stats; + FAR struct net_driver_s *dev; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + stats = &dev->d_statistics; + + return snprintf(netfile->line, NET_LINELEN, "\t %08lx %08lx %08lx %08lx\n", + (unsigned long)stats->tx_packets, + (unsigned long)stats->tx_done, + (unsigned long)stats->tx_errors, + (unsigned long)stats->tx_timeouts); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Name: netprocfs_errors + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_STATISTICS +static int netprocfs_errors(FAR struct netprocfs_file_s *netfile) +{ + FAR struct netdev_statistics_s *stats; + FAR struct net_driver_s *dev; + + DEBUGASSERT(netfile != NULL && netfile->dev != NULL); + dev = netfile->dev; + stats = &dev->d_statistics; + + return snprintf(netfile->line, NET_LINELEN , "\tTotal Errors: %08x\n\n", + (unsigned long)stats->errors); +} +#endif /* CONFIG_NETDEV_STATISTICS */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_read_devstats + * + * Description: + * Read and format network device statistics. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which device status will be + * returned. + * bulen - The size in bytes of the user provided buffer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +ssize_t netprocfs_read_devstats(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen) +{ + return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES); +} + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && + * !CONFIG_FS_PROCFS_EXCLUDE_NET */ diff --git a/net/procfs/procfs.h b/net/procfs/procfs.h new file mode 100644 index 0000000000000000000000000000000000000000..889f35072561bba10b62dec76b2d3ea9a6f8b29f --- /dev/null +++ b/net/procfs/procfs.h @@ -0,0 +1,178 @@ +/**************************************************************************** + * net/procfs/procfs.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __NET_PROCFS_PROCFS_H +#define __NET_PROCFS_PROCFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define NET_LINELEN 64 + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct net_driver_s; /* Forward reference */ +struct netprocfs_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + FAR struct net_driver_s *dev; /* Current network device */ + uint8_t lineno; /* Line number */ + uint8_t linesize; /* Number of valid characters in line[] */ + uint8_t offset; /* Offset to first valid character in line[] */ + char line[NET_LINELEN]; /* Pre-allocated buffer for formatted lines */ +}; + +/* Level 1 is the directory of attributes */ + +struct netprocfs_level1_s +{ + struct procfs_dir_priv_s base; /* Base directory private data */ + char name[NAME_MAX + 1]; /* Name of last node visited */ +}; + +/* Line generating function type */ + +typedef int (*linegen_t)(FAR struct netprocfs_file_s *netfile); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: netprocfs_read_linegen + * + * Description: + * Read and format procfs data using a line generation table. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which device status will be + * returned. + * buflen - The size in bytes of the user provided buffer. + * gentab - Table of line generation functions + * nelems - The number of elements in the table + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +ssize_t netprocfs_read_linegen(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen, + FAR const linegen_t *gentab, int nelems); + +/**************************************************************************** + * Name: netprocfs_read_netstats + * + * Description: + * Read and format network layer statistics. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which network status will be + * returned. + * bulen - The size in bytes of the user provided buffer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_STATISTICS +ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen); +#endif + +/**************************************************************************** + * Name: netprocfs_read_devstats + * + * Description: + * Read and format network device statistics. + * + * Input Parameters: + * priv - A reference to the network procfs file structure + * buffer - The user-provided buffer into which device status will be + * returned. + * bulen - The size in bytes of the user provided buffer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +ssize_t netprocfs_read_devstats(FAR struct netprocfs_file_s *priv, + FAR char *buffer, size_t buflen); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_FS_PROCFS && !CONFIG_FS_PROCFS_EXCLUDE_NET */ +#endif /* __NET_PROCFS_PROCFS_H */ diff --git a/net/route/net_addroute.c b/net/route/net_addroute.c index 7ff316660dbb2e415b58ce28ee675159082fd764..bf9ea3f3df9e4ef691aca51037d05286a6ce18a9 100644 --- a/net/route/net_addroute.c +++ b/net/route/net_addroute.c @@ -53,14 +53,6 @@ #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/route/net_delroute.c b/net/route/net_delroute.c index 9e31768ff521408c346f0f01b9e9a1f7d974dd25..1efbb0e18eb6abb38a2766d71d2a7fdbfdc47768 100644 --- a/net/route/net_delroute.c +++ b/net/route/net_delroute.c @@ -93,7 +93,7 @@ struct route_match_ipv6_s #ifdef CONFIG_NET_IPv4 static int net_match(FAR struct net_route_s *route, FAR void *arg) { - FAR struct route_match_s *match = ( FAR struct route_match_s *)arg; + FAR struct route_match_s *match = (FAR struct route_match_s *)arg; /* To match, the masked target address must be the same, and the masks * must be the same. @@ -133,7 +133,7 @@ static int net_match(FAR struct net_route_s *route, FAR void *arg) #ifdef CONFIG_NET_IPv6 static int net_match_ipv6(FAR struct net_route_ipv6_s *route, FAR void *arg) { - FAR struct route_match_ipv6_s *match = ( FAR struct route_match_ipv6_s *)arg; + FAR struct route_match_ipv6_s *match = (FAR struct route_match_ipv6_s *)arg; /* To match, the masked target address must be the same, and the masks * must be the same. diff --git a/net/route/net_foreachroute.c b/net/route/net_foreachroute.c index 41cd1245a31e85f65b83386ae460f6a91ccb0fe1..13c154f539e0a895156ff2de972c32a622143142 100644 --- a/net/route/net_foreachroute.c +++ b/net/route/net_foreachroute.c @@ -50,10 +50,6 @@ #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/route/net_router.c b/net/route/net_router.c index d0bd3eb0b2b1109d785e14d9916b2ee26e47c6ce..a72990e37da32b7b123850bc417fe9ac9b0d4dca 100644 --- a/net/route/net_router.c +++ b/net/route/net_router.c @@ -60,7 +60,7 @@ struct route_ipv4_match_s { in_addr_t target; /* Target IPv4 address on an external network to match */ - in_addr_t router; /* IPv4 address of the router on one of our networks*/ + in_addr_t router; /* IPv4 address of the router on one of our networks */ }; #endif @@ -68,7 +68,7 @@ struct route_ipv4_match_s struct route_ipv6_match_s { net_ipv6addr_t target; /* Target IPv6 address on an external network to match */ - net_ipv6addr_t router; /* IPv6 address of the router on one of our networks*/ + net_ipv6addr_t router; /* IPv6 address of the router on one of our networks */ }; #endif diff --git a/net/route/netdev_router.c b/net/route/netdev_router.c index fda212c66443c76242af162b0b9322d9c755817a..d76a4e52b74fb5c24fd799fdb6c1a5602256057f 100644 --- a/net/route/netdev_router.c +++ b/net/route/netdev_router.c @@ -60,7 +60,7 @@ struct route_ipv4_devmatch_s { FAR struct net_driver_s *dev; /* The route must use this device */ in_addr_t target; /* Target IPv4 address on an external network to match */ - in_addr_t router; /* IPv6 address of the router on one of our networks*/ + in_addr_t router; /* IPv6 address of the router on one of our networks */ }; #endif @@ -69,7 +69,7 @@ struct route_ipv6_devmatch_s { FAR struct net_driver_s *dev; /* The route must use this device */ net_ipv6addr_t target; /* Target IPv4 address on an external network to match */ - net_ipv6addr_t router; /* IPv6 address of the router on one of our networks*/ + net_ipv6addr_t router; /* IPv6 address of the router on one of our networks */ }; #endif diff --git a/net/socket/Make.defs b/net/socket/Make.defs index ca4dab4d77fcea542eaf6db5eb0c09c08d0b96a7..cfb6233bd1f6b73a235acaea62ba25e8d53b4631 100644 --- a/net/socket/Make.defs +++ b/net/socket/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # net/socket/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -35,21 +35,19 @@ # Include socket source files -SOCK_CSRCS += bind.c connect.c getsockname.c recv.c recvfrom.c socket.c -SOCK_CSRCS += sendto.c net_sockets.c net_close.c net_dupsd.c net_dupsd2.c -SOCK_CSRCS += net_clone.c net_poll.c net_vfcntl.c +SOCK_CSRCS += bind.c connect.c getsockname.c recv.c recvfrom.c send.c +SOCK_CSRCS += sendto.c socket.c net_sockets.c net_close.c net_dupsd.c +SOCK_CSRCS += net_dupsd2.c net_clone.c net_poll.c net_vfcntl.c # TCP/IP support ifeq ($(CONFIG_NET_TCP),y) -SOCK_CSRCS += send.c listen.c accept.c net_monitor.c -else +SOCK_CSRCS += listen.c accept.c net_monitor.c # Local Unix domain support -ifeq ($(CONFIG_NET_LOCAL_STREAM),y) -SOCK_CSRCS += send.c listen.c accept.c -endif +else ifeq ($(CONFIG_NET_LOCAL_STREAM),y) +SOCK_CSRCS += listen.c accept.c endif # Socket options diff --git a/net/socket/accept.c b/net/socket/accept.c index 83cd9602cce23f96ae86e078773a97a89d782641..ea1e887bf9a92bd3df10fe7da58880700f0cb774 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -54,10 +54,6 @@ #include "local/local.h" #include "socket/socket.h" -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/socket/bind.c b/net/socket/bind.c index c577dd8c26ea68c2666009ca9afef2f0dcdd0380..8095c7180777a846c848693c2bbe038303eff280 100644 --- a/net/socket/bind.c +++ b/net/socket/bind.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/bind.c * - * Copyright (C) 2007-2009, 2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -86,9 +86,15 @@ static int pkt_bind(FAR struct pkt_conn_s *conn, { int ifindex; #if 0 - char hwaddr[6] = {0x00, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1}; /* our MAC for debugging */ + char hwaddr[6] = /* our MAC for debugging */ + { + 0x00, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1 + }; #endif - char hwaddr[6] = {0x00, 0xe0, 0xde, 0xad, 0xbe, 0xef}; /* MAC from ifconfig */ + char hwaddr[6] = /* MAC from ifconfig */ + { + 0x00, 0xe0, 0xde, 0xad, 0xbe, 0xef + }; /* Look at the addr and identify network interface */ @@ -310,7 +316,7 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr, return OK; errout: - *get_errno_ptr() = err; + set_errno(err); return ERROR; } diff --git a/net/socket/connect.c b/net/socket/connect.c index 7360d611c6ad5fb05af1643e26e6d2c982d11b3c..cbd19e177450523f0f9f69895122592c69748fd1 100644 --- a/net/socket/connect.c +++ b/net/socket/connect.c @@ -121,7 +121,7 @@ static inline int psock_setup_callbacks(FAR struct socket *psock, pstate->tc_cb->flags = (TCP_NEWDATA | TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT | TCP_CONNECTED | NETDEV_DOWN); - pstate->tc_cb->priv = (void*)pstate; + pstate->tc_cb->priv = (FAR void *)pstate; pstate->tc_cb->event = psock_connect_interrupt; ret = OK; } @@ -217,7 +217,7 @@ static uint16_t psock_connect_interrupt(FAR struct net_driver_s *dev, else if ((flags & TCP_TIMEDOUT) != 0) { - /* Indicate that the connection timedout?)*/ + /* Indicate that the connection timedout?) */ pstate->tc_result = -ETIMEDOUT; } @@ -278,22 +278,32 @@ static uint16_t psock_connect_interrupt(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 - if (pstate->tc_conn->domain == PF_INET) + if (pstate->tc_conn->domain == PF_INET) #endif - { - pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev); - } + { + pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev); + } #endif /* CONFIG_NET_IPv4 */ #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else + else #endif - { - pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev); - } + { + pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev); + } #endif /* CONFIG_NET_IPv6 */ +#ifdef CONFIG_NETDEV_MULTINIC + /* We now have to filter all outgoing transfers so that they use only + * the MSS of this device. + */ + + DEBUGASSERT(pstate->tc_conn->dev == NULL || + pstate->tc_conn->dev == dev); + pstate->tc_conn->dev = dev; + +#endif /* CONFIG_NETDEV_MULTINIC */ #endif /* CONFIG_NET_MULTILINK */ /* Wake up the waiting thread */ @@ -621,6 +631,14 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr, #endif { ret = udp_connect(psock->s_conn, addr); + if (ret < 0 || addr == NULL) + { + psock->s_flags &= ~_SF_CONNECTED; + } + else + { + psock->s_flags |= _SF_CONNECTED; + } } #endif /* CONFIG_NET_UDP */ diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c index 2a9223f5ff466a122d9ae8042b8f0b5654bf7b0b..b6b8eebcee8e6fb92aa9eeb906704acd64e44601 100644 --- a/net/socket/getsockname.c +++ b/net/socket/getsockname.c @@ -228,14 +228,14 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr, /* Check if enough space has been provided for the full address */ if (*addrlen < sizeof(struct sockaddr_in6)) - { - /* This function is supposed to return the partial address if - * a smaller buffer has been provided. This support has not - * been implemented. - */ - - return -ENOSYS; - } + { + /* This function is supposed to return the partial address if + * a smaller buffer has been provided. This support has not + * been implemented. + */ + + return -ENOSYS; + } /* Set the port number */ diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c index 2af5dce60c2f0b914d64e5978cb595a6d72f3687..c2236e7591052fe909cb627b5243a17ce1ebe6be 100644 --- a/net/socket/getsockopt.c +++ b/net/socket/getsockopt.c @@ -141,9 +141,9 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option, * a macro will do. */ - optionset = psock->s_options; - *(int*)value = _SO_GETOPT(optionset, option); - *value_len = sizeof(int); + optionset = psock->s_options; + *(FAR int *)value = _SO_GETOPT(optionset, option); + *value_len = sizeof(int); } break; @@ -161,8 +161,8 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option, /* Return the socket type */ - *(int*)value = psock->s_type; - *value_len = sizeof(int); + *(FAR int *)value = psock->s_type; + *value_len = sizeof(int); } break; diff --git a/net/socket/net_close.c b/net/socket/net_close.c index 499eee7c5df1631e9ecc90bdd5974da63dd3efd0..f439811b854b1cf6453efa56a78f2b1fea90a5ff 100644 --- a/net/socket/net_close.c +++ b/net/socket/net_close.c @@ -66,10 +66,6 @@ #include "local/local.h" #include "socket/socket.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -82,7 +78,7 @@ struct tcp_close_s FAR struct socket *cl_psock; /* Reference to the TCP socket */ sem_t cl_sem; /* Signals disconnect completion */ int cl_result; /* The result of the close */ - uint32_t cl_start; /* Time close started (in ticks) */ + systime_t cl_start; /* Time close started (in ticks) */ #endif }; #endif @@ -117,17 +113,17 @@ static inline int close_timeout(FAR struct tcp_close_s *pstate) if (pstate) { - /* Yes Check for a timeout configured via setsockopts(SO_LINGER). - * If none... we well let the send wait forever. - */ + /* Yes Check for a timeout configured via setsockopts(SO_LINGER). + * If none... we well let the send wait forever. + */ - psock = pstate->cl_psock; - if (psock && psock->s_linger != 0) - { - /* Check if the configured timeout has elapsed */ + psock = pstate->cl_psock; + if (psock && psock->s_linger != 0) + { + /* Check if the configured timeout has elapsed */ - return net_timeo(pstate->cl_start, psock->s_linger); - } + return net_timeo(pstate->cl_start, psock->s_linger); + } } /* No timeout */ @@ -179,7 +175,7 @@ static uint16_t netclose_interrupt(FAR struct net_driver_s *dev, /* The disconnection is complete */ #ifdef CONFIG_NET_SOLINGER - /* pstate non-NULL means that we are performing a LINGERing close.*/ + /* pstate non-NULL means that we are performing a LINGERing close. */ if (pstate) { @@ -223,7 +219,7 @@ static uint16_t netclose_interrupt(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Check if all outstanding bytes have been ACKed */ - else if (conn->unacked != 0) + else if (conn->unacked != 0 || !sq_empty(&conn->write_q)) { /* No... we are still waiting for ACKs. Drop any received data, but * do not yet report TCP_CLOSE in the response. @@ -357,14 +353,11 @@ static inline int netclose_disconnect(FAR struct socket *psock) #ifdef CONFIG_NET_TCP_WRITE_BUFFERS if (psock->s_sndcb) { - tcp_callback_free(conn, psock->s_sndcb); psock->s_sndcb = NULL; } #endif - /* There shouldn't be any callbacks registered. */ - - DEBUGASSERT(conn && conn->list == NULL); + DEBUGASSERT(conn != NULL); /* Check for the case where the host beat us and disconnected first */ @@ -527,9 +520,12 @@ int psock_close(FAR struct socket *psock) /* We perform the uIP close operation only if this is the last count on * the socket. (actually, I think the socket crefs only takes the values * 0 and 1 right now). + * + * It is possible for a psock to have no connection, e.g. a TCP socket + * waiting in accept. */ - if (psock->s_crefs <= 1) + if (psock->s_crefs <= 1 && psock->s_conn != NULL) { /* Perform uIP side of the close depending on the protocol type */ diff --git a/net/socket/net_dupsd.c b/net/socket/net_dupsd.c index 6381c45d52877a791669cd9b1c4c8ddfe62d236c..85d9b6f9356fcf80b95abfd257e5d8013327bae3 100644 --- a/net/socket/net_dupsd.c +++ b/net/socket/net_dupsd.c @@ -48,10 +48,6 @@ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -99,7 +95,7 @@ int net_dupsd(int sockfd, int minsd) psock1 = sockfd_socket(sockfd); - /* Verify that the sockfd corresponds to valid, allocated socket */ + /* Verify that the sockfd corresponds to valid, allocated socket */ if (!psock1 || psock1->s_crefs <= 0) { diff --git a/net/socket/net_monitor.c b/net/socket/net_monitor.c index a57308cbcc7caf4ef6a11ee9f6259e8b70114622..3e6cf0c2ae318fe1d69095fb33cc2b423c82ee6e 100644 --- a/net/socket/net_monitor.c +++ b/net/socket/net_monitor.c @@ -50,10 +50,6 @@ #include "tcp/tcp.h" #include "socket/socket.h" -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -66,6 +62,7 @@ static uint16_t connection_event(FAR struct net_driver_s *dev, /**************************************************************************** * Private Functions ****************************************************************************/ + /**************************************************************************** * Name: connection_closed * @@ -117,7 +114,7 @@ static void connection_closed(FAR struct socket *psock, uint16_t flags) * be reported as an ENOTCONN error. */ - psock->s_flags &= ~(_SF_CONNECTED |_SF_CLOSED); + psock->s_flags &= ~(_SF_CONNECTED | _SF_CLOSED); } } @@ -163,6 +160,24 @@ static uint16_t connection_event(FAR struct net_driver_s *dev, else if ((flags & TCP_CONNECTED) != 0) { +#if 0 /* REVISIT: Assertion fires. Why? */ +#ifdef CONFIG_NETDEV_MULTINIC + FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; + + /* Make sure that this is the device bound to the connection */ + + DEBUGASSERT(conn->dev == NULL || conn->dev == dev); + conn->dev = dev; +#endif +#endif + + /* If there is no local address assigned to the socket (perhaps + * because it was INADDR_ANY), then assign it the address of the + * connecting device. + * + * TODO: Implement this. + */ + /* Indicate that the socket is now connected */ psock->s_flags |= _SF_CONNECTED; @@ -244,7 +259,7 @@ int net_startmonitor(FAR struct socket *psock) if (cb != NULL) { cb->event = connection_event; - cb->priv = (void*)psock; + cb->priv = (FAR void *)psock; cb->flags = NETDEV_DOWN; } @@ -252,7 +267,7 @@ int net_startmonitor(FAR struct socket *psock) /* Set up to receive callbacks on connection-related events */ - conn->connection_private = (void*)psock; + conn->connection_private = (FAR void *)psock; conn->connection_event = connection_event; net_unlock(save); diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c index 2f6c3c9bb529a85a6389c5037beab6d2d18852c4..a8b7b9f16284d902611ef61e20e3899bff95ebbd 100644 --- a/net/socket/net_sendfile.c +++ b/net/socket/net_sendfile.c @@ -2,7 +2,7 @@ * net/socket/net_sendfile.c * * Copyright (C) 2013 UVC Ingenieure. All rights reserved. - * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2016 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * Max Holtzberg * @@ -103,7 +103,7 @@ struct sendfile_s uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ #ifdef CONFIG_NET_SOCKOPTS - uint32_t snd_time; /* Last send time for determining timeout */ + systime_t snd_time; /* Last send time for determining timeout */ #endif }; @@ -320,10 +320,22 @@ static inline bool sendfile_addrcheck(FAR struct tcp_conn_s *conn) static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvconn, FAR void *pvpriv, uint16_t flags) { - FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s*)pvconn; + FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn; FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv; int ret; +#ifdef CONFIG_NETDEV_MULTINIC + /* The TCP socket is connected and, hence, should be bound to a device. + * Make sure that the polling device is the own that we are bound to. + */ + + DEBUGASSERT(conn->dev != NULL); + if (dev != conn->dev) + { + return flags; + } +#endif + nllvdbg("flags: %04x acked: %d sent: %d\n", flags, pstate->snd_acked, pstate->snd_sent); @@ -354,9 +366,9 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon uint32_t sndlen = pstate->snd_flen - pstate->snd_sent; - if (sndlen > tcp_mss(conn)) + if (sndlen > conn->mss) { - sndlen = tcp_mss(conn); + sndlen = conn->mss; } /* Check if we have "space" in the window */ @@ -708,7 +720,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, /* Set up the ACK callback in the connection */ state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS); - state.snd_ackcb->priv = (void*)&state; + state.snd_ackcb->priv = (FAR void *)&state; state.snd_ackcb->event = ack_interrupt; /* Perform the TCP send operation */ @@ -716,7 +728,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, do { state.snd_datacb->flags = TCP_POLL; - state.snd_datacb->priv = (void*)&state; + state.snd_datacb->priv = (FAR void *)&state; state.snd_datacb->event = sendfile_interrupt; /* Notify the device driver of the availability of TX data */ @@ -732,15 +744,15 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, tcp_callback_free(conn, state.snd_ackcb); - errout_datacb: +errout_datacb: tcp_callback_free(conn, state.snd_datacb); - errout_locked: +errout_locked: sem_destroy(&state. snd_sem); net_unlock(save); - errout: +errout: if (err) { diff --git a/net/socket/net_sockets.c b/net/socket/net_sockets.c index 6c7e1d11284def4e812b5094c1469e0e9610fd5a..31274117c7307eb1935df46e7477b6fdf40ad85c 100644 --- a/net/socket/net_sockets.c +++ b/net/socket/net_sockets.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/net_sockets.c * - * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,22 +53,6 @@ #if CONFIG_NSOCKET_DESCRIPTORS > 0 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -83,7 +67,7 @@ static void _net_semtake(FAR struct socketlist *list) * the wait was awakened by a signal. */ - ASSERT(*get_errno_ptr() == EINTR); + DEBUGASSERT(get_errno() == EINTR); } } @@ -217,7 +201,7 @@ int sockfd_allocate(int minsd) void sock_release(FAR struct socket *psock) { -#if CONFIG_DEBUG +#ifdef CONFIG_DEBUG if (psock) #endif { @@ -297,7 +281,7 @@ FAR struct socket *sockfd_socket(int sockfd) FAR struct socketlist *list; int ndx = sockfd - __SOCKFD_OFFSET; - if (ndx >=0 && ndx < CONFIG_NSOCKET_DESCRIPTORS) + if (ndx >= 0 && ndx < CONFIG_NSOCKET_DESCRIPTORS) { list = sched_getsockets(); if (list) diff --git a/net/socket/net_timeo.c b/net/socket/net_timeo.c index 70f670dacdd3481aa369b649dbb5086df8e203e1..47099d205d5928c7637ab4e6892f4aa081384593 100644 --- a/net/socket/net_timeo.c +++ b/net/socket/net_timeo.c @@ -69,10 +69,10 @@ * ****************************************************************************/ -int net_timeo(uint32_t start_time, socktimeo_t timeo) +int net_timeo(systime_t start_time, socktimeo_t timeo) { - uint32_t timeo_ticks = DSEC2TICK(timeo); - uint32_t elapsed = clock_systimer() - start_time; + systime_t timeo_ticks = DSEC2TICK(timeo); + systime_t elapsed = clock_systimer() - start_time; if (elapsed >= timeo_ticks) { diff --git a/net/socket/net_vfcntl.c b/net/socket/net_vfcntl.c index 5341328a7b97405353b7490afe1fab67761a84a8..d6fd76f20b51ba5a269469206bada1e57b55369f 100644 --- a/net/socket/net_vfcntl.c +++ b/net/socket/net_vfcntl.c @@ -52,10 +52,6 @@ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index cf26072ac98fb75c8ff238b8f9de9f56b9107864..a6921315fd1b64a276ba724add4b6ac2c7fab4e7 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/recvfrom.c * - * Copyright (C) 2007-2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -88,12 +88,12 @@ * Private Types ****************************************************************************/ -#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) +#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) || defined(CONFIG_NET_PKT) struct recvfrom_s { FAR struct socket *rf_sock; /* The parent socket structure */ #ifdef CONFIG_NET_SOCKOPTS - uint32_t rf_starttime; /* rcv start time for determining timeout */ + systime_t rf_starttime; /* rcv start time for determining timeout */ #endif FAR struct devif_callback_s *rf_cb; /* Reference to callback instance */ sem_t rf_sem; /* Semaphore signals recv completion */ @@ -101,7 +101,7 @@ struct recvfrom_s uint8_t *rf_buffer; /* Pointer to receive buffer */ FAR struct sockaddr *rf_from; /* Address of sender */ FAR socklen_t *rf_fromlen; /* Number of bytes allocated for address of sender */ - size_t rf_recvlen; /* The received length */ + ssize_t rf_recvlen; /* The received length */ int rf_result; /* Success:OK, failure:negated errno */ }; #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */ @@ -110,6 +110,39 @@ struct recvfrom_s * Private Functions ****************************************************************************/ +/**************************************************************************** + * Function: recvfrom_add_recvlen + * + * Description: + * Update information about space available for new data and update size + * of data in buffer, This logic accounts for the case where + * recvfrom_udpreadahead() sets state.rf_recvlen == -1 . + * + * Parameters: + * pstate recvfrom state structure + * recvlen size of new data appended to buffer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) || defined(CONFIG_NET_PKT) + +static inline void recvfrom_add_recvlen(FAR struct recvfrom_s *pstate, + size_t recvlen) +{ + if (pstate->rf_recvlen < 0) + { + pstate->rf_recvlen = 0; + } + + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; +} +#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP || CONFIG_NET_PKT */ + /**************************************************************************** * Function: recvfrom_newdata * @@ -124,7 +157,7 @@ struct recvfrom_s * The number of bytes taken from the packet. * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -152,9 +185,7 @@ static size_t recvfrom_newdata(FAR struct net_driver_s *dev, /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); return recvlen; } @@ -174,7 +205,7 @@ static size_t recvfrom_newdata(FAR struct net_driver_s *dev, * None. * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -200,9 +231,7 @@ static void recvfrom_newpktdata(FAR struct net_driver_s *dev, /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buffer -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); } #endif /* CONFIG_NET_PKT */ @@ -220,7 +249,7 @@ static void recvfrom_newpktdata(FAR struct net_driver_s *dev, * None. * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -236,8 +265,8 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev, * add it to the read-ahead buffers. */ - if (recvlen < dev->d_len) - { + if (recvlen < dev->d_len) + { #ifdef CONFIG_NET_TCP_READAHEAD FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->rf_sock->s_conn; FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen; @@ -292,7 +321,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev, * None. * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -324,7 +353,7 @@ static inline void recvfrom_newudpdata(FAR struct net_driver_s *dev, * None * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -353,9 +382,7 @@ static inline void recvfrom_tcpreadahead(struct recvfrom_s *pstate) /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; + recvfrom_add_recvlen(pstate, recvlen); /* If we took all of the ata from the I/O buffer chain is empty, then * release it. If there is still data available in the I/O buffer @@ -404,8 +431,9 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate) * buffer. */ - if ((iob = iob_peek_queue(&conn->readahead)) != NULL && - pstate->rf_buflen > 0) + pstate->rf_recvlen = -1; + + if ((iob = iob_peek_queue(&conn->readahead)) != NULL) { FAR struct iob_s *tmp; uint8_t src_addr_size; @@ -422,12 +450,12 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate) goto out; } - if ( 0 + if (0 #ifdef CONFIG_NET_IPv6 - || src_addr_size == sizeof(struct sockaddr_in6) + || src_addr_size == sizeof(struct sockaddr_in6) #endif #ifdef CONFIG_NET_IPv4 - || src_addr_size == sizeof(struct sockaddr_in) + || src_addr_size == sizeof(struct sockaddr_in) #endif ) { @@ -445,16 +473,23 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate) } } - recvlen = iob_copyout(pstate->rf_buffer, iob, pstate->rf_buflen, - src_addr_size + sizeof(uint8_t)); + if (pstate->rf_buflen > 0) + { + recvlen = iob_copyout(pstate->rf_buffer, iob, pstate->rf_buflen, + src_addr_size + sizeof(uint8_t)); - nllvdbg("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen); + nllvdbg("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen); - /* Update the accumulated size of the data read */ + /* Update the accumulated size of the data read */ - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; + pstate->rf_recvlen = recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; + } + else + { + pstate->rf_recvlen = 0; + } out: /* Remove the I/O buffer chain from the head of the read-ahead @@ -485,7 +520,7 @@ out: * TRUE:timeout FALSE:no timeout * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -581,7 +616,7 @@ static inline void recvfrom_pktsender(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_PKT static uint16_t recvfrom_pktinterrupt(FAR struct net_driver_s *dev, - FAR void *conn, FAR void *pvpriv, + FAR void *pvconn, FAR void *pvpriv, uint16_t flags) { struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv; @@ -709,24 +744,40 @@ static inline void recvfrom_tcpsender(FAR struct net_driver_s *dev, * * Parameters: * dev The structure of the network driver that caused the interrupt - * conn The connection structure associated with the socket + * pvconn The connection structure associated with the socket * flags Set of events describing why the callback was invoked * * Returned Value: * None * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ #ifdef CONFIG_NET_TCP static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev, - FAR void *conn, FAR void *pvpriv, + FAR void *pvconn, FAR void *pvpriv, uint16_t flags) { FAR struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv; +#if 0 /* REVISIT: The assertion fires. Why? */ +#ifdef CONFIG_NETDEV_MULTINIC + FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn; + + /* The TCP socket is connected and, hence, should be bound to a device. + * Make sure that the polling device is the own that we are bound to. + */ + + DEBUGASSERT(conn->dev == NULL || conn->dev == dev); + if (conn->dev != NULL && conn->dev != dev) + { + return flags; + } +#endif +#endif + nllvdbg("flags: %04x\n", flags); /* 'priv' might be null in some race conditions (?) */ @@ -794,11 +845,11 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev, } #ifdef CONFIG_NET_SOCKOPTS - /* Reset the timeout. We will want a short timeout to terminate - * the TCP receive. - */ + /* Reset the timeout. We will want a short timeout to terminate + * the TCP receive. + */ - pstate->rf_starttime = clock_systimer(); + pstate->rf_starttime = clock_systimer(); #endif } @@ -881,11 +932,11 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev, /* Report an error only if no data has been received. (If * CONFIG_NET_TCP_RECVDELAY then rf_recvlen should always be - * zero). + * less than or equal to zero). */ #if CONFIG_NET_TCP_RECVDELAY > 0 - if (pstate->rf_recvlen == 0) + if (pstate->rf_recvlen <= 0) #endif { /* Report the timeout error */ @@ -921,7 +972,7 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev, * None * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -966,7 +1017,8 @@ static inline void recvfrom_udpsender(struct net_driver_s *dev, struct recvfrom_ if (infrom) { #ifdef CONFIG_NET_IPv6 - FAR struct udp_conn_s *conn = (FAR struct udp_conn_s*)pstate->rf_sock->s_conn; + FAR struct udp_conn_s *conn = + (FAR struct udp_conn_s *)pstate->rf_sock->s_conn; /* Hybrid dual-stack IPv6/IPv4 implementations recognize a special * class of addresses, the IPv4-mapped IPv6 addresses. @@ -1014,7 +1066,8 @@ static inline void recvfrom_udpsender(struct net_driver_s *dev, struct recvfrom_ * Terminate the UDP transfer. * * Parameters: - * conn The connection structure associated with the socket + * pstate - The recvfrom state structure + * result - The result of the operation * * Returned Value: * None @@ -1051,14 +1104,14 @@ static void recvfrom_udp_terminate(FAR struct recvfrom_s *pstate, int result) * * Parameters: * dev The structure of the network driver that caused the interrupt - * conn The connection structure associated with the socket + * pvconn The connection structure associated with the socket * flags Set of events describing why the callback was invoked * * Returned Value: * None * * Assumptions: - * Running at the interrupt level + * The network is locked. * ****************************************************************************/ @@ -1155,7 +1208,7 @@ static uint16_t recvfrom_udp_interrupt(FAR struct net_driver_s *dev, * ****************************************************************************/ -#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) +#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) || defined(CONFIG_NET_PKT) static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len, FAR struct sockaddr *infrom, FAR socklen_t *fromlen, @@ -1203,7 +1256,7 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, * ****************************************************************************/ -#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) +#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP) || defined(CONFIG_NET_PKT) static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate) { int save_errno = get_errno(); /* In case something we do changes it */ @@ -1374,7 +1427,7 @@ static ssize_t pkt_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, if (state.rf_cb) { state.rf_cb->flags = (PKT_NEWDATA | PKT_POLL); - state.rf_cb->priv = (void*)&state; + state.rf_cb->priv = (FAR void *)&state; state.rf_cb->event = recvfrom_pktinterrupt; /* Notify the device driver of the receive call */ @@ -1482,7 +1535,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, * something was received (already in 'ret'); EAGAIN if not. */ - if (ret <= 0) + if (ret < 0) { /* Nothing was received */ @@ -1493,9 +1546,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* It is okay to block if we need to. If there is space to receive anything * more, then we will wait to receive the data. Otherwise return the number * of bytes read from the read-ahead buffer (already in 'ret'). + * + * NOTE: that recvfrom_udpreadahead() may set state.rf_recvlen == -1. */ - else if (state.rf_recvlen == 0) + else if (state.rf_recvlen <= 0) #endif { /* Get the device that will handle the packet transfers. This may be @@ -1513,7 +1568,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Set up the callback in the connection */ state.rf_cb->flags = (UDP_NEWDATA | UDP_POLL | NETDEV_DOWN); - state.rf_cb->priv = (void*)&state; + state.rf_cb->priv = (FAR void *)&state; state.rf_cb->event = recvfrom_udp_interrupt; /* Notify the device driver of the receive call */ @@ -1695,7 +1750,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, if (state.rf_cb) { state.rf_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS); - state.rf_cb->priv = (void*)&state; + state.rf_cb->priv = (FAR void *)&state; state.rf_cb->event = recvfrom_tcpinterrupt; /* Wait for either the receive to complete or for an error/timeout diff --git a/net/socket/send.c b/net/socket/send.c index 771f4e980666fa791fe8375d5b1f8b0181aa8296..60b19ab296fbff601bd7579bae48cbc4654bb24e 100644 --- a/net/socket/send.c +++ b/net/socket/send.c @@ -38,29 +38,17 @@ ****************************************************************************/ #include -#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM) #include #include #include #include "tcp/tcp.h" +#include "udp/udp.h" #include "pkt/pkt.h" #include "local/local.h" #include "socket/socket.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -168,6 +156,31 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, break; #endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */ +#ifdef CONFIG_NET_UDP + case SOCK_DGRAM: + { +#ifdef CONFIG_NET_LOCAL_DGRAM +#ifdef CONFIG_NET_UDP + if (psock->s_domain == PF_LOCAL) +#endif + { +#warning Missing logic + ret = -ENOSYS; + } +#endif /* CONFIG_NET_LOCAL_DGRAM */ + +#ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_LOCAL_DGRAM + else +#endif + { + ret = psock_udp_send(psock, buf, len); + } +#endif /* CONFIG_NET_UDP */ + } + break; +#endif /* CONFIG_NET_UDP */ + default: { /* EDESTADDRREQ. Signifies that the socket is not connection-mode @@ -250,5 +263,3 @@ ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags) { return psock_send(sockfd_socket(sockfd), buf, len, flags); } - -#endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */ diff --git a/net/socket/sendto.c b/net/socket/sendto.c index 3332f5791602b56a245af89b64c4a10bbd24afe8..193e3ae4fe222b22fe421123abe127b28060f64a 100644 --- a/net/socket/sendto.c +++ b/net/socket/sendto.c @@ -38,7 +38,6 @@ ****************************************************************************/ #include -#ifdef CONFIG_NET #include #include @@ -319,5 +318,3 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags, return psock_sendto(psock, buf, len, flags, to, tolen); } - -#endif /* CONFIG_NET */ diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c index cc6d15dec9eb90231c9502a478475a46cb9501d2..99ec9378ed0a40b132c19d67a0e511b965dd8deb 100644 --- a/net/socket/setsockopt.c +++ b/net/socket/setsockopt.c @@ -147,7 +147,7 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option, /* Get the value. Is the option being set or cleared? */ - setting = *(int*)value; + setting = *(FAR int *)value; /* Disable interrupts so that there is no conflict with interrupt * level access to options. diff --git a/net/socket/socket.c b/net/socket/socket.c index 2c8376e1e7fd6de6710f640c11c1c9b610404ed7..93fd41a278db51d6f9aafd7cdb6d00ca3108afde 100644 --- a/net/socket/socket.c +++ b/net/socket/socket.c @@ -185,9 +185,9 @@ static int psock_local_alloc(FAR struct socket *psock) return -ENOMEM; } - /* Set the reference count on the connection structure. This reference - * count will be incremented only if the socket is dup'ed - */ + /* Set the reference count on the connection structure. This reference + * count will be incremented only if the socket is dup'ed + */ DEBUGASSERT(conn->lc_crefs == 0); conn->lc_crefs = 1; diff --git a/net/socket/socket.h b/net/socket/socket.h index 7137b143ef924719a7aaf9bc9e401fd22cb592c9..e9bfa161db368d2235a8488b254075e78401a004 100644 --- a/net/socket/socket.h +++ b/net/socket/socket.h @@ -47,6 +47,7 @@ #include #include +#include #include /**************************************************************************** @@ -135,7 +136,7 @@ ****************************************************************************/ /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -345,7 +346,7 @@ int net_close(int sockfd); ****************************************************************************/ #ifdef CONFIG_NET_SOCKOPTS -int net_timeo(uint32_t start_time, socktimeo_t timeo); +int net_timeo(systime_t start_time, socktimeo_t timeo); #endif /**************************************************************************** diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 7e958b6006894fc6cf91c04aea6894db9902ced6..0b3bd37ce5720537d7b6b26e1ff58350be37b01c 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp.h * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -101,12 +101,6 @@ devif_conn_callback_free(g_netdevices, cb, NULL) #endif -/* Get the current maximum segment size that can be sent on the current - * TCP connection. - */ - -#define tcp_mss(conn) ((conn)->mss) - #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* TCP write buffer access macros */ @@ -132,6 +126,7 @@ /**************************************************************************** * Public Type Definitions ****************************************************************************/ + /* Representation of a TCP connection. * * The tcp_conn_s structure is used for identifying a connection. All @@ -413,10 +408,11 @@ FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn); /**************************************************************************** - * Function: tcp_find_ipv4_device + * Function: tcp_local_ipv4_device * * Description: - * Select the network driver to use with the IPv4 TCP transaction. + * Select the network driver to use with the IPv4 TCP transaction based + * on the locally bound IPv4 address * * Input Parameters: * conn - TCP connection structure. The locally bound address, laddr, @@ -424,19 +420,41 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn); * * Returned Value: * Zero (OK) is returned on success. A negated errno value is returned - * on failure. -ENODEV is the only expected error value. + * on failure. -ENETUNREACH is the only expected error value. * ****************************************************************************/ #ifdef CONFIG_NET_IPv4 -int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn); +int tcp_local_ipv4_device(FAR struct tcp_conn_s *conn); #endif /**************************************************************************** - * Function: tcp_find_ipv6_device + * Function: tcp_remote_ipv4_device * * Description: - * Select the network driver to use with the IPv6 TCP transaction. + * Select the network driver to use with the IPv4 TCP transaction based + * on the remotely connected IPv4 address + * + * Input Parameters: + * conn - TCP connection structure. The remotely conected address, raddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -ENETUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +int tcp_remote_ipv4_device(FAR struct tcp_conn_s *conn); +#endif + +/**************************************************************************** + * Function: tcp_local_ipv6_device + * + * Description: + * Select the network driver to use with the IPv6 TCP transaction based + * on the locally bound IPv6 address * * Input Parameters: * conn - TCP connection structure. The locally bound address, laddr, @@ -449,7 +467,28 @@ int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn); ****************************************************************************/ #ifdef CONFIG_NET_IPv6 -int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn); +int tcp_local_ipv6_device(FAR struct tcp_conn_s *conn); +#endif + +/**************************************************************************** + * Function: tcp_remote_ipv6_device + * + * Description: + * Select the network driver to use with the IPv6 TCP transaction based + * on the remotely conected IPv6 address + * + * Input Parameters: + * conn - TCP connection structure. The remotely connected address, raddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -EHOSTUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +int tcp_remote_ipv6_device(FAR struct tcp_conn_s *conn); #endif /**************************************************************************** @@ -1105,6 +1144,35 @@ struct socket; ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, size_t len); +/**************************************************************************** + * Function: psock_tcp_cansend + * + * Description: + * psock_tcp_cansend() returns a value indicating if a write to the socket + * would block. No space in the buffer is actually reserved, so it is + * possible that the write may still block if the buffer is filled by + * another means. + * + * Parameters: + * psock An instance of the internal socket structure. + * + * Returned Value: + * OK + * At least one byte of data could be succesfully written. + * -EWOULDBLOCK + * There is no room in the output buffer. + * -EBADF + * An invalid descriptor was specified. + * -ENOTCONN + * The socket is not connected. + * + * Assumptions: + * Not running at the interrupt level + * + ****************************************************************************/ + +int psock_tcp_cansend(FAR struct socket *psock); + /**************************************************************************** * Function: tcp_wrbuffer_initialize * @@ -1159,6 +1227,21 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void); void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb); #endif /* CONFIG_NET_TCP_WRITE_BUFFERS */ +/**************************************************************************** + * Function: tcp_wrbuffer_test + * + * Description: + * Check if there is room in the write buffer. Does not reserve any space. + * + * Assumptions: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP_WRITE_BUFFERS +int tcp_wrbuffer_test(void); +#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */ + /**************************************************************************** * Function: tcp_wrbuffer_dump * diff --git a/net/tcp/tcp_accept.c b/net/tcp/tcp_accept.c index 9597b6b36b2efcfa6ff7aace34cbe39f7c2e5f68..a37db211db4887857750d5322e1e280d46d8ed5a 100644 --- a/net/tcp/tcp_accept.c +++ b/net/tcp/tcp_accept.c @@ -54,10 +54,6 @@ #include "socket/socket.h" #include "tcp/tcp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -72,10 +68,6 @@ struct accept_s int acpt_result; /* The result of the wait */ }; -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -96,7 +88,7 @@ struct accept_s * * Assumptions: * Running at the interrupt level -* + * ****************************************************************************/ #ifdef CONFIG_NET_TCP @@ -238,7 +230,6 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, { FAR struct tcp_conn_s *conn; struct accept_s state; - int err = OK; int ret; DEBUGASSERT(psock && newconn); @@ -267,8 +258,7 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, else if (_SS_ISNONBLOCK(psock->s_flags)) { - err = EAGAIN; - goto errout; + return -EAGAIN; } else #endif @@ -293,7 +283,7 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, /* Set up the callback in the connection */ - conn->accept_private = (void*)&state; + conn->accept_private = (FAR void *)&state; conn->accept = accept_interrupt; /* Wait for the send to complete or an error to occur: NOTES: (1) @@ -314,7 +304,8 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, * altered by intervening operations. */ - err = get_errno(); + ret = -get_errno(); + DEBUGASSERT(ret < 0); } /* Make sure that no further interrupts are processed */ @@ -334,27 +325,23 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, if (state.acpt_result != 0) { - err = state.acpt_result; - goto errout; + DEBUGASSERT(state.acpt_result > 0); + return -state.acpt_result; } /* If net_lockedwait failed, then we were probably reawakened by a - * signal. In this case, logic above will have set 'err' to the + * signal. In this case, logic above will have set 'ret' to the * errno value returned by net_lockedwait(). */ if (ret < 0) { - goto errout; + return ret; } } *newconn = (FAR void *)state.acpt_newconn; return OK; - -errout: - set_errno(err); - return ERROR; } #endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS && CONFIG_NET_TCP */ diff --git a/net/tcp/tcp_appsend.c b/net/tcp/tcp_appsend.c index 4f110f848a91c05fbf4514056e0e48723f5ece7e..a56da75714f086c500b0a8423259c64bb7817a4f 100644 --- a/net/tcp/tcp_appsend.c +++ b/net/tcp/tcp_appsend.c @@ -55,22 +55,6 @@ #include "devif/devif.h" #include "tcp/tcp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -172,7 +156,7 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, else { #ifdef CONFIG_NET_TCP_WRITE_BUFFERS - DEBUGASSERT(dev->d_sndlen >= 0 && dev->d_sndlen <= conn->mss); + DEBUGASSERT(dev->d_sndlen <= conn->mss); #else /* If d_sndlen > 0, the application has data to be sent. */ @@ -253,7 +237,7 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, } #endif /* CONFIG_NET_IPv6 */ - /* If the application has data to be sent, or if the incoming packet had + /* If the application has data to be sent, or if the incoming packet had * new data in it, we must send out a packet. */ diff --git a/net/tcp/tcp_backlog.c b/net/tcp/tcp_backlog.c index 4d2ecbc2cb18dc1b5b6b2e355632a6108c8c08c2..f4bba6cbebc61c35c873979d83c98f0ef60e8cd2 100644 --- a/net/tcp/tcp_backlog.c +++ b/net/tcp/tcp_backlog.c @@ -52,14 +52,6 @@ #include "devif/devif.h" #include "tcp/tcp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -123,7 +115,7 @@ int tcp_backlogcreate(FAR struct tcp_conn_s *conn, int nblg) /* Then add all of the pre-allocated containers to the free list */ - blc = (FAR struct tcp_blcontainer_s*)(((FAR uint8_t*)bls) + offset); + blc = (FAR struct tcp_blcontainer_s *)(((FAR uint8_t *)bls) + offset); for (i = 0; i < nblg; i++) { sq_addfirst(&blc->bc_node, &bls->bl_free); @@ -189,7 +181,7 @@ int tcp_backlogdestroy(FAR struct tcp_conn_s *conn) /* Handle any pending connections in the backlog */ - while ((blc = (FAR struct tcp_blcontainer_s*)sq_remfirst(&blg->bl_pending)) != NULL) + while ((blc = (FAR struct tcp_blcontainer_s *)sq_remfirst(&blg->bl_pending)) != NULL) { blconn = blc->bc_conn; if (blconn) @@ -242,25 +234,26 @@ int tcp_backlogadd(FAR struct tcp_conn_s *conn, FAR struct tcp_conn_s *blconn) bls = conn->backlog; if (bls && blconn) { - /* Allocate a container for the connection from the free list */ + /* Allocate a container for the connection from the free list */ - blc = (FAR struct tcp_blcontainer_s *)sq_remfirst(&bls->bl_free); - if (!blc) - { - nlldbg("Failed to allocate container\n"); - ret = -ENOMEM; - } - else - { - /* Save the connection reference in the container and put the - * container at the end of the pending connection list (FIFO). - */ + blc = (FAR struct tcp_blcontainer_s *)sq_remfirst(&bls->bl_free); + if (!blc) + { + nlldbg("Failed to allocate container\n"); + ret = -ENOMEM; + } + else + { + /* Save the connection reference in the container and put the + * container at the end of the pending connection list (FIFO). + */ - blc->bc_conn = blconn; - sq_addlast(&blc->bc_node, &bls->bl_pending); - ret = OK; - } + blc->bc_conn = blconn; + sq_addlast(&blc->bc_node, &bls->bl_pending); + ret = OK; + } } + return ret; } @@ -311,21 +304,21 @@ FAR struct tcp_conn_s *tcp_backlogremove(FAR struct tcp_conn_s *conn) bls = conn->backlog; if (bls) { - /* Remove the a container at the head of the pending connection list - * (FIFO) - */ + /* Remove the a container at the head of the pending connection list + * (FIFO) + */ - blc = (FAR struct tcp_blcontainer_s *)sq_remfirst(&bls->bl_pending); - if (blc) - { - /* Extract the connection reference from the container and put - * container in the free list - */ + blc = (FAR struct tcp_blcontainer_s *)sq_remfirst(&bls->bl_pending); + if (blc) + { + /* Extract the connection reference from the container and put + * container in the free list + */ - blconn = blc->bc_conn; - blc->bc_conn = NULL; - sq_addlast(&blc->bc_node, &bls->bl_free); - } + blconn = blc->bc_conn; + blc->bc_conn = NULL; + sq_addlast(&blc->bc_node, &bls->bl_free); + } } nllvdbg("conn=%p, returning %p\n", conn, blconn); @@ -364,41 +357,41 @@ int tcp_backlogdelete(FAR struct tcp_conn_s *conn, bls = conn->backlog; if (bls) { - /* Find the container hold the connection */ + /* Find the container hold the connection */ - for (blc = (FAR struct tcp_blcontainer_s *)sq_peek(&bls->bl_pending), prev = NULL; - blc; - prev = blc, blc = (FAR struct tcp_blcontainer_s *)sq_next(&blc->bc_node)) - { - if (blc->bc_conn == blconn) - { - if (prev) - { - /* Remove the a container from the middle of the list of - * pending connections - */ - - (void)sq_remafter(&prev->bc_node, &bls->bl_pending); - } - else - { - /* Remove the a container from the head of the list of - * pending connections - */ - - (void)sq_remfirst(&bls->bl_pending); - } - - /* Put container in the free list */ - - blc->bc_conn = NULL; - sq_addlast(&blc->bc_node, &bls->bl_free); - return OK; - } - } - - nlldbg("Failed to find pending connection\n"); - return -EINVAL; + for (blc = (FAR struct tcp_blcontainer_s *)sq_peek(&bls->bl_pending), prev = NULL; + blc; + prev = blc, blc = (FAR struct tcp_blcontainer_s *)sq_next(&blc->bc_node)) + { + if (blc->bc_conn == blconn) + { + if (prev) + { + /* Remove the a container from the middle of the list of + * pending connections + */ + + (void)sq_remafter(&prev->bc_node, &bls->bl_pending); + } + else + { + /* Remove the a container from the head of the list of + * pending connections + */ + + (void)sq_remfirst(&bls->bl_pending); + } + + /* Put container in the free list */ + + blc->bc_conn = NULL; + sq_addlast(&blc->bc_node, &bls->bl_free); + return OK; + } + } + + nlldbg("Failed to find pending connection\n"); + return -EINVAL; } return OK; diff --git a/net/tcp/tcp_callback.c b/net/tcp/tcp_callback.c index 68f4277232637fadcaf10c1a3a4132c43a71f48d..73c6175fee508243b380c861821500f859cef196 100644 --- a/net/tcp/tcp_callback.c +++ b/net/tcp/tcp_callback.c @@ -53,10 +53,6 @@ #include "iob/iob.h" #include "tcp/tcp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -116,7 +112,7 @@ tcp_data_event(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, nllvdbg("Dropped %d bytes\n", dev->d_len); - #ifdef CONFIG_NET_STATISTICS +#ifdef CONFIG_NET_STATISTICS g_netstats.tcp.syndrop++; g_netstats.tcp.drop++; #endif diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index fd411cf8dc7f11e1de620c6a33e5dd40d8a9d877..6cc9950fc0675384c062c55d669dd44c44760045 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -543,16 +543,16 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn, net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr); #endif - /* Find the device that can receive packets on the network - * associated with this local address. + /* Find the device that can receive packets on the network associated with + * this local address. */ - ret = tcp_find_ipv4_device(conn); + ret = tcp_local_ipv4_device(conn); if (ret < 0) { /* If no device is found, then the address is not reachable */ - ndbg("tcp_find_ipv4_device failed: %d\n", ret); + ndbg("tcp_local_ipv4_device failed: %d\n", ret); /* Back out the local address setting */ @@ -628,12 +628,12 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn, * associated with this local address. */ - ret = tcp_find_ipv6_device(conn); + ret = tcp_local_ipv6_device(conn); if (ret < 0) { /* If no device is found, then the address is not reachable */ - ndbg("tcp_find_ipv6_device failed: %d\n", ret); + ndbg("tcp_local_ipv6_device failed: %d\n", ret); /* Back out the local address setting */ @@ -1003,13 +1003,20 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr); #ifdef CONFIG_NETDEV_MULTINIC net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr); + + /* We now have to filter all outgoing transfers so that they use + * only the MSS of this device. + */ + + DEBUGASSERT(conn->dev == NULL || conn->dev == dev); + conn->dev = dev; #endif /* Find the device that can receive packets on the network * associated with this local address. */ - ret = tcp_find_ipv6_device(conn); + ret = tcp_remote_ipv6_device(conn); } #endif /* CONFIG_NET_IPv6 */ @@ -1020,21 +1027,31 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, { FAR struct ipv4_hdr_s *ip = IPv4BUF; - /* Set the IPv6 specific MSS and the IPv4 locally bound address. */ + /* Set the IPv6 specific MSS and the IPv4 bound remote address. */ conn->mss = TCP_IPv4_INITIAL_MSS(dev); net_ipv4addr_copy(conn->u.ipv4.raddr, net_ip4addr_conv32(ip->srcipaddr)); + #ifdef CONFIG_NETDEV_MULTINIC + /* Set the local address as well */ + net_ipv4addr_copy(conn->u.ipv4.laddr, net_ip4addr_conv32(ip->destipaddr)); + + /* We now have to filter all outgoing transfers so that they use + * only the MSS of this device. + */ + + DEBUGASSERT(conn->dev == NULL || conn->dev == dev); + conn->dev = dev; #endif /* Find the device that can receive packets on the network * associated with this local address. */ - ret = tcp_find_ipv4_device(conn); + ret = tcp_remote_ipv4_device(conn); } #endif /* CONFIG_NET_IPv4 */ @@ -1238,8 +1255,9 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) goto errout_with_lock; } - /* Set up the local address (laddr) and the remote address (raddr) that describes the TCP connection. - */ + /* Set up the local address (laddr) and the remote address (raddr) that + * describes the TCP connection. + */ #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 @@ -1259,10 +1277,10 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) net_ipv4addr_copy(conn->u.ipv4.raddr, inaddr->sin_addr.s_addr); /* Find the device that can receive packets on the network associated - * with this local address. + * with this remote address. */ - ret = tcp_find_ipv4_device(conn); + ret = tcp_remote_ipv4_device(conn); } #endif /* CONFIG_NET_IPv4 */ @@ -1287,7 +1305,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) * with this local address. */ - ret = tcp_find_ipv6_device(conn); + ret = tcp_remote_ipv6_device(conn); } #endif /* CONFIG_NET_IPv6 */ diff --git a/net/tcp/tcp_devpoll.c b/net/tcp/tcp_devpoll.c index 9f971db286aa408323d8c101ef223340cdfdefe6..e4fadc6be66706d673a443e8912cecc95ee29943 100644 --- a/net/tcp/tcp_devpoll.c +++ b/net/tcp/tcp_devpoll.c @@ -55,22 +55,6 @@ #include "devif/devif.h" #include "tcp/tcp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/tcp/tcp_finddev.c b/net/tcp/tcp_finddev.c index fc198e66ad6153d79764d3860057805b0b0aaab9..ef6ae8f0d257ced6dd113c58965ef7b07e68c9eb 100644 --- a/net/tcp/tcp_finddev.c +++ b/net/tcp/tcp_finddev.c @@ -49,27 +49,19 @@ #include "netdev/netdev.h" #include "tcp/tcp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Function: tcp_find_ipv4_device * * Description: - * Select the network driver to use with the IPv4 TCP transaction. + * Select the network driver to use with the IPv4 TCP connection. * * Input Parameters: - * conn - TCP connection structure. The locally bound address, laddr, - * should be set to a non-zero value in this structure. + * conn - TCP connection structure. + * addr - The IPv4 address to use * * Returned Value: * Zero (OK) is returned on success. A negated errno value is returned @@ -78,18 +70,24 @@ ****************************************************************************/ #ifdef CONFIG_NET_IPv4 -int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn) +static int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn, in_addr_t addr) { #ifdef CONFIG_NETDEV_MULTINIC + /* Do nothing if a device is already bound to the connection */ + + if (conn->dev != NULL) + { + return OK; + } + /* Return success without using device notification if the locally bound * address is INADDR_ANY. In this case, there may be multiple devices * that can provide data so the exceptional events from any particular * device are not important. */ - if (net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY)) + if (net_ipv4addr_cmp(addr, INADDR_ANY)) { - conn->dev = NULL; return OK; } @@ -97,8 +95,7 @@ int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn) * is going to route the TCP packet based on the provided IP address. */ - conn->dev = netdev_findby_ipv4addr(conn->u.ipv4.laddr, - conn->u.ipv4.laddr); + conn->dev = netdev_findby_ipv4addr(addr, addr); /* Return success if we found the device */ @@ -121,8 +118,8 @@ int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn) * Select the network driver to use with the IPv6 TCP transaction. * * Input Parameters: - * conn - TCP connection structure. The locally bound address, laddr, - * should be set to a non-zero value in this structure. + * conn - TCP connection structure. + * addr - The IPv6 address to use * * Returned Value: * Zero (OK) is returned on success. A negated errno value is returned @@ -131,18 +128,25 @@ int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn) ****************************************************************************/ #ifdef CONFIG_NET_IPv6 -int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn) +static int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn, + const net_ipv6addr_t addr) { #ifdef CONFIG_NETDEV_MULTINIC + /* Do nothing if a device is already bound to the connection */ + + if (conn->dev != NULL) + { + return OK; + } + /* Return success without using device notification if the locally bound * address is IN6ADDR_ANY. In this case, there may be multiple devices * that can provide data so the exceptional events from any particular * device are not important. */ - if (net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr)) + if (net_ipv6addr_cmp(addr, g_ipv6_allzeroaddr)) { - conn->dev = NULL; return OK; } @@ -150,8 +154,7 @@ int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn) * is going to route the TCP packet based on the provided IP address. */ - conn->dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, - conn->u.ipv6.laddr); + conn->dev = netdev_findby_ipv6addr(addr, addr); /* Return success if we found the device */ @@ -167,4 +170,112 @@ int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn) } #endif /* CONFIG_NET_IPv6 */ +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: tcp_local_ipv4_device + * + * Description: + * Select the network driver to use with the IPv4 TCP transaction based + * on the locally bound IPv4 address + * + * Input Parameters: + * conn - TCP connection structure. The locally bound address, laddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -ENETUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +int tcp_local_ipv4_device(FAR struct tcp_conn_s *conn) +{ +#ifdef CONFIG_NETDEV_MULTINIC + return tcp_find_ipv4_device(conn, conn->u.ipv4.laddr); +#else + return tcp_find_ipv4_device(conn, 0); +#endif +} +#endif /* CONFIG_NET_IPv4 */ + +/**************************************************************************** + * Function: tcp_remote_ipv4_device + * + * Description: + * Select the network driver to use with the IPv4 TCP transaction based + * on the remotely connected IPv4 address + * + * Input Parameters: + * conn - TCP connection structure. The remotely conected address, raddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -ENETUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +int tcp_remote_ipv4_device(FAR struct tcp_conn_s *conn) +{ + return tcp_find_ipv4_device(conn, conn->u.ipv4.raddr); +} +#endif + +/**************************************************************************** + * Function: tcp_local_ipv6_device + * + * Description: + * Select the network driver to use with the IPv6 TCP transaction. + * + * Input Parameters: + * conn - TCP connection structure. The locally bound address, laddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -ENETUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +int tcp_local_ipv6_device(FAR struct tcp_conn_s *conn) +{ +#ifdef CONFIG_NETDEV_MULTINIC + return tcp_find_ipv6_device(conn, conn->u.ipv6.laddr); +#else + return tcp_find_ipv6_device(conn, NULL); +#endif + +} +#endif /* CONFIG_NET_IPv6 */ + +/**************************************************************************** + * Function: tcp_remote_ipv6_device + * + * Description: + * Select the network driver to use with the IPv6 TCP transaction based + * on the remotely conected IPv6 address + * + * Input Parameters: + * conn - TCP connection structure. The remotely connected address, raddr, + * should be set to a non-zero value in this structure. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. -EHOSTUNREACH is the only expected error value. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +int tcp_remote_ipv6_device(FAR struct tcp_conn_s *conn) +{ + return tcp_find_ipv6_device(conn, conn->u.ipv6.raddr); +} +#endif /* CONFIG_NET_IPv6 */ + #endif /* CONFIG_NET && CONFIG_NET_TCP */ diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index f6af2bbbdcc79dc87448ebe778562bc863d066e6..3db34ae38461a001a52f14007789855a1530d52d 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -60,18 +60,6 @@ #include "utils/utils.h" #include "tcp/tcp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -228,7 +216,7 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) if ((tcp->tcpoffset & 0xf0) > 0x50) { - for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;) + for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ; ) { opt = dev->d_buf[hdrlen + i]; if (opt == TCP_OPT_END) @@ -520,7 +508,7 @@ found: if ((tcp->tcpoffset & 0xf0) > 0x50) { - for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ;) + for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ; ) { opt = dev->d_buf[hdrlen + i]; if (opt == TCP_OPT_END) @@ -682,7 +670,8 @@ found: { dev->d_urglen = 0; #else /* CONFIG_NET_TCPURGDATA */ - dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((tcp->urgp[0] << 8) | tcp->urgp[1]); + dev->d_appdata = ((FAR uint8_t *)dev->d_appdata) + ((tcp->urgp[0] << 8) | + tcp->urgp[1]); dev->d_len -= (tcp->urgp[0] << 8) | tcp->urgp[1]; #endif /* CONFIG_NET_TCPURGDATA */ } diff --git a/net/tcp/tcp_ipselect.c b/net/tcp/tcp_ipselect.c index 9463fe4b30b4c4b227b1605c8105537eb3842e4c..a2570c34b007954caa521fe63c23ab74e27cd7c9 100644 --- a/net/tcp/tcp_ipselect.c +++ b/net/tcp/tcp_ipselect.c @@ -49,14 +49,6 @@ #include "tcp/tcp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -76,9 +68,9 @@ void tcp_ipv4_select(FAR struct net_driver_s *dev) IFF_SET_IPv4(dev->d_flags); - /* Set the offset to the beginning of the TCP data payload */ + /* Set the offset to the beginning of the TCP data payload */ - dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv4TCP_HDRLEN + NET_LL_HDRLEN(dev)]; } #endif /* CONFIG_NET_IPv4 */ @@ -97,9 +89,9 @@ void tcp_ipv6_select(FAR struct net_driver_s *dev) IFF_SET_IPv6(dev->d_flags); - /* Set the offset to the beginning of the TCP data payload */ + /* Set the offset to the beginning of the TCP data payload */ - dev->d_appdata = &dev->d_buf[IPv6TCP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv6TCP_HDRLEN + NET_LL_HDRLEN(dev)]; } #endif /* CONFIG_NET_IPv6 */ diff --git a/net/tcp/tcp_listen.c b/net/tcp/tcp_listen.c index dbe56b9f2a6394db808d3425575f4da818ae9b0c..b4990ba1663eb068a0aa2ae0ce620a836efef5fc 100644 --- a/net/tcp/tcp_listen.c +++ b/net/tcp/tcp_listen.c @@ -243,7 +243,7 @@ bool tcp_islistener(uint16_t portno) * Accept the new connection for the specified listening port. * * Assumptions: - * Called at interrupt level + * Called with the network locked. * ****************************************************************************/ diff --git a/net/tcp/tcp_netpoll.c b/net/tcp/tcp_netpoll.c index 41793f36419421989d1cff5470e47e51e0a5416a..522c00986b82e2e0072a005e91f019a733a0a350 100644 --- a/net/tcp/tcp_netpoll.c +++ b/net/tcp/tcp_netpoll.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp_netpoll.c * - * Copyright (C) 2008-2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -127,7 +127,7 @@ static uint16_t tcp_poll_interrupt(FAR struct net_driver_s *dev, FAR void *conn, eventset |= (POLLERR | POLLHUP); } - /* Awaken the caller of poll() is requested event occurred. */ + /* Awaken the caller of poll() if requested event occurred. */ if (eventset) { @@ -282,6 +282,10 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) fds->revents |= (POLLERR | POLLHUP); } + else if (_SS_ISCONNECTED(psock->s_flags) && psock_tcp_cansend(psock) >= 0) + { + fds->revents |= (POLLWRNORM & fds->events); + } /* Check if any requested events are already in effect */ diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c index 536cf2dc44bf1d2c5ddb7ffcabc3350b79ea7b36..14affd53de92a05bd9d1347bd146d1756e7fe49d 100644 --- a/net/tcp/tcp_send.c +++ b/net/tcp/tcp_send.c @@ -68,14 +68,6 @@ #define TCPIPv4BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN]) #define TCPIPv6BUF ((struct tcp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN]) -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index d8ea4a66b7aa49a78a8322c354fbc39103e6523a..3ab9f269d7ae23a37f4d1d14effae1b7f0239470 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp_send_buffered.c * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * Jason Jiang * @@ -101,10 +101,6 @@ # define WRB_DUMP(msg,wrb,len,offset) #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -131,13 +127,13 @@ static void psock_insert_segment(FAR struct tcp_wrbuffer_s *wrb, FAR sq_queue_t *q) { - sq_entry_t *entry = (sq_entry_t*)wrb; - sq_entry_t *insert = NULL; + FAR sq_entry_t *entry = (FAR sq_entry_t *)wrb; + FAR sq_entry_t *insert = NULL; - sq_entry_t *itr; + FAR sq_entry_t *itr; for (itr = sq_peek(q); itr; itr = sq_next(itr)) { - FAR struct tcp_wrbuffer_s *wrb0 = (FAR struct tcp_wrbuffer_s*)itr; + FAR struct tcp_wrbuffer_s *wrb0 = (FAR struct tcp_wrbuffer_s *)itr; if (WRB_SEQNO(wrb0) < WRB_SEQNO(wrb)) { insert = itr; @@ -181,8 +177,11 @@ static inline void psock_lost_connection(FAR struct socket *psock, /* Do not allow any further callbacks */ - psock->s_sndcb->flags = 0; - psock->s_sndcb->event = NULL; + if (psock->s_sndcb != NULL) + { + psock->s_sndcb->flags = 0; + psock->s_sndcb->event = NULL; + } /* Free all queued write buffers */ @@ -338,6 +337,18 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn; FAR struct socket *psock = (FAR struct socket *)pvpriv; +#ifdef CONFIG_NETDEV_MULTINIC + /* The TCP socket is connected and, hence, should be bound to a device. + * Make sure that the polling device is the own that we are bound to. + */ + + DEBUGASSERT(conn->dev != NULL); + if (dev != conn->dev) + { + return flags; + } +#endif + nllvdbg("flags: %04x\n", flags); /* If this packet contains an acknowledgement, then update the count of @@ -391,7 +402,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, /* Check of some or all of this write buffer has been ACKed. */ next = sq_next(entry); - wrb = (FAR struct tcp_wrbuffer_s*)entry; + wrb = (FAR struct tcp_wrbuffer_s *)entry; /* If the ACKed sequence number is greater than the start * sequence number of the write buffer, then some or all of @@ -457,7 +468,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, * before the entire write buffer has even been sent. */ - wrb = (FAR struct tcp_wrbuffer_s*)sq_peek(&conn->write_q); + wrb = (FAR struct tcp_wrbuffer_s *)sq_peek(&conn->write_q); if (wrb && WRB_SENT(wrb) > 0 && ackno > WRB_SEQNO(wrb)) { uint32_t nacked; @@ -492,9 +503,12 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, { nllvdbg("Lost connection: %04x\n", flags); - /* Report not connected */ + if (psock->s_conn != NULL) + { + /* Report not connected */ - net_lostconnection(psock, flags); + net_lostconnection(psock, flags); + } /* Free write buffers and terminate polling */ @@ -577,7 +591,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, conn->expired++; } } - + /* Move all segments that have been sent but not ACKed to the write * queue again note, the un-ACKed segments are put at the head of the * write_q so they can be resent as soon as possible. @@ -585,7 +599,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, while ((entry = sq_remlast(&conn->unacked_q)) != NULL) { - wrb = (FAR struct tcp_wrbuffer_s*)entry; + wrb = (FAR struct tcp_wrbuffer_s *)entry; uint16_t sent; /* Reset the number of bytes sent sent from the write buffer */ @@ -697,9 +711,9 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, */ sndlen = WRB_PKTLEN(wrb) - WRB_SENT(wrb); - if (sndlen > tcp_mss(conn)) + if (sndlen > conn->mss) { - sndlen = tcp_mss(conn); + sndlen = conn->mss; } if (sndlen > conn->winsize) @@ -714,7 +728,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, * retransmitting, then the sequence number will already * be set for this write buffer. */ - + if (WRB_SEQNO(wrb) == (unsigned)-1) { WRB_SEQNO(wrb) = conn->isn + conn->sent; @@ -1024,14 +1038,14 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, psock->s_sndcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | TCP_DISCONN_EVENTS); - psock->s_sndcb->priv = (void*)psock; + psock->s_sndcb->priv = (FAR void *)psock; psock->s_sndcb->event = psock_send_interrupt; /* Initialize the write buffer */ WRB_SEQNO(wrb) = (unsigned)-1; WRB_NRTX(wrb) = 0; - WRB_COPYIN(wrb, (FAR uint8_t *)buf, len); + result = WRB_COPYIN(wrb, (FAR uint8_t *)buf, len); /* Dump I/O buffer chain */ @@ -1042,15 +1056,14 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, */ sq_addlast(&wrb->wb_node, &conn->write_q); - nvdbg("Queued WRB=%p pktlen=%u write_q(%p,%p)\n", - wrb, WRB_PKTLEN(wrb), - conn->write_q.head, conn->write_q.tail); + nllvdbg("Queued WRB=%p pktlen=%u write_q(%p,%p)\n", + wrb, WRB_PKTLEN(wrb), + conn->write_q.head, conn->write_q.tail); /* Notify the device driver of the availability of TX data */ send_txnotify(psock, conn); net_unlock(save); - result = len; } /* Set the socket state to idle */ @@ -1092,4 +1105,53 @@ errout: return ERROR; } +/**************************************************************************** + * Function: psock_tcp_cansend + * + * Description: + * psock_tcp_cansend() returns a value indicating if a write to the socket + * would block. No space in the buffer is actually reserved, so it is + * possible that the write may still block if the buffer is filled by + * another means. + * + * Parameters: + * psock An instance of the internal socket structure. + * + * Returned Value: + * OK + * At least one byte of data could be succesfully written. + * -EWOULDBLOCK + * There is no room in the output buffer. + * -EBADF + * An invalid descriptor was specified. + * -ENOTCONN + * The socket is not connected. + * + * Assumptions: + * Not running at the interrupt level + * + ****************************************************************************/ + +int psock_tcp_cansend(FAR struct socket *psock) +{ + if (!psock || psock->s_crefs <= 0) + { + ndbg("ERROR: Invalid socket\n"); + return -EBADF; + } + + if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) + { + ndbg("ERROR: Not connected\n"); + return -ENOTCONN; + } + + if (tcp_wrbuffer_test()) + { + return -EWOULDBLOCK; + } + + return OK; +} + #endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_TCP_WRITE_BUFFERS */ diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 9526332424448a40219f6977874ab9ecfefd13af..7c0faac458c359c1fc78d400eb61792a824ec076 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp_send_unbuffered.c * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -103,7 +103,7 @@ struct send_s uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ #ifdef CONFIG_NET_SOCKOPTS - uint32_t snd_time; /* Last send time for determining timeout */ + systime_t snd_time; /* Last send time for determining timeout */ #endif #if defined(CONFIG_NET_TCP_SPLIT) bool snd_odd; /* True: Odd packet in pair transaction */ @@ -260,7 +260,7 @@ static inline bool psock_send_addrchck(FAR struct tcp_conn_s *conn) } #else /* CONFIG_NET_ETHERNET */ -# psock_send_addrchck(r) (true) +# define psock_send_addrchck(r) (true) #endif /* CONFIG_NET_ETHERNET */ /**************************************************************************** @@ -290,6 +290,18 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn; FAR struct send_s *pstate = (FAR struct send_s *)pvpriv; +#ifdef CONFIG_NETDEV_MULTINIC + /* The TCP socket is connected and, hence, should be bound to a device. + * Make sure that the polling device is the own that we are bound to. + */ + + DEBUGASSERT(conn->dev != NULL); + if (dev != conn->dev) + { + return flags; + } +#endif + nllvdbg("flags: %04x acked: %d sent: %d\n", flags, pstate->snd_acked, pstate->snd_sent); @@ -374,7 +386,7 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, /* Fall through to re-send data from the last that was ACKed */ } - /* Check for a loss of connection */ + /* Check for a loss of connection */ else if ((flags & TCP_DISCONN_EVENTS) != 0) { @@ -387,17 +399,17 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, goto end_wait; } - /* Check if the outgoing packet is available (it may have been claimed - * by a sendto interrupt serving a different thread). - */ + /* Check if the outgoing packet is available (it may have been claimed + * by a sendto interrupt serving a different thread). + */ #if 0 /* We can't really support multiple senders on the same TCP socket */ - else if (dev->d_sndlen > 0) - { - /* Another thread has beat us sending data, wait for the next poll */ + else if (dev->d_sndlen > 0) + { + /* Another thread has beat us sending data, wait for the next poll */ - return flags; - } + return flags; + } #endif /* We get here if (1) not all of the data has been ACKed, (2) we have been @@ -442,12 +454,12 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, if (sndlen >= CONFIG_NET_TCP_SPLIT_SIZE) { /* sndlen is the number of bytes remaining to be sent. - * tcp_mss(conn) will return the number of bytes that can sent + * conn->mss will provide the number of bytes that can sent * in one packet. The difference, then, is the number of bytes * that would be sent in the next packet after this one. */ - int32_t next_sndlen = sndlen - tcp_mss(conn); + int32_t next_sndlen = sndlen - conn->mss; /* Is this the even packet in the packet pair transaction? */ @@ -474,13 +486,13 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, { /* Will there be another (even) packet afer this one? * (next_sndlen > 0) Will the split condition occur on that - * next, even packet? ((next_sndlen - tcp_mss(conn)) < 0) If + * next, even packet? ((next_sndlen - conn->mss) < 0) If * so, then perform the split now to avoid the case where the * byte count is less than CONFIG_NET_TCP_SPLIT_SIZE on the * next pair. */ - if (next_sndlen > 0 && (next_sndlen - tcp_mss(conn)) < 0) + if (next_sndlen > 0 && (next_sndlen - conn->mss) < 0) { /* Here, we know that sndlen must be MSS < sndlen <= 2*MSS * and so (sndlen / 2) is <= MSS. @@ -497,9 +509,9 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, #endif /* CONFIG_NET_TCP_SPLIT */ - if (sndlen > tcp_mss(conn)) + if (sndlen > conn->mss) { - sndlen = tcp_mss(conn); + sndlen = conn->mss; } /* Check if we have "space" in the window */ @@ -868,4 +880,30 @@ errout: return ERROR; } +/**************************************************************************** + * Function: psock_tcp_cansend + * + * Description: + * psock_tcp_cansend() returns a value indicating if a write to the socket + * would block. It is still possible that the write may block if another + * write occurs first. + * + * Parameters: + * psock An instance of the internal socket structure. + * + * Returned Value: + * OK (Function not implemented). + * + * Assumptions: + * None + * + ****************************************************************************/ + +int psock_tcp_cansend(FAR struct socket *psock) +{ + /* TODO: return OK unless someone is waiting for a packet to send */ + + return OK; +} + #endif /* CONFIG_NET && CONFIG_NET_TCP && !CONFIG_NET_TCP_WRITE_BUFFERS */ diff --git a/net/tcp/tcp_seqno.c b/net/tcp/tcp_seqno.c index 6eb9141ce5b325b58f26ddf8ecfe5c7b3f65d766..d2c5600107a35035ccf908ee3cf2f88a02f8aa6d 100644 --- a/net/tcp/tcp_seqno.c +++ b/net/tcp/tcp_seqno.c @@ -55,10 +55,6 @@ #include "devif/devif.h" -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ @@ -67,10 +63,6 @@ static uint32_t g_tcpsequence; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 25659790ab72655cb1eca0a9d0581e0a5c2fb484..a9681a5c8a1bd4f6fb52ef9683bad3b4461a69b7 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -56,22 +56,6 @@ #include "devif/devif.h" #include "tcp/tcp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/tcp/tcp_wrbuffer.c b/net/tcp/tcp_wrbuffer.c index 3bdb8b2ba935ad95f7a3e25caa5889ed88305183..cb6c10e9d8d405c1be47d65a766b168ad8f1c2f4 100644 --- a/net/tcp/tcp_wrbuffer.c +++ b/net/tcp/tcp_wrbuffer.c @@ -88,10 +88,6 @@ struct wrbuffer_s static struct wrbuffer_s g_wrbuffer; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -201,4 +197,22 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb) sem_post(&g_wrbuffer.sem); } +/**************************************************************************** + * Function: tcp_wrbuffer_test + * + * Description: + * Check if there is room in the write buffer. Does not reserve any space. + * + * Assumptions: + * None. + * + ****************************************************************************/ + +int tcp_wrbuffer_test(void) +{ + int val = 0; + sem_getvalue(&g_wrbuffer.sem, &val); + return val > 0 ? OK : ERROR; +} + #endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_TCP_WRITE_BUFFERS */ diff --git a/net/tcp/tcp_wrbuffer_dump.c b/net/tcp/tcp_wrbuffer_dump.c index 741120f6fd76af90c61bd7729505a3cee043bcdb..5458519195d27158f53479b601dc63dddbf2ad34 100644 --- a/net/tcp/tcp_wrbuffer_dump.c +++ b/net/tcp/tcp_wrbuffer_dump.c @@ -48,10 +48,6 @@ #ifdef CONFIG_DEBUG -/**************************************************************************** - * Pre-processor definitions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/udp/Make.defs b/net/udp/Make.defs index 3b4d1062af6c792b422c893317c088572a01ea9e..76c72b33ab00401a0b700489332ad3b9ff14dcee 100644 --- a/net/udp/Make.defs +++ b/net/udp/Make.defs @@ -39,7 +39,7 @@ ifeq ($(CONFIG_NET_UDP),y) # Socket layer -NET_CSRCS += udp_sendto.c +NET_CSRCS += udp_psock_send.c udp_psock_sendto.c ifneq ($(CONFIG_DISABLE_POLL),y) ifeq ($(CONFIG_NET_UDP_READAHEAD),y) diff --git a/net/udp/udp.h b/net/udp/udp.h index 66612eef814d1b1c375c31f38cce7f42704b08d8..91447d25965a8e41f398b08201951ce75d7c77b6 100644 --- a/net/udp/udp.h +++ b/net/udp/udp.h @@ -425,6 +425,17 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn); uint16_t udp_callback(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, uint16_t flags); +/**************************************************************************** + * Function: psock_udp_send + * + * Description: + * Implements send() for connected UDP sockets + * + ****************************************************************************/ + +ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf, + size_t len); + /**************************************************************************** * Function: psock_udp_sendto * diff --git a/net/udp/udp_callback.c b/net/udp/udp_callback.c index f99aa2eac1d673d0c6cce3b72ab4c43809900304..86b733f81a3de4da34f4bfb93425f8c01fe52d5c 100644 --- a/net/udp/udp_callback.c +++ b/net/udp/udp_callback.c @@ -63,10 +63,6 @@ #define UDPIPv4BUF ((FAR struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv4_HDRLEN]) #define UDPIPv6BUF ((FAR struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN]) -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -174,7 +170,7 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con * any failure to allocated, the entire I/O buffer chain will be discarded. */ - ret = iob_trycopyin(iob, (FAR const uint8_t*)&src_addr_size, + ret = iob_trycopyin(iob, (FAR const uint8_t *)&src_addr_size, sizeof(uint8_t), 0, true); if (ret < 0) { @@ -187,7 +183,7 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con return 0; } - ret = iob_trycopyin(iob, (FAR const uint8_t*)src_addr, src_addr_size, + ret = iob_trycopyin(iob, (FAR const uint8_t *)src_addr, src_addr_size, sizeof(uint8_t), true); if (ret < 0) { @@ -200,19 +196,23 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con return 0; } - /* Copy the new appdata into the I/O buffer chain */ - - ret = iob_trycopyin(iob, buffer, buflen, src_addr_size + sizeof(uint8_t), - true); - if (ret < 0) + if (buflen > 0) { - /* On a failure, iob_trycopyin return a negated error value but does - * not free any I/O buffers. - */ + /* Copy the new appdata into the I/O buffer chain */ - nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret); - (void)iob_free_chain(iob); - return 0; + ret = iob_trycopyin(iob, buffer, buflen, + src_addr_size + sizeof(uint8_t), true); + if (ret < 0) + { + /* On a failure, iob_trycopyin return a negated error value but + * does not free any I/O buffers. + */ + + nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n", + ret); + (void)iob_free_chain(iob); + return 0; + } } /* Add the new I/O buffer chain to the tail of the read-ahead queue */ @@ -243,6 +243,11 @@ net_dataevent(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, uint16_t flags) { uint16_t ret; +#ifdef CONFIG_NET_UDP_READAHEAD + uint8_t *buffer = dev->d_appdata; + int buflen = dev->d_len; + uint16_t recvlen; +#endif ret = (flags & ~UDP_NEWDATA); @@ -250,35 +255,26 @@ net_dataevent(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, * can have zero-length with UDP_NEWDATA set just to cause an ACK). */ - if (dev->d_len > 0) - { -#ifdef CONFIG_NET_UDP_READAHEAD - uint8_t *buffer = dev->d_appdata; - int buflen = dev->d_len; - uint16_t recvlen; -#endif - - nllvdbg("No receive on connection\n"); + nllvdbg("No receive on connection\n"); #ifdef CONFIG_NET_UDP_READAHEAD - /* Save as the packet data as in the read-ahead buffer. NOTE that - * partial packets will not be buffered. - */ + /* Save as the packet data as in the read-ahead buffer. NOTE that + * partial packets will not be buffered. + */ - recvlen = udp_datahandler(dev, conn, buffer, buflen); - if (recvlen < buflen) + recvlen = udp_datahandler(dev, conn, buffer, buflen); + if (recvlen < buflen) #endif - { - /* There is no handler to receive new data and there are no free - * read-ahead buffers to retain the data -- drop the packet. - */ + { + /* There is no handler to receive new data and there are no free + * read-ahead buffers to retain the data -- drop the packet. + */ - nllvdbg("Dropped %d bytes\n", dev->d_len); + nllvdbg("Dropped %d bytes\n", dev->d_len); - #ifdef CONFIG_NET_STATISTICS - g_netstats.udp.drop++; +#ifdef CONFIG_NET_STATISTICS + g_netstats.udp.drop++; #endif - } } /* In any event, the new data has now been handled */ diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c index fbc8c8c9c84e53258f8fd110ee13f866aa49a5bb..ddd599382e55cc12a2e0afa19ec2e4682095a4ad 100644 --- a/net/udp/udp_conn.c +++ b/net/udp/udp_conn.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/udp/udp_conn.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Large parts of this file were leveraged from uIP logic: @@ -115,7 +115,7 @@ static inline void _udp_semtake(FAR sem_t *sem) * the wait was awakened by a signal. */ - ASSERT(*get_errno_ptr() == EINTR); + ASSERT(get_errno() == EINTR); } } @@ -141,7 +141,7 @@ static FAR struct udp_conn_s *udp_find_conn(uint16_t portno) FAR struct udp_conn_s *conn; int i; - /* Now search each connection structure.*/ + /* Now search each connection structure. */ for (i = 0; i < CONFIG_NET_UDP_CONNS; i++) { diff --git a/net/udp/udp_devpoll.c b/net/udp/udp_devpoll.c index 8352b7b2669e778f3c9986473d5dafda1af85813..22962173dbe58d412049ee1f17e7e5b41e1e3e19 100644 --- a/net/udp/udp_devpoll.c +++ b/net/udp/udp_devpoll.c @@ -54,22 +54,6 @@ #include "devif/devif.h" #include "udp/udp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/udp/udp_finddev.c b/net/udp/udp_finddev.c index 38287d887d68fb8a435c880c608365313bb3ebbe..c943ab3796480a460f1e1af32bf2a72a26e625ec 100644 --- a/net/udp/udp_finddev.c +++ b/net/udp/udp_finddev.c @@ -48,14 +48,6 @@ #include "netdev/netdev.h" #include "udp/udp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/udp/udp_input.c b/net/udp/udp_input.c index f699e74ffbec1bcd4a4ce70287041fd890bb6c1d..640fd617ad784081198c56db99e5c82d8fb55da9 100644 --- a/net/udp/udp_input.c +++ b/net/udp/udp_input.c @@ -56,18 +56,6 @@ #include "utils/utils.h" #include "udp/udp.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/net/udp/udp_ipselect.c b/net/udp/udp_ipselect.c index 7c5227ba258ab4e5c339fbbe6206df64a02bdafd..286e79610270f07baa6d3f6ae03f1399659e5513 100644 --- a/net/udp/udp_ipselect.c +++ b/net/udp/udp_ipselect.c @@ -50,14 +50,6 @@ #include "udp/udp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -77,9 +69,9 @@ void udp_ipv4_select(FAR struct net_driver_s *dev) IFF_SET_IPv4(dev->d_flags); - /* Set the offset to the beginning of the UDP data payload */ + /* Set the offset to the beginning of the UDP data payload */ - dev->d_appdata = &dev->d_buf[IPv4UDP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv4UDP_HDRLEN + NET_LL_HDRLEN(dev)]; } #endif /* CONFIG_NET_IPv4 */ @@ -98,9 +90,9 @@ void udp_ipv6_select(FAR struct net_driver_s *dev) IFF_SET_IPv6(dev->d_flags); - /* Set the offset to the beginning of the UDP data payload */ + /* Set the offset to the beginning of the UDP data payload */ - dev->d_appdata = &dev->d_buf[IPv6UDP_HDRLEN + NET_LL_HDRLEN(dev)]; + dev->d_appdata = &dev->d_buf[IPv6UDP_HDRLEN + NET_LL_HDRLEN(dev)]; } #endif /* CONFIG_NET_IPv6 */ diff --git a/net/udp/udp_psock_send.c b/net/udp/udp_psock_send.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e2eb0c881d50d20d18471299080b9352310ff3 --- /dev/null +++ b/net/udp/udp_psock_send.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * net/udp/udp_psock_send.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "socket/socket.h" +#include "udp/udp.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: psock_udp_send + * + * Description: + * Implements send() for connected UDP sockets + * + ****************************************************************************/ + +ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf, + size_t len) +{ + FAR struct udp_conn_s *conn; + union + { + struct sockaddr addr; +#ifdef CONFIG_NET_IPv4 + struct sockaddr_in addr4; +#endif +#ifdef CONFIG_NET_IPv6 + struct sockaddr_in6 addr6; +#endif + } to; + socklen_t tolen; + + DEBUGASSERT(psock != NULL && psock->s_crefs > 0); + DEBUGASSERT(psock->s_type != SOCK_DGRAM); + + conn = (FAR struct udp_conn_s *)psock->s_conn; + DEBUGASSERT(conn); + + /* Was the UDP socket connected via connect()? */ + + if (!_SS_ISCONNECTED(psock->s_flags)) + { + /* No, then it is not legal to call send() with this socket. */ + + return -ENOTCONN; + } + + /* Yes, then let psock_sendto to the work */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (conn->domain == PF_INET) +#endif + { + tolen = sizeof(struct sockaddr_in); + to.addr4.sin_family = AF_INET; + to.addr4.sin_port = conn->rport; + net_ipv4addr_copy(to.addr4.sin_addr.s_addr, conn->u.ipv4.raddr); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + tolen = sizeof(struct sockaddr_in6); + to.addr6.sin6_family = AF_INET6; + to.addr6.sin6_port = conn->rport; + net_ipv6addr_copy(to.addr6.sin6_addr.s6_addr, conn->u.ipv6.raddr); + } +#endif /* CONFIG_NET_IPv6 */ + + return psock_udp_sendto(psock, buf, len, 0, &to.addr, tolen); +} diff --git a/net/udp/udp_sendto.c b/net/udp/udp_psock_sendto.c similarity index 97% rename from net/udp/udp_sendto.c rename to net/udp/udp_psock_sendto.c index e1463f7fee5bb7442965f43f0c452d4be138de81..71fbe55af186a569eee4040440ed648958e63d79 100644 --- a/net/udp/udp_sendto.c +++ b/net/udp/udp_psock_sendto.c @@ -1,7 +1,7 @@ /**************************************************************************** - * net/udp/udp_sendto.c + * net/udp/udp_psock_sendto.c * - * Copyright (C) 2007-2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ struct sendto_s FAR struct socket *st_sock; /* Points to the parent socket structure */ #endif #ifdef CONFIG_NET_SENDTO_TIMEOUT - uint32_t st_time; /* Last send time for determining timeout */ + systime_t st_time; /* Last send time for determining timeout */ #endif FAR struct devif_callback_s *st_cb; /* Reference to callback instance */ sem_t st_sem; /* Semaphore signals sendto completion */ @@ -247,10 +247,10 @@ static uint16_t sendto_interrupt(FAR struct net_driver_s *dev, FAR void *conn, else if (dev->d_sndlen > 0 || (flags & UDP_NEWDATA) != 0) { - /* Another thread has beat us sending data or the buffer is busy, - * Check for a timeout. If not timed out, wait for the next - * polling cycle and check again. - */ + /* Another thread has beat us sending data or the buffer is busy, + * Check for a timeout. If not timed out, wait for the next + * polling cycle and check again. + */ #ifdef CONFIG_NET_SENDTO_TIMEOUT if (send_timeout(pstate)) @@ -441,7 +441,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, if (state.st_cb) { state.st_cb->flags = (UDP_POLL | NETDEV_DOWN); - state.st_cb->priv = (void*)&state; + state.st_cb->priv = (FAR void *)&state; state.st_cb->event = sendto_interrupt; /* Notify the device driver of the availability of TX data */ diff --git a/net/udp/udp_send.c b/net/udp/udp_send.c index c54933d7154b0c98563674e9e85f86e763540bb9..b764fade4204bdbe38de7b781a8a5ebff72dd4c5 100644 --- a/net/udp/udp_send.c +++ b/net/udp/udp_send.c @@ -74,18 +74,6 @@ #define UDPIPv6BUF \ ((struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN]) -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -122,7 +110,7 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) #ifdef CONFIG_NET_IPv6 if (conn->domain == PF_INET || (conn->domain == PF_INET6 && - ip6_is_ipv4addr((FAR struct in6_addr*)conn->u.ipv6.raddr))) + ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr))) #endif { /* Get pointers to the IPv4 header and the offset TCP header */ @@ -148,9 +136,9 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) #ifdef CONFIG_NET_IPv6 if (conn->domain == PF_INET6 && - ip6_is_ipv4addr((FAR struct in6_addr*)conn->u.ipv6.raddr)) + ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr)) { - in_addr_t raddr = ip6_get_ipv4addr((FAR struct in6_addr*)conn->u.ipv6.raddr); + in_addr_t raddr = ip6_get_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr); net_ipv4addr_hdrcopy(ipv4->destipaddr, &raddr); } else @@ -242,7 +230,7 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn) #ifdef CONFIG_NET_IPv6 if (conn->domain == PF_INET || (conn->domain == PF_INET6 && - ip6_is_ipv4addr((FAR struct in6_addr*)conn->u.ipv6.raddr))) + ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr))) #endif { udp->udpchksum = ~udp_ipv4_chksum(dev); diff --git a/net/utils/Make.defs b/net/utils/Make.defs index 6be4afdfc1f5e644e033cccb596a15dfda8ea84a..5abcb9226c77dd2c082e24e43d731c650c057b76 100644 --- a/net/utils/Make.defs +++ b/net/utils/Make.defs @@ -41,7 +41,7 @@ NET_CSRCS += net_chksum.c # IPv6 utilities ifeq ($(CONFIG_NET_IPv6),y) -NET_CSRCS += net_ipv6_maskcmp.c net_ipv6_pref2mask.c +NET_CSRCS += net_ipv6_maskcmp.c net_ipv6_mask2pref.c net_ipv6_pref2mask.c endif # Non-interrupt level support required? diff --git a/net/utils/net_chksum.c b/net/utils/net_chksum.c index 98732bcc62cac5cb966ed874884b8a4b94d9aa2b..9f4055c75647500a94ca8d5780900a0244e65e78 100644 --- a/net/utils/net_chksum.c +++ b/net/utils/net_chksum.c @@ -59,10 +59,6 @@ #define ICMPBUF ((struct icmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) #define ICMPv6BUF ((struct icmp_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -71,7 +67,7 @@ * Name: chksum ****************************************************************************/ -#if !CONFIG_NET_ARCH_CHKSUM +#ifndef CONFIG_NET_ARCH_CHKSUM static uint16_t chksum(uint16_t sum, FAR const uint8_t *data, uint16_t len) { FAR const uint8_t *dataptr; @@ -204,7 +200,7 @@ static uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, * ****************************************************************************/ -#if !CONFIG_NET_ARCH_INCR32 +#ifndef CONFIG_NET_ARCH_INCR32 static inline void net_carry32(FAR uint8_t *sum, uint16_t op16) { if (sum[2] < (op16 >> 8)) @@ -254,7 +250,7 @@ static inline void net_carry32(FAR uint8_t *sum, uint16_t op16) * ****************************************************************************/ -#if !CONFIG_NET_ARCH_INCR32 +#ifndef CONFIG_NET_ARCH_INCR32 void net_incr32(FAR uint8_t *op32, uint16_t op16) { op32[3] += (op16 & 0xff); @@ -288,7 +284,7 @@ void net_incr32(FAR uint8_t *op32, uint16_t op16) * ****************************************************************************/ -#if !CONFIG_NET_ARCH_CHKSUM +#ifndef CONFIG_NET_ARCH_CHKSUM uint16_t net_chksum(FAR uint16_t *data, uint16_t len) { return htons(chksum(0, (uint8_t *)data, len)); @@ -341,7 +337,7 @@ uint16_t ipv4_chksum(FAR struct net_driver_s *dev) * ****************************************************************************/ -#if !CONFIG_NET_ARCH_CHKSUM +#ifndef CONFIG_NET_ARCH_CHKSUM #ifdef CONFIG_NET_IPv4 uint16_t tcp_ipv4_chksum(FAR struct net_driver_s *dev) { @@ -413,7 +409,7 @@ uint16_t udp_ipv6_chksum(FAR struct net_driver_s *dev) uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len) { FAR struct icmp_iphdr_s *icmp = ICMPBUF; - return net_chksum((uint16_t*)&icmp->type, len); + return net_chksum((FAR uint16_t *)&icmp->type, len); } #endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING */ diff --git a/net/utils/net_dsec2tick.c b/net/utils/net_dsec2tick.c index 833ce48c0ee5d3e92b66bd4fb87f8589e80fa911..96a28db005053cca42315b5cd04616dcffc4abbe 100644 --- a/net/utils/net_dsec2tick.c +++ b/net/utils/net_dsec2tick.c @@ -40,14 +40,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/utils/net_ipv6_mask2pref.c b/net/utils/net_ipv6_mask2pref.c new file mode 100644 index 0000000000000000000000000000000000000000..763fc0188a8514454fc5e116ad2653d748264c87 --- /dev/null +++ b/net/utils/net_ipv6_mask2pref.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * net/utils/net_ipv6_mask2pref.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "utils/utils.h" + +#ifdef CONFIG_NET_IPv6 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_nibblemap[16] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0: No bits, 1-7: Should not happen */ + 1, 1, 1, 1, /* 8: 1 bit, 9-b: Should not happen */ + 2, 2, 3, 4 /* c: 2 bits, d: Should not happen, e: 3 bits, f: 4 bits */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_msbits4 + * + * Description: + * Count the number of leading '1' bits in an 4-bit nibble + * + ****************************************************************************/ + +static inline uint8_t net_msbits4(uint8_t nibble) +{ + /* Return the number of leading zeroes: 0-4) */ + + return g_nibblemap[nibble]; +} + +/**************************************************************************** + * Name: net_msbits8 + * + * Description: + * Count the number of leading '1' bits in an 8-bit byte + * + ****************************************************************************/ + +static uint8_t net_msbits8(uint8_t byval) +{ + uint8_t ones; + + /* Check the MS nibble */ + + ones = net_msbits4(byval >> 4); + if (ones == 4) + { + /* All ones, try the LS nibble */ + + ones += net_msbits4(byval & 0x0f); + } + + /* Return the number of leading ones (0-8) */ + + return ones; +} + +/**************************************************************************** + * Name: net_msbits16 + * + * Description: + * Count the number of leading '1' bits in a 16-bit half-workd + * + ****************************************************************************/ + +static inline uint8_t net_msbits16(uint16_t hword) +{ + uint8_t ones; + + /* Look at the MS byte of the 16-bit value */ + + ones = net_msbits8((uint8_t)(hword >> 8)); + if (ones == 8) + { + /* All '1's, try the LS byte */ + + ones += net_msbits8((uint8_t)(hword & 0xff)); + } + + /* Return the number of leading ones (0-15) */ + + return ones; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_ipv6_mask2pref + * + * Description: + * Convert a 128-bit netmask to a prefix length. The Nuttx IPv6 + * networking uses 128-bit network masks internally. This function + * converts the IPv6 netmask to a prefix length. + * + * The prefix length is the number of MS '1' bits on in the netmask. + * This, of course, assumes that all MS bits are '1' and all LS bits are + * '0' with no intermixed 1's and 0's. This function searches from the MS + * bit until the first '0' is found (this does not necessary mean that + * there might not be additional '1' bits following the firs '0', but that + * will be a malformed netmask. + * + * Parameters: + * mask Points to an IPv6 netmask in the form of uint16_t[8] + * + * Return: + * The prefix length, range 0-128 on success; This function will not + * fail. + * + ****************************************************************************/ + +uint8_t net_ipv6_mask2pref(FAR const uint16_t *mask) +{ + uint8_t preflen; + int i; + + /* Count the leading all '1' 16-bit groups */ + + for (i = 0, preflen = 0; i < 8 && mask[i] == 0xffff; i++, preflen += 16); + + /* Now i either, (1) indexes past the end of the mask, or (2) is the index + * to the first half-word that is not equal to 0xffff. + */ + + if (i < 8) + { + preflen += net_msbits16(ntohs(mask[i])); + } + + /* Return the prefix length */ + + return preflen; +} + +#endif /* CONFIG_NET_IPv6 */ diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index da359840ceb64cd1a99af5d61bee64526781373f..49ce834070f8714e9f5ae85877c30baad568d1b5 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/utils/net_lock.c * - * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -197,7 +198,7 @@ int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) irqstate_t flags; int ret; - flags = irqsave(); /* No interrupts */ + flags = enter_critical_section(); /* No interrupts */ sched_lock(); /* No context switches */ if (g_holder == me) { @@ -235,7 +236,7 @@ int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) } sched_unlock(); - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/net/utils/utils.h b/net/utils/utils.h index d3644d446abd9ac900a8cac0e9f7f4681d55f6de..355e75e51e78ea7d9cdae3b989357f9d7b4fd4d3 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -44,10 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Types ****************************************************************************/ @@ -151,6 +147,34 @@ unsigned int net_dsec2tick(int dsec); unsigned int net_timeval2dsec(FAR struct timeval *tv, enum tv2ds_remainder_e remainder); +/**************************************************************************** + * Name: net_ipv6_mask2pref + * + * Description: + * Convert a 128-bit netmask to a prefix length. The Nuttx IPv6 + * networking uses 128-bit network masks internally. This function + * converts the IPv6 netmask to a prefix length. + * + * The prefix length is the number of MS '1' bits on in the netmask. + * This, of course, assumes that all MS bits are '1' and all LS bits are + * '0' with no intermixed 1's and 0's. This function searches from the MS + * bit until the first '0' is found (this does not necessary mean that + * there might not be additional '1' bits following the firs '0', but that + * will be a malformed netmask. + * + * Parameters: + * mask Points to an IPv6 netmask in the form of uint16_t[8] + * + * Return: + * The prefix length, range 0-128 on success; This function will not + * fail. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +uint8_t net_ipv6_mask2pref(FAR const uint16_t *mask); +#endif + /**************************************************************************** * Function: net_ipv6_pref2mask * diff --git a/sched/Kconfig b/sched/Kconfig index be15080ea49a9046b78c185d7c296131455a3d03..dc9d7d13d93e52e1e20ce96da7a9d6597db6be36 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -147,7 +147,7 @@ config SYSTEM_TIME64 USEC_PER_TICK, typically at 100Hz. The count at any given time is then the "uptime" in units of system timer ticks. By default, the system time is 32-bits wide. Those defaults provide a range of about - 13.6 years which is probably a sufficient range for "uptime". + 497 days which is probably a sufficient range for "uptime". However, if the system timer rate is significantly higher than 100Hz and/or if a very long "uptime" is required, then this option can be @@ -229,6 +229,44 @@ endmenu # Clocks and Timers menu "Tasks and Scheduling" +config SPINLOCK + bool "Support Spinlocks" + default n + depends on EXPERIMENTAL + ---help--- + Enables suppport for spinlocks. Spinlocks are current used only for + SMP suppport. + +config SMP + bool "Symmetric Multi-Processing (SMP)" + default n + depends on ARCH_HAVE_MULTICPU && EXPERIMENTAL + select SPINLOCK + ---help--- + Enables support for Symmetric Multi-Processing (SMP) on a multi-CPU + platform. + +if SMP + +config SMP_NCPUS + int "Number of CPUs" + default 4 + range 2 32 + ---help--- + This value identifies the number of CPUs supported by the processor + that will be used for SMP. + +config SMP_IDLETHREAD_STACKSIZE + int "CPU IDLE stack size" + default 2048 + ---help--- + Each CPU will have its own IDLE task. System initialization occurs + on CPU0 and uses CONFIG_IDLETHREAD_STACKSIZE which will probably be + larger than is generally needed. This setting provides the stack + size for the IDLE task on CPUS 1 through (CONFIG_SMP_NCPUS-1). + +endif # SMP + choice prompt "Initialization Task" default INIT_ENTRYPOINT if !BUILD_KERNEL @@ -332,10 +370,10 @@ config SPORADIC_INSTRUMENTATION scheduler behavior. If enabled, then the board-specific logic must provide the following functions: - void arch_sporadic_start(FAR struct tcb_s *tcb); - void arch_sporadic_lowpriority(FAR struct tcb_s *tcb); - void arch_sporadic_suspend(FAR struct tcb_s *tcb); - void arch_sporadic_resume(FAR struct tcb_s *tcb); + void arch_sporadic_start(FAR struct tcb_s *tcb); + void arch_sporadic_lowpriority(FAR struct tcb_s *tcb); + void arch_sporadic_suspend(FAR struct tcb_s *tcb); + void arch_sporadic_resume(FAR struct tcb_s *tcb); endif # SCHED_SPORADIC @@ -500,6 +538,11 @@ config SCHED_CPULOAD The statistics collected in this could be used, for example in the PROCFS file system to provide CPU load measurements when read. + Note that in tickless mode of operation (SCHED_TICKLESS) there is + no system timer interrupt and CPU load measurements will not be + possible unless you provide an alternative clock to driver the + sampling and select SCHED_CPULOAD_EXTCLK. + if SCHED_CPULOAD config SCHED_CPULOAD_EXTCLK @@ -558,10 +601,72 @@ config SCHED_INSTRUMENTATION If enabled, then the board-specific logic must provide the following functions (see include/sched.h): - void sched_note_start(FAR struct tcb_s *tcb); - void sched_note_stop(FAR struct tcb_s *tcb); - void sched_note_switch(FAR struct tcb_s *pFromTcb, FAR struct tcb_s *pToTcb); + void sched_note_start(FAR struct tcb_s *tcb); + void sched_note_stop(FAR struct tcb_s *tcb); + void sched_note_switch(FAR struct tcb_s *pFromTcb, FAR struct tcb_s *pToTcb); + + NOTE: These are internal OS interfaces and are called at at very + critical locations in the OS. There is very little that can be + done in these interfaces. For example, normal devices may not be + used; syslog output cannot be performed. + + An option is to use SCHED_INSTRUMENTATION_BUFFER below. + +if SCHED_INSTRUMENTATION + +config SCHED_INSTRUMENTATION_PREEMPTION + bool "Preemption monitor hooks" + default n + ---help--- + Enables additional hooks for changes to pre-emption state. Board- + specific logic must provide this additional logic. + + void sched_note_premption(FAR struct tcb_s *tcb, bool state); + +config SCHED_INSTRUMENTATION_CSECTION + bool "Critical section monitor hooks" + default n + depends on SMP + ---help--- + Enables additional hooks for entry and exit from critical sections. + Interrupts are disabled while within a critical section. Board- + specific logic must provide this additional logic. + + void sched_note_csection(FAR struct tcb_s *tcb, bool state); + +config SCHED_INSTRUMENTATION_BUFFER + bool "Buffer instrumentation data in memory" + default n + ---help--- + If this option is selected, then in-memory buffering logic is + enabled to capature scheduler instrumentation data. This has + the advantage that (1) the platform logic does not have to provide + the sched_note_* interaces described for the previous settings. + Instead, the buffering logic catches all of these. It encodes + timestamps the scheduler note and adds the note to an in-memory, + circular buffer. And (2) buffering the scheduler instrumentation + data (versus performing some output operation) minimizes the impact + of the instrumentation on the behavior of the system. + + If the in-memory buffer becomes full, then older notes are + overwritten by newer notes. The following interface is provided: + + ssize_t sched_note_get(FAR uint8_t *buffer, size_t buflen); + + Platform specific information must call this function and dispose + of it quickly so that overwriting of the tail of the circular buffer + does not occur. See include/nuttx/sched_note.h for additional + information. + +config SCHED_NOTE_BUFSIZE + int "Instrumentation buffer size" + default 2048 + depends on SCHED_INSTRUMENTATION_BUFFER + ---help--- + The size of the in-memory, circular instrumentation buffer (in + bytes). +endif # SCHED_INSTRUMENTATION endmenu # Performance Monitoring menu "Files and I/O" @@ -606,7 +711,7 @@ config SDCLONE_DISABLE default n ---help--- Disable cloning of all socket - desciptors by task_create() when a new task is started. If + descriptors by task_create() when a new task is started. If set, all sockets will appear to be closed in the new task. config NFILE_DESCRIPTORS @@ -775,6 +880,18 @@ config SCHED_ONEXIT_MAX endmenu # RTOS hooks +config SIG_EVTHREAD + bool "Support SIGEV_THHREAD" + default n + depends on BUILD_FLAT && SCHED_WORKQUEUE + ---help--- + Built in support for the SIGEV_THREAD signal deliver method. + + NOTE: The current implementation uses a work queue to notify the + client. This, however, would only work in the FLAT build. A + different mechanism would need to be development to support this + feature on the PROTECTED or KERNEL build. + menu "Signal Numbers" depends on !DISABLE_SIGNALS @@ -852,7 +969,48 @@ config MQ_MAXMSGSIZE endmenu # POSIX Message Queue Options -menu "Work Queue Support" +menuconfig MODULE + bool "Enable loadable OS modules" + default n + ---help--- + Enable support for loadable OS modules. Default: n + +if MODULE + +config MODULE_ALIGN_LOG2 + int "Log2 Section Alignment" + default 2 + ---help--- + Align all sections to this Log2 value: 0->1, 1->2, 2->4, etc. + +config MODULE_BUFFERSIZE + int "Module I/O Buffer Size" + default 128 + ---help--- + This is an I/O buffer that is used to access the module file. + Variable length items will need to be read (such as symbol names). + This is really just this initial size of the buffer; it will be + reallocated as necessary to hold large symbol names). Default: 128 + +config MODULE_BUFFERINCR + int "Module I/O Buffer Realloc Increment" + default 32 + ---help--- + This is an I/O buffer that is used to access the module file. + Variable length items will need to be read (such as symbol names). + This value specifies the size increment to use each time the + buffer is reallocated. Default: 32 + +config MODULE_DUMPBUFFER + bool "Dump module buffers" + default n + depends on DEBUG && DEBUG_VERBOSE + ---help--- + Dump various module buffers for debug purposes + +endif + +menu "Work queue support" config SCHED_WORKQUEUE # bool "Enable worker thread" diff --git a/sched/Makefile b/sched/Makefile index 64d243a896bc404550c3deed33eb146bf4de59d5..63d1c519edd894fdc484168f2bc463f65fa45805 100644 --- a/sched/Makefile +++ b/sched/Makefile @@ -1,7 +1,7 @@ ############################################################################ # sched/Makefile # -# Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -41,21 +41,22 @@ CSRCS = VPATH = DEPPATH = --dep-path . +include clock/Make.defs +include errno/Make.defs +include environ/Make.defs +include group/Make.defs include init/Make.defs include irq/Make.defs +include mqueue/Make.defs +include module/Make.defs include paging/Make.defs -include group/Make.defs +include pthread/Make.defs include sched/Make.defs -include task/Make.defs -include errno/Make.defs -include wdog/Make.defs include semaphore/Make.defs include signal/Make.defs -include pthread/Make.defs -include mqueue/Make.defs -include clock/Make.defs +include task/Make.defs include timer/Make.defs -include environ/Make.defs +include wdog/Make.defs include wqueue/Make.defs AOBJS = $(ASRCS:.S=$(OBJEXT)) diff --git a/sched/clock/Make.defs b/sched/clock/Make.defs index 927c41625d0b27d4d729988e08b0068441ec566a..c0bc23f51017f5b357b777e2efb80453a54d924b 100644 --- a/sched/clock/Make.defs +++ b/sched/clock/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # sched/clock/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without diff --git a/sched/clock/clock.h b/sched/clock/clock.h index 154af6f5a3e75f74f0fd1b11065652a3a9e070c3..8a5c55a3e767b162659a1ec3fea3b07c5660ff58 100644 --- a/sched/clock/clock.h +++ b/sched/clock/clock.h @@ -64,7 +64,7 @@ ********************************************************************************/ /******************************************************************************** - * Global Variables + * Public Data ********************************************************************************/ #if !defined(CONFIG_SCHED_TICKLESS) && !defined(__HAVE_KERNEL_GLOBALS) diff --git a/sched/clock/clock_abstime2ticks.c b/sched/clock/clock_abstime2ticks.c index 46b1086856de0cf1c3b2e07ca16223ee062e83c4..24213dd07b29a80acbf500791fd0caa79c178b3a 100644 --- a/sched/clock/clock_abstime2ticks.c +++ b/sched/clock/clock_abstime2ticks.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/clock/clock_abstime2ticks.c * - * Copyright (C) 2007, 2008, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2013-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,22 +44,6 @@ #include #include "clock/clock.h" -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - /******************************************************************************** * Private Functions ********************************************************************************/ @@ -85,7 +69,7 @@ static long compare_timespec(FAR const struct timespec *a, if (a->tv_sec > b->tv_sec) { return 1; - } + } return (long)a->tv_nsec -(long)b->tv_nsec; } diff --git a/sched/clock/clock_dow.c b/sched/clock/clock_dow.c index 00e9703bc57665c3f78d0f29c3ed1bb8f4630169..c105d1edaa304b9a9b354b12e0f99eb33b487894 100644 --- a/sched/clock/clock_dow.c +++ b/sched/clock/clock_dow.c @@ -45,10 +45,6 @@ #include "clock/clock.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Data ****************************************************************************/ diff --git a/sched/clock/clock_getres.c b/sched/clock/clock_getres.c index ef48a363ebccabbf1cabebbfdacb78c3ad03bb30..aad5dec9c32a1deee788b75bd83fb2f1980e8ea2 100644 --- a/sched/clock/clock_getres.c +++ b/sched/clock/clock_getres.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/clock/clock_getres.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,45 +46,17 @@ #include "clock/clock.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/********************************************************************** - * Public Constant Data - **********************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: clock_getres * * Description: * Clock Functions based on POSIX APIs * - ************************************************************************/ + ****************************************************************************/ int clock_getres(clockid_t clock_id, struct timespec *res) { diff --git a/sched/clock/clock_gettime.c b/sched/clock/clock_gettime.c index ddd71a2e1706410c18354770402e7ea41e14c161..50e3c6e7c12781eb4a9d649547f3aae3d42766fa 100644 --- a/sched/clock/clock_gettime.c +++ b/sched/clock/clock_gettime.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/clock/clock_gettime.c * - * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,45 +50,17 @@ #include "clock/clock.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/********************************************************************** - * Public Constant Data - **********************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: clock_gettime * * Description: * Clock Functions based on POSIX APIs * - ************************************************************************/ + ****************************************************************************/ int clock_gettime(clockid_t clock_id, struct timespec *tp) { diff --git a/sched/clock/clock_initialize.c b/sched/clock/clock_initialize.c index 50a9af1050ee9a02aa6ba2b30dd2d266d89787d0..6e653e78e7f71a2fdb0b339027ea33cc0b6e8f60 100644 --- a/sched/clock/clock_initialize.c +++ b/sched/clock/clock_initialize.c @@ -46,7 +46,7 @@ #include #ifdef CONFIG_RTC -# include +# include #endif #include @@ -65,19 +65,7 @@ #define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR) /**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/************************************************************************** - * Public Constant Data - **************************************************************************/ - -/**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifndef CONFIG_SCHED_TICKLESS @@ -90,13 +78,9 @@ volatile uint32_t g_system_timer; struct timespec g_basetime; -/************************************************************************** - * Private Variables - **************************************************************************/ - -/************************************************************************** +/**************************************************************************** * Private Functions - **************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: clock_basetime @@ -110,47 +94,53 @@ struct timespec g_basetime; #if defined(CONFIG_RTC_DATETIME) /* Initialize the system time using a broken out date/time structure */ -static inline void clock_basetime(FAR struct timespec *tp) +static inline int clock_basetime(FAR struct timespec *tp) { struct tm rtctime; + int ret; /* Get the broken-out time from the date/time RTC. */ - (void)up_rtc_getdatetime(&rtctime); + ret = up_rtc_getdatetime(&rtctime); + if (ret >= 0) + { + /* And use the broken-out time to initialize the system time */ - /* And use the broken-out time to initialize the system time */ + tp->tv_sec = mktime(&rtctime); + tp->tv_nsec = 0; + } - tp->tv_sec = mktime(&rtctime); - tp->tv_nsec = 0; + return ret; } #elif defined(CONFIG_RTC_HIRES) /* Initialize the system time using a high-resolution structure */ -static inline void clock_basetime(FAR struct timespec *tp) +static inline int clock_basetime(FAR struct timespec *tp) { /* Get the complete time from the hi-res RTC. */ - (void)up_rtc_gettime(tp); + return up_rtc_gettime(tp); } #else /* Initialize the system time using seconds only */ -static inline void clock_basetime(FAR struct timespec *tp) +static inline int clock_basetime(FAR struct timespec *tp) { /* Get the seconds (only) from the lo-resolution RTC */ tp->tv_sec = up_rtc_time(); tp->tv_nsec = 0; + return OK; } #endif /* CONFIG_RTC_HIRES */ #else /* CONFIG_RTC */ -static inline void clock_basetime(FAR struct timespec *tp) +static inline int clock_basetime(FAR struct timespec *tp) { time_t jdn = 0; @@ -165,6 +155,7 @@ static inline void clock_basetime(FAR struct timespec *tp) tp->tv_sec = jdn * SEC_PER_DAY; tp->tv_nsec = 0; + return OK; } #endif /* CONFIG_RTC */ @@ -181,7 +172,7 @@ static void clock_inittime(void) { /* (Re-)initialize the time value to match the RTC */ - clock_basetime(&g_basetime); + (void)clock_basetime(&g_basetime); #ifndef CONFIG_SCHED_TICKLESS g_system_timer = 0; #endif @@ -201,10 +192,12 @@ static void clock_inittime(void) void clock_initialize(void) { - /* Initialize the RTC hardware */ +#if defined(CONFIG_RTC) && !defined(CONFIG_RTC_EXTERNAL) + /* Initialize the internal RTC hardware. Initialization of external RTC + * must be deferred until the system has booted. + */ -#ifdef CONFIG_RTC - up_rtcinitialize(); + up_rtc_initialize(); #endif /* Initialize the time value to match the RTC */ @@ -247,9 +240,9 @@ void clock_synchronize(void) /* Re-initialize the time value to match the RTC */ - flags = irqsave(); + flags = enter_critical_section(); clock_inittime(); - irqrestore(flags); + leave_critical_section(flags); } #endif diff --git a/sched/clock/clock_settime.c b/sched/clock/clock_settime.c index e9f27f0f6a37f873a2019c8b94aed31c7dea7f0d..640e375a63c1ad279fd6bf7bea844b5c1668bb79 100644 --- a/sched/clock/clock_settime.c +++ b/sched/clock/clock_settime.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/clock/clock_settime.c * * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,49 +45,21 @@ #include #include -#include +#include #include "clock/clock.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/********************************************************************** - * Public Constant Data - **********************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: clock_settime * * Description: * Clock Functions based on POSIX APIs * - ************************************************************************/ + ****************************************************************************/ int clock_settime(clockid_t clock_id, FAR const struct timespec *tp) { @@ -109,7 +81,7 @@ int clock_settime(clockid_t clock_id, FAR const struct timespec *tp) * possible. */ - flags = irqsave(); + flags = enter_critical_section(); /* Get the elapsed time since power up (in milliseconds). This is a * bias value that we need to use to correct the base time. @@ -146,7 +118,7 @@ int clock_settime(clockid_t clock_id, FAR const struct timespec *tp) up_rtc_settime(tp); } #endif - irqrestore(flags); + leave_critical_section(flags); sdbg("basetime=(%ld,%lu) bias=(%ld,%lu)\n", (long)g_basetime.tv_sec, (unsigned long)g_basetime.tv_nsec, diff --git a/sched/clock/clock_systimer.c b/sched/clock/clock_systimer.c index a87f36a0afbca9cc78c4a8017152402b471c5ba1..3e8e978ce994c16043f27d632f93788b29e6e8ca 100644 --- a/sched/clock/clock_systimer.c +++ b/sched/clock/clock_systimer.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/clock/clock_systimer.c * - * Copyright (C) 2011, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include +#include #include #include @@ -52,11 +53,6 @@ /* See nuttx/clock.h */ #undef clock_systimer -#undef clock_systimer64 - -/**************************************************************************** - * Private Data - ****************************************************************************/ /**************************************************************************** * Public Functions @@ -66,7 +62,7 @@ * Name: clock_systimer * * Description: - * Return the current value of the 32-bit system timer counter + * Return the current value of the 32/64-bit system timer counter * * Parameters: * None @@ -78,71 +74,55 @@ * ****************************************************************************/ -uint32_t clock_systimer(void) +systime_t clock_systimer(void) { #ifdef CONFIG_SCHED_TICKLESS +# ifdef CONFIG_SYSTEM_TIME64 + struct timespec ts; - uint64_t tmp; /* Get the time from the platform specific hardware */ (void)up_timer_gettime(&ts); - /* Convert to a 64- then 32-bit value */ + /* Convert to a 64-bit value in microseconds, then in clock tick units */ - tmp = MSEC2TICK(1000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000000); - return (uint32_t)(tmp & 0x00000000ffffffff); + return USEC2TICK(1000000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000); -#else +# else /* CONFIG_SYSTEM_TIME64 */ -#ifdef CONFIG_SYSTEM_TIME64 - /* Return the current system time truncated to 32-bits */ + struct timespec ts; + uint64_t tmp; - return (uint32_t)(g_system_timer & 0x00000000ffffffff); + /* Get the time from the platform specific hardware */ -#else - /* Return the current system time */ + (void)up_timer_gettime(&ts); - return g_system_timer; + /* Convert to a 64- then a 32-bit value */ -#endif -#endif -} + tmp = MSEC2TICK(1000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000000); + return (systime_t)(tmp & 0x00000000ffffffff); -/**************************************************************************** - * Name: clock_systimer64 - * - * Description: - * Return the current value of the 64-bit system timer counter - * - * Parameters: - * None - * - * Return Value: - * The current value of the system timer counter - * - * Assumptions: - * - ****************************************************************************/ +# endif /* CONFIG_SYSTEM_TIME64 */ +#else /* CONFIG_SCHED_TICKLESS */ +# ifdef CONFIG_SYSTEM_TIME64 -#ifdef CONFIG_SYSTEM_TIME64 -uint64_t clock_systimer64(void) -{ -#ifdef CONFIG_SCHED_TICKLESS - struct timespec ts; + irqstate_t flags; + systime_t sample; - /* Get the time from the platform specific hardware */ + /* 64-bit accesses are not atomic on most architectures. */ - (void)up_timer_gettime(&ts); + flags = enter_critical_section(); + sample = g_system_timer; + leave_critical_section(flags); + return sample; - /* Convert to a 64-bit value in microseconds, then in clock tick units */ +# else /* CONFIG_SYSTEM_TIME64 */ - return USEC2TICK(1000000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000); -#else /* Return the current system time */ return g_system_timer; -#endif +# endif /* CONFIG_SYSTEM_TIME64 */ +#endif /* CONFIG_SCHED_TICKLESS */ } -#endif diff --git a/sched/clock/clock_systimespec.c b/sched/clock/clock_systimespec.c index 37511f1d0aabb19fb45393e8bce17f7af5a5ca31..5d6009d0510fc1ab71da2d18f8a34db525ab7c19 100644 --- a/sched/clock/clock_systimespec.c +++ b/sched/clock/clock_systimespec.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/clock/clock_systimespec.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,14 +48,6 @@ #include "clock/clock.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -138,15 +130,20 @@ int clock_systimespec(FAR struct timespec *ts) return up_timer_gettime(ts); #elif defined(CONFIG_HAVE_LONG_LONG) && (CONFIG_USEC_PER_TICK % 1000) != 0 - /* 64-bit microsecond calculations should improve our accuracy. */ + /* 64-bit microsecond calculations should improve our accuracy + * when the clock period is in units of microseconds. + */ uint64_t usecs; uint64_t secs; uint64_t nsecs; - /* Get the time since power-on in seconds and milliseconds */ + /* Get the time since power-on in seconds and microseconds. + * NOTE that overflow is still possible if we use a 64-bit + * timer. + */ - usecs = TICK2MSEC(clock_systimer()); + usecs = (uint64_t)TICK2USEC(clock_systimer()); secs = usecs / USEC_PER_SEC; /* Return the elapsed time in seconds and nanoseconds */ @@ -158,11 +155,28 @@ int clock_systimespec(FAR struct timespec *ts) return OK; #else - /* 32-bit millisecond calculations should be just fine. */ + /* We know that the clock rate is in units of milliseconds + * show we should be able to do the calculations with less + * chance of overflow. + * + * 32-bit millisecond calculations should be just fine in + * most cases. For a 32-bit system timer and a clock period + * of 10 milliseconds, the msecs value will overflow at about + * 49.7 days. + * + * So.. we will still use 64-bit calculations if we have them + * in order to avoid that limitation. + */ - uint32_t msecs; - uint32_t secs; - uint32_t nsecs; +#ifdef CONFIG_HAVE_LONG_LONG + uint64_t msecs; + uint64_t secs; + uint64_t nsecs; +#else + systime_t msecs; + systime_t secs; + systime_t nsecs; +#endif /* Get the time since power-on in seconds and milliseconds */ diff --git a/sched/clock/clock_ticks2time.c b/sched/clock/clock_ticks2time.c index d77f8497f651de2380cc1c215abd973e69620a6e..b69379d827543f1c675ad55fe1bb85febca07a1f 100644 --- a/sched/clock/clock_ticks2time.c +++ b/sched/clock/clock_ticks2time.c @@ -42,26 +42,6 @@ #include #include "clock/clock.h" -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/clock/clock_time2ticks.c b/sched/clock/clock_time2ticks.c index df3407f2afc466e7bc34426ed1301ae9a1dc4633..8667e6bcd9dc1a94a5ff4413d7b26ba30608bfc5 100644 --- a/sched/clock/clock_time2ticks.c +++ b/sched/clock/clock_time2ticks.c @@ -44,26 +44,6 @@ #include "clock/clock.h" -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/clock/clock_timespec_add.c b/sched/clock/clock_timespec_add.c index 21688a2b816535d5593aa11babc34dd3b0af09ce..f2eae0dac26dccadfdb8ee579ef643da83e45d13 100644 --- a/sched/clock/clock_timespec_add.c +++ b/sched/clock/clock_timespec_add.c @@ -48,7 +48,7 @@ * Public Functions ********************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: clock_timespec_add * * Description: @@ -61,7 +61,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void clock_timespec_add(FAR const struct timespec *ts1, FAR const struct timespec *ts2, diff --git a/sched/clock/clock_timespec_subtract.c b/sched/clock/clock_timespec_subtract.c index 34b072542666e257f024f3c0a6637faae4301290..c02dc35538e57e8aa400676d9c6b5415e94fdba7 100644 --- a/sched/clock/clock_timespec_subtract.c +++ b/sched/clock/clock_timespec_subtract.c @@ -48,7 +48,7 @@ * Public Functions ********************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: clock_timespec_subtract * * Description: @@ -62,7 +62,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void clock_timespec_subtract(FAR const struct timespec *ts1, FAR const struct timespec *ts2, @@ -83,7 +83,7 @@ void clock_timespec_subtract(FAR const struct timespec *ts1, } else { - sec = ts1->tv_sec + ts2->tv_sec; + sec = ts1->tv_sec - ts2->tv_sec; if (ts1->tv_nsec < ts2->tv_nsec) { nsec = (ts1->tv_nsec + NSEC_PER_SEC) - ts2->tv_nsec; diff --git a/sched/environ/env_clearenv.c b/sched/environ/env_clearenv.c index e45939ce0e5d0c408e2acd32e9c08574766512ac..ededbadbed13173995950b30cae79df3a5b0cc66 100644 --- a/sched/environ/env_clearenv.c +++ b/sched/environ/env_clearenv.c @@ -46,10 +46,6 @@ #include "sched/sched.h" #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -74,7 +70,7 @@ int clearenv(void) { - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); DEBUGASSERT(tcb->group); env_release(tcb->group); diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 90abc1c98f152cd205a9a0d87114d7a8a1f087aa..1745385daffd3fd189ba6c6e71e97a3e380959db 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -51,10 +51,6 @@ #include "sched/sched.h" #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -81,7 +77,7 @@ int env_dup(FAR struct task_group_s *group) { - FAR struct tcb_s *ptcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *ptcb = this_task(); FAR char *envp = NULL; size_t envlen; int ret = OK; diff --git a/sched/environ/env_findvar.c b/sched/environ/env_findvar.c index 2112c14118c889bdc31ceae4816be821c572091c..f6b44da5c497c26a63fcc2c9aabeb73b743f3d78 100644 --- a/sched/environ/env_findvar.c +++ b/sched/environ/env_findvar.c @@ -47,10 +47,6 @@ #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -67,7 +63,7 @@ static bool env_cmpname(const char *pszname, const char *peqname) /* On sucess, pszname will end with '\0' and peqname with '=' */ - if ( *pszname == '\0' && *peqname == '=' ) + if (*pszname == '\0' && *peqname == '=') { return true; } diff --git a/sched/environ/env_getenv.c b/sched/environ/env_getenv.c index 51f886fe0fecba75b3183cbff80aa2faeca880d0..e5309be325a2f7088dea3a83f87104b82c966e35 100644 --- a/sched/environ/env_getenv.c +++ b/sched/environ/env_getenv.c @@ -49,10 +49,6 @@ #include "sched/sched.h" #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -94,12 +90,12 @@ FAR char *getenv(const char *name) /* Get a reference to the thread-private environ in the TCB. */ sched_lock(); - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); group = rtcb->group; /* Check if the variable exists */ - if ( !group || (pvar = env_findvar(group, name)) == NULL) + if (!group || (pvar = env_findvar(group, name)) == NULL) { ret = ENOENT; goto errout_with_lock; @@ -130,4 +126,3 @@ errout: } #endif /* CONFIG_DISABLE_ENVIRON */ - diff --git a/sched/environ/env_getenvironptr.c b/sched/environ/env_getenvironptr.c index f56a08a1b005c3c81fbd7f5920509c9d16950545..d392777392abcb7f4e13ee4f3241fe6f366d239a 100644 --- a/sched/environ/env_getenvironptr.c +++ b/sched/environ/env_getenvironptr.c @@ -47,10 +47,6 @@ #undef get_environ_ptr -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -71,7 +67,7 @@ * ****************************************************************************/ -FAR char **get_environ_ptr( void ) +FAR char **get_environ_ptr(void) { #if 1 @@ -85,7 +81,7 @@ FAR char **get_environ_ptr( void ) /* Return a reference to the thread-private environ in the TCB. */ - FAR struct tcb_s *ptcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *ptcb = this_task(); if (ptcb->envp) { return &ptcb->envp->ev_env; diff --git a/sched/environ/env_putenv.c b/sched/environ/env_putenv.c index aef05fc829ebb217ddb1cb3cd899ca5cfd4fcea3..484fd3ad59adbed396c568906a0281dc6aaa6ea2 100644 --- a/sched/environ/env_putenv.c +++ b/sched/environ/env_putenv.c @@ -48,10 +48,6 @@ #include -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -100,7 +96,7 @@ int putenv(FAR const char *string) goto errout; } - pequal = strchr( pname, '='); + pequal = strchr(pname, '='); if (pequal) { /* Then let setenv do all of the work */ diff --git a/sched/environ/env_release.c b/sched/environ/env_release.c index 67db8eda9f145226e8f293346f1432c58fb44109..d1ace0505b0ebb0ce338eb75e82840fc3d0f5129 100644 --- a/sched/environ/env_release.c +++ b/sched/environ/env_release.c @@ -48,10 +48,6 @@ #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/environ/env_removevar.c b/sched/environ/env_removevar.c index 4132eb26041e59ae74218cba4f76f6d214074104..b18ebbf899c7633f321c3ec59232b3b7f96f3ddb 100644 --- a/sched/environ/env_removevar.c +++ b/sched/environ/env_removevar.c @@ -46,10 +46,6 @@ #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/environ/env_setenv.c b/sched/environ/env_setenv.c index 92b118cfc8fd442decdbda30d3418bcfcd1ff968..38faae839a8fb87e7706b9c507912833587c7cb0 100644 --- a/sched/environ/env_setenv.c +++ b/sched/environ/env_setenv.c @@ -52,10 +52,6 @@ #include "sched/sched.h" #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -124,7 +120,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) /* Get a reference to the thread-private environ in the TCB. */ sched_lock(); - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); group = rtcb->group; DEBUGASSERT(group); diff --git a/sched/environ/env_unsetenv.c b/sched/environ/env_unsetenv.c index 013b9e68047cdd93b3812ef0ed5b1695c7e766f4..2956cfe783c5f2be3c00b0e388f9cace351fdcab 100644 --- a/sched/environ/env_unsetenv.c +++ b/sched/environ/env_unsetenv.c @@ -50,10 +50,6 @@ #include "sched/sched.h" #include "environ/environ.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -77,7 +73,7 @@ int unsetenv(FAR const char *name) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; FAR char *pvar; FAR char *newenvp; diff --git a/sched/environ/environ.h b/sched/environ/environ.h index 98fc98728a5757a739097d40f59963494b1a0f3e..7ad59626e5e09e58fcce7e0881fda960dcb76421 100644 --- a/sched/environ/environ.h +++ b/sched/environ/environ.h @@ -53,11 +53,7 @@ #else /**************************************************************************** - * Public Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef __cplusplus diff --git a/sched/errno/errno_get.c b/sched/errno/errno_get.c index 100facc335a6973e7d47b48768817f41824db7b2..8982ac61e735f659f0e453f32c13e83bc1e8d4e5 100644 --- a/sched/errno/errno_get.c +++ b/sched/errno/errno_get.c @@ -49,10 +49,6 @@ #undef get_errno #undef errno -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/errno/errno_getptr.c b/sched/errno/errno_getptr.c index 50a753d021d5d77dd9bcdb16eb3656226a44f74d..4e47895a0b4eda981427a7bfb3c2e917b01f5cc9 100644 --- a/sched/errno/errno_getptr.c +++ b/sched/errno/errno_getptr.c @@ -97,11 +97,11 @@ FAR int *get_errno_ptr(void) * logic (see, for example, task_exit.c). * * There is also a corner case early in the initialization sequence: - * The ready to run list may not yet be initialized and g_readytorun.head + * The ready to run list may not yet be initialized and this_task() * may be NULL. */ - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); if (rtcb && rtcb->task_state == TSTATE_TASK_RUNNING) { /* Yes.. the task is running normally. Return a reference to the diff --git a/sched/errno/errno_set.c b/sched/errno/errno_set.c index 73f8198977dab7c65dd353655707cb5f1a7cef12..540bc8b7829f2249862198779c71b8e83c608ca3 100644 --- a/sched/errno/errno_set.c +++ b/sched/errno/errno_set.c @@ -49,10 +49,6 @@ #undef set_errno #undef errno -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/group/Make.defs b/sched/group/Make.defs index e3b4cba93be4b949fda546c4aca7625127f3818a..91a025e1fd36149f266c3f7d91d31e6d1dfdd12b 100644 --- a/sched/group/Make.defs +++ b/sched/group/Make.defs @@ -42,6 +42,10 @@ CSRCS += task_reparent.c ifeq ($(CONFIG_SCHED_CHILD_STATUS),y) CSRCS += group_childstatus.c endif +else +ifeq ($(CONFIG_SCHED_WAITPID),y) +CSRCS += group_waiter.c +endif endif ifeq ($(CONFIG_ARCH_ADDRENV),y) diff --git a/sched/group/group.h b/sched/group/group.h index 2dc74e709a2a97e1dc6ea99c9f072429e03599e8..a508d5d462c99b3d2dfea385dbea78f23bd6e5e3 100644 --- a/sched/group/group.h +++ b/sched/group/group.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/group/group.h * - * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -102,6 +102,10 @@ int group_bind(FAR struct pthread_tcb_s *tcb); int group_join(FAR struct pthread_tcb_s *tcb); #endif void group_leave(FAR struct tcb_s *tcb); +#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT) +void group_addwaiter(FAR struct task_group_s *group); +void group_delwaiter(FAR struct task_group_s *group); +#endif #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) FAR struct task_group_s *group_findbygid(gid_t gid); diff --git a/sched/group/group_addrenv.c b/sched/group/group_addrenv.c index c1ddb07b6e5d35c3ae952bbd1b182012b7b0f71b..ddc27a4153fd9d6557fe9bb4745f4748336b560f 100644 --- a/sched/group/group_addrenv.c +++ b/sched/group/group_addrenv.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/group/group_addrenv.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include +#include #include #include "sched/sched.h" @@ -48,10 +49,6 @@ #ifdef CONFIG_ARCH_ADDRENV -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -64,10 +61,6 @@ gid_t g_gid_current; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -114,7 +107,7 @@ int group_addrenv(FAR struct tcb_s *tcb) if (!tcb) { - tcb = (FAR struct tcb_s *)g_readytorun.head; + tcb = this_task(); } DEBUGASSERT(tcb && tcb->group); @@ -138,7 +131,7 @@ int group_addrenv(FAR struct tcb_s *tcb) /* Are we going to change address environments? */ - flags = irqsave(); + flags = enter_critical_section(); if (gid != g_gid_current) { /* Yes.. Is there a current address environment in place? */ @@ -174,11 +167,11 @@ int group_addrenv(FAR struct tcb_s *tcb) } /* Save the new, current group */ - + g_gid_current = gid; } - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/sched/group/group_childstatus.c b/sched/group/group_childstatus.c index d67aad6067cb4adc5244c84a4269ca02c6d6c49c..00e78b4322dffb7187a55cacbbe997c030dd267d 100644 --- a/sched/group/group_childstatus.c +++ b/sched/group/group_childstatus.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_childstatus.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -48,9 +48,9 @@ #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* Note that there cannot be more that CONFIG_MAX_TASKS tasks in total. * However, the number of child status structures may need to be significantly * larger because this number includes the maximum number of tasks that are @@ -70,9 +70,9 @@ # undef CONFIG_DEBUG_CHILDSTATUS #endif -/***************************************************************************** +/**************************************************************************** * Private Types - *****************************************************************************/ + ****************************************************************************/ /* Globals are maintained in a structure to minimize name collisions. */ struct child_pool_s @@ -81,17 +81,17 @@ struct child_pool_s FAR struct child_status_s *freelist; }; -/***************************************************************************** +/**************************************************************************** * Private Data - *****************************************************************************/ + ****************************************************************************/ static struct child_pool_s g_child_pool; -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_dumpchildren * * Description: @@ -106,7 +106,7 @@ static struct child_pool_s g_child_pool; * Assumptions: * Called early in initialization. No special precautions are required. * - *****************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_DEBUG_CHILDSTATUS static void group_dumpchildren(FAR struct task_group_s *group, @@ -126,11 +126,11 @@ static void group_dumpchildren(FAR struct task_group_s *group, # define group_dumpchildren(t,m) #endif -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: task_initialize * * Description: @@ -146,7 +146,7 @@ static void group_dumpchildren(FAR struct task_group_s *group, * Assumptions: * Called early in initialization. No special precautions are required. * - *****************************************************************************/ + ****************************************************************************/ void task_initialize(void) { @@ -166,7 +166,7 @@ void task_initialize(void) } } -/***************************************************************************** +/**************************************************************************** * Name: group_allocchild * * Description: @@ -184,7 +184,7 @@ void task_initialize(void) * Called during task creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ FAR struct child_status_s *group_allocchild(void) { @@ -202,7 +202,7 @@ FAR struct child_status_s *group_allocchild(void) return ret; } -/***************************************************************************** +/**************************************************************************** * Name: group_freechild * * Description: @@ -218,7 +218,7 @@ FAR struct child_status_s *group_allocchild(void) * Called during task creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ void group_freechild(FAR struct child_status_s *child) { @@ -231,7 +231,7 @@ void group_freechild(FAR struct child_status_s *child) } } -/***************************************************************************** +/**************************************************************************** * Name: group_addchild * * Description: @@ -248,7 +248,7 @@ void group_freechild(FAR struct child_status_s *child) * Called during task creation processing in a safe context. No special * precautions are required here. * - *****************************************************************************/ + ****************************************************************************/ void group_addchild(FAR struct task_group_s *group, FAR struct child_status_s *child) @@ -261,7 +261,7 @@ void group_addchild(FAR struct task_group_s *group, group_dumpchildren(group, "group_addchild"); } -/***************************************************************************** +/**************************************************************************** * Name: group_findchild * * Description: @@ -281,7 +281,7 @@ void group_addchild(FAR struct task_group_s *group, * Called during SIGCHLD processing in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ FAR struct child_status_s *group_findchild(FAR struct task_group_s *group, pid_t pid) @@ -303,7 +303,7 @@ FAR struct child_status_s *group_findchild(FAR struct task_group_s *group, return NULL; } -/***************************************************************************** +/**************************************************************************** * Name: group_exitchild * * Description: @@ -320,7 +320,7 @@ FAR struct child_status_s *group_findchild(FAR struct task_group_s *group, * Called during SIGCHLD processing in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ FAR struct child_status_s *group_exitchild(FAR struct task_group_s *group) { @@ -339,7 +339,7 @@ FAR struct child_status_s *group_exitchild(FAR struct task_group_s *group) return NULL; } -/***************************************************************************** +/**************************************************************************** * Name: group_removechild * * Description: @@ -359,7 +359,7 @@ FAR struct child_status_s *group_exitchild(FAR struct task_group_s *group) * Called during SIGCHLD processing in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ FAR struct child_status_s *group_removechild(FAR struct task_group_s *group, pid_t pid) @@ -403,7 +403,7 @@ FAR struct child_status_s *group_removechild(FAR struct task_group_s *group, return curr; } -/***************************************************************************** +/**************************************************************************** * Name: group_removechildren * * Description: @@ -419,7 +419,7 @@ FAR struct child_status_s *group_removechild(FAR struct task_group_s *group, * Called during task exit processing in a safe context. No special * precautions are required here. * - *****************************************************************************/ + ****************************************************************************/ void group_removechildren(FAR struct task_group_s *group) { diff --git a/sched/group/group_create.c b/sched/group/group_create.c index 7d84e3e2068c92423581c234ed7c9ca46f3d1285..3b3cb6be08e41d924f8d2c77c20ba159e35d0799 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_create.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -44,6 +44,7 @@ #include #include +#include #include #include "environ/environ.h" @@ -51,29 +52,25 @@ #ifdef HAVE_TASK_GROUP -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* Is this worth making a configuration option? */ #define GROUP_INITIAL_MEMBERS 4 -/***************************************************************************** - * Private Types - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Private Data - *****************************************************************************/ + ****************************************************************************/ /* This is counter that is used to generate unique task group IDs */ #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) static gid_t g_gidcounter; #endif -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) /* This is the head of a list of all group members */ @@ -81,11 +78,11 @@ static gid_t g_gidcounter; FAR struct task_group_s *g_grouphead; #endif -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_assigngid * * Description: @@ -101,7 +98,7 @@ FAR struct task_group_s *g_grouphead; * Called during task creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) static void group_assigngid(FAR struct task_group_s *group) @@ -115,11 +112,11 @@ static void group_assigngid(FAR struct task_group_s *group) /* Loop until we create a unique ID */ - for (;;) + for (; ; ) { /* Increment the ID counter. This is global data so be extra paranoid. */ - flags = irqsave(); + flags = enter_critical_section(); gid = ++g_gidcounter; /* Check for overflow */ @@ -127,13 +124,13 @@ static void group_assigngid(FAR struct task_group_s *group) if (gid <= 0) { g_gidcounter = 1; - irqrestore(flags); + leave_critical_section(flags); } else { /* Does a task group with this ID already exist? */ - irqrestore(flags); + leave_critical_section(flags); if (group_findbygid(gid) == NULL) { /* Now assign this ID to the group and return */ @@ -147,11 +144,11 @@ static void group_assigngid(FAR struct task_group_s *group) } #endif /* HAVE_GROUP_MEMBERS */ -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_allocate * * Description: @@ -174,7 +171,7 @@ static void group_assigngid(FAR struct task_group_s *group) * Called during task creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) { @@ -253,7 +250,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) return OK; } -/***************************************************************************** +/**************************************************************************** * Name: group_initialize * * Description: @@ -272,7 +269,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) * Called during task creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ int group_initialize(FAR struct task_tcb_s *tcb) { @@ -309,10 +306,10 @@ int group_initialize(FAR struct task_tcb_s *tcb) #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) /* Add the initialized entry to the list of groups */ - flags = irqsave(); + flags = enter_critical_section(); group->flink = g_grouphead; g_grouphead = group; - irqrestore(flags); + leave_critical_section(flags); #endif diff --git a/sched/group/group_find.c b/sched/group/group_find.c index c0c70bbc75cf6968424af71daee3b859da8e6034..3db582fa25157337aa1fc76cb9063275d491f390 100644 --- a/sched/group/group_find.c +++ b/sched/group/group_find.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_find.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -44,6 +44,7 @@ #include #include +#include #include #include "group/group.h" @@ -51,31 +52,11 @@ #ifdef HAVE_TASK_GROUP -/***************************************************************************** - * Pre-processor Definitions - *****************************************************************************/ - -/***************************************************************************** - * Private Types - *****************************************************************************/ - -/***************************************************************************** - * Private Data - *****************************************************************************/ - -/***************************************************************************** - * Public Data - *****************************************************************************/ - -/***************************************************************************** - * Private Functions - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_findbygid * * Description: @@ -97,7 +78,7 @@ * precautions should be required here. However, extra care is taken when * accessing the global g_grouphead list. * - *****************************************************************************/ + ****************************************************************************/ #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) FAR struct task_group_s *group_findbygid(gid_t gid) @@ -107,22 +88,22 @@ FAR struct task_group_s *group_findbygid(gid_t gid) /* Find the status structure with the matching GID */ - flags = irqsave(); + flags = enter_critical_section(); for (group = g_grouphead; group; group = group->flink) { if (group->tg_gid == gid) { - irqrestore(flags); + leave_critical_section(flags); return group; } } - irqrestore(flags); + leave_critical_section(flags); return NULL; } #endif -/***************************************************************************** +/**************************************************************************** * Name: group_findbypid * * Description: @@ -143,7 +124,7 @@ FAR struct task_group_s *group_findbygid(gid_t gid) * precautions should be required here. However, extra care is taken when * accessing the global g_grouphead list. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS FAR struct task_group_s *group_findbypid(pid_t pid) @@ -153,17 +134,17 @@ FAR struct task_group_s *group_findbypid(pid_t pid) /* Find the status structure with the matching PID */ - flags = irqsave(); + flags = enter_critical_section(); for (group = g_grouphead; group; group = group->flink) { if (group->tg_task == pid) { - irqrestore(flags); + leave_critical_section(flags); return group; } } - irqrestore(flags); + leave_critical_section(flags); return NULL; } #endif diff --git a/sched/group/group_foreachchild.c b/sched/group/group_foreachchild.c index deaeea2cdec39dea9c89ba04038407f05ace0677..10fed5f90a5bb0d7209b34fc6e955ce59df4e6fc 100644 --- a/sched/group/group_foreachchild.c +++ b/sched/group/group_foreachchild.c @@ -45,10 +45,6 @@ #ifdef HAVE_GROUP_MEMBERS -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -83,11 +79,11 @@ int group_foreachchild(FAR struct task_group_s *group, for (i = 0; i < group->tg_nmembers; i++) { - ret = handler(group->tg_members[i], arg); - if (ret != 0) - { - return ret; - } + ret = handler(group->tg_members[i], arg); + if (ret != 0) + { + return ret; + } } return 0; diff --git a/sched/group/group_free.c b/sched/group/group_free.c index ce0cc9cad7258f6cdd3746bc1e8e61cd8a56eff6..3692b4495f525e8f6198ae6c80663bc82465ba09 100644 --- a/sched/group/group_free.c +++ b/sched/group/group_free.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/group/group_free.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,38 +50,18 @@ #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: group_free * * Description: * Free memory appropriate previously allocated via group_malloc() using * the appropriate memory manager. * - ************************************************************************/ + ****************************************************************************/ void group_free(FAR struct task_group_s *group, FAR void *mem) { @@ -89,7 +69,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem) if (!group) { - FAR struct tcb_s *tcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); DEBUGASSERT(tcb && tcb->group); group = tcb->group; } @@ -100,7 +80,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem) { /* It is a privileged group... use the kernel mode memory allocator */ - return kmm_free(mem); + kmm_free(mem); } else { @@ -108,7 +88,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem) * allocator. */ - return kumm_free(mem); + kumm_free(mem); } } diff --git a/sched/group/group_join.c b/sched/group/group_join.c index 662db69bc827e16247560bb1606281111caed94b..bdf2fc546d0e7ec9c45da343b65d216a48c2b3c4 100644 --- a/sched/group/group_join.c +++ b/sched/group/group_join.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_join.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -44,6 +44,7 @@ #include #include +#include #include #include "sched/sched.h" @@ -52,26 +53,18 @@ #if defined(HAVE_TASK_GROUP) && !defined(CONFIG_DISABLE_PTHREAD) -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ /* Is this worth making a configuration option? */ #define GROUP_REALLOC_MEMBERS 4 -/***************************************************************************** - * Private Types - *****************************************************************************/ - -/***************************************************************************** - * Private Data - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_addmember * * Description: @@ -88,7 +81,7 @@ * Called during thread creation and during reparenting in a safe context. * No special precautions are required here. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS static inline int group_addmember(FAR struct task_group_s *group, pid_t pid) @@ -126,10 +119,10 @@ static inline int group_addmember(FAR struct task_group_s *group, pid_t pid) * may be traversed from an interrupt handler (read-only). */ - flags = irqsave(); + flags = enter_critical_section(); group->tg_members = newmembers; group->tg_mxmembers = newmax; - irqrestore(flags); + leave_critical_section(flags); } /* Assign this new pid to the group; group->tg_nmembers will be incremented @@ -141,11 +134,11 @@ static inline int group_addmember(FAR struct task_group_s *group, pid_t pid) } #endif /* HAVE_GROUP_MEMBERS */ -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_bind * * Description: @@ -168,11 +161,11 @@ static inline int group_addmember(FAR struct task_group_s *group, pid_t pid) * - Called during thread creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ int group_bind(FAR struct pthread_tcb_s *tcb) { - FAR struct tcb_s *ptcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *ptcb = this_task(); DEBUGASSERT(ptcb && tcb && ptcb->group && !tcb->cmn.group); @@ -182,7 +175,7 @@ int group_bind(FAR struct pthread_tcb_s *tcb) return OK; } -/***************************************************************************** +/**************************************************************************** * Name: group_join * * Description: @@ -205,7 +198,7 @@ int group_bind(FAR struct pthread_tcb_s *tcb) * - Called during thread creation in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ int group_join(FAR struct pthread_tcb_s *tcb) { diff --git a/sched/group/group_killchildren.c b/sched/group/group_killchildren.c index a320d50bc57b7c0d0f70d5916e01ba5ce2ce356a..9ec7465f9871eb0488ec9edcdf2767a453f71cd0 100644 --- a/sched/group/group_killchildren.c +++ b/sched/group/group_killchildren.c @@ -43,13 +43,13 @@ #include "group/group.h" -#if HAVE_GROUP_MEMBERS +#ifdef HAVE_GROUP_MEMBERS /**************************************************************************** * Private Functions ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_killchildren_handler * * Description: @@ -62,7 +62,7 @@ * Return Value: * 0 (OK) on success; a negated errno value on failure. * - *****************************************************************************/ + ****************************************************************************/ static int group_killchildren_handler(pid_t pid, FAR void *arg) { @@ -77,7 +77,7 @@ static int group_killchildren_handler(pid_t pid, FAR void *arg) ret = pthread_cancel(pid); } - return ret; + return ret; } /**************************************************************************** diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 7fadb31fc4b1e4a363f6c38c31f1bd317cb40a9e..9c5cf0f50b0552ac1b8530d859496e35544c9821 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_leave.c * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -56,23 +57,11 @@ #ifdef HAVE_TASK_GROUP -/***************************************************************************** - * Pre-processor Definitions - *****************************************************************************/ - -/***************************************************************************** - * Private Types - *****************************************************************************/ - -/***************************************************************************** - * Private Data - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_remove * * Description: @@ -88,7 +77,7 @@ * Called during task deletion in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV) static void group_remove(FAR struct task_group_s *group) @@ -101,7 +90,7 @@ static void group_remove(FAR struct task_group_s *group) * This is probably un-necessary. */ - flags = irqsave(); + flags = enter_critical_section(); /* Find the task group structure */ @@ -127,11 +116,11 @@ static void group_remove(FAR struct task_group_s *group) curr->flink = NULL; } - irqrestore(flags); + leave_critical_section(flags); } #endif -/***************************************************************************** +/**************************************************************************** * Name: group_release * * Description: @@ -147,7 +136,7 @@ static void group_remove(FAR struct task_group_s *group) * Called during task deletion in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ static inline void group_release(FAR struct task_group_s *group) { @@ -271,12 +260,26 @@ static inline void group_release(FAR struct task_group_s *group) # endif #endif - /* Release the group container itself */ +#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT) + /* If there are threads waiting for this group to be freed, then we cannot + * yet free the memory resources. Instead just mark the group deleted + * and wait for those threads complete their waits. + */ - sched_kfree(group); + if (group->tg_nwaiters > 0) + { + group->tg_flags |= GROUP_FLAG_DELETED; + } + else +#endif + { + /* Release the group container itself */ + + sched_kfree(group); + } } -/***************************************************************************** +/**************************************************************************** * Name: group_removemember * * Description: @@ -295,7 +298,7 @@ static inline void group_release(FAR struct task_group_s *group) * Called during task deletion and also from the reparenting logic, both * in a safe context. No special precautions are required here. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS static inline void group_removemember(FAR struct task_group_s *group, pid_t pid) @@ -312,26 +315,26 @@ static inline void group_removemember(FAR struct task_group_s *group, pid_t pid) /* Does this member have the matching pid */ if (group->tg_members[i] == pid) - { + { /* Remove the member from the array of members. This must be an * atomic operation because the member array may be accessed from * interrupt handlers (read-only). */ - flags = irqsave(); + flags = enter_critical_section(); group->tg_members[i] = group->tg_members[group->tg_nmembers - 1]; group->tg_nmembers--; - irqrestore(flags); + leave_critical_section(flags); } } } #endif /* HAVE_GROUP_MEMBERS */ -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_leave * * Description: @@ -350,7 +353,7 @@ static inline void group_removemember(FAR struct task_group_s *group, pid_t pid) * Called during task deletion in a safe context. No special precautions * are required here. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS void group_leave(FAR struct tcb_s *tcb) diff --git a/sched/group/group_malloc.c b/sched/group/group_malloc.c index 89c0eccfdea15b02adf62f4f84de0e5e2d3de382..c8fe8104c4cd2930281cdd0fb217c81f2d0bd9a8 100644 --- a/sched/group/group_malloc.c +++ b/sched/group/group_malloc.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/group/group_malloc.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,31 +50,11 @@ #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: group_malloc * * Description: @@ -84,7 +64,7 @@ * group and must be allocated so that it accessible by unprivileged * code. * - ************************************************************************/ + ****************************************************************************/ FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes) { @@ -92,7 +72,7 @@ FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes) if (!group) { - FAR struct tcb_s *tcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); DEBUGASSERT(tcb && tcb->group); group = tcb->group; } diff --git a/sched/group/group_setupidlefiles.c b/sched/group/group_setupidlefiles.c index a18af782abd2e44701c00e0f86b456da184ee531..c5ed320f5e3fc571f4ffc146421f72dca81b5329 100644 --- a/sched/group/group_setupidlefiles.c +++ b/sched/group/group_setupidlefiles.c @@ -53,10 +53,6 @@ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/group/group_setupstreams.c b/sched/group/group_setupstreams.c index 72fc12dd6e35503433e395eed38f5536e3acae5c..02df7b7b53eb05b35abdc46f9a5af8d07675efd6 100644 --- a/sched/group/group_setupstreams.c +++ b/sched/group/group_setupstreams.c @@ -55,10 +55,6 @@ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 #if CONFIG_NFILE_STREAMS > 0 -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -68,7 +64,7 @@ * * Description: * Setup streams data structures that may be used for standard C buffered - * I/O with underlying socket or file desciptors + * I/O with underlying socket or file descriptors * ****************************************************************************/ @@ -88,9 +84,9 @@ int group_setupstreams(FAR struct task_tcb_s *tcb) * fd = 2 is stderr (write-only, append) */ - (void)fs_fdopen(0, O_RDONLY, (FAR struct tcb_s *)tcb); - (void)fs_fdopen(1, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb); - (void)fs_fdopen(2, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb); + (void)fs_fdopen(0, O_RDONLY, (FAR struct tcb_s *)tcb); + (void)fs_fdopen(1, O_WROK | O_CREAT, (FAR struct tcb_s *)tcb); + (void)fs_fdopen(2, O_WROK | O_CREAT, (FAR struct tcb_s *)tcb); return OK; } diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c index a1db88023f71c08b895e7697ace5a557a33f0a6d..e1068712507d2ff90c89d531b8850ca901fae16c 100644 --- a/sched/group/group_setuptaskfiles.c +++ b/sched/group/group_setuptaskfiles.c @@ -89,7 +89,7 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb) { /* The parent task is the one at the head of the ready-to-run list */ - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct file *parent; FAR struct file *child; int i; @@ -102,7 +102,7 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb) * accordingly above. */ - /* Get pointers to the parent and child task file lists */ + /* Get pointers to the parent and child task file lists */ parent = rtcb->group->tg_filelist.fl_files; child = tcb->cmn.group->tg_filelist.fl_files; @@ -147,7 +147,7 @@ static inline void sched_dupsockets(FAR struct task_tcb_s *tcb) { /* The parent task is the one at the head of the ready-to-run list */ - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct socket *parent; FAR struct socket *child; int i; diff --git a/sched/group/group_signal.c b/sched/group/group_signal.c index 4569fdb9c7038db85e00d2a15524685055e64162..1f681928d9060dbbfbc7893cd77d6af0ed903719 100644 --- a/sched/group/group_signal.c +++ b/sched/group/group_signal.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/group/group_signal.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -51,13 +51,9 @@ #if defined(HAVE_TASK_GROUP) && !defined(CONFIG_DISABLE_SIGNALS) -/***************************************************************************** - * Pre-processor Definitions - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Private Types - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS struct group_signal_s @@ -70,15 +66,11 @@ struct group_signal_s }; #endif -/***************************************************************************** - * Private Data - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_signal_handler * * Description: @@ -91,7 +83,7 @@ struct group_signal_s * Return Value: * 0 (OK) on success; a negated errno value on failure. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS static int group_signal_handler(pid_t pid, FAR void *arg) @@ -101,12 +93,12 @@ static int group_signal_handler(pid_t pid, FAR void *arg) FAR sigactq_t *sigact; int ret; - DEBUGASSERT(info); + DEBUGASSERT(tcb != NULL && tcb->group != NULL && info != NULL); /* Get the TCB associated with the group member */ tcb = sched_gettcb(pid); - DEBUGASSERT(tcb); + DEBUGASSERT(tcb ! = NULL); if (tcb) { /* Set this one as the default if we have not already set the default. */ @@ -159,9 +151,9 @@ static int group_signal_handler(pid_t pid, FAR void *arg) info->utcb = tcb; } - /* Is there also an action associated with the task? */ + /* Is there also a action associated with the task group? */ - sigact = sig_findaction(tcb, info->siginfo->si_signo); + sigact = sig_findaction(tcb->group, info->siginfo->si_signo); if (sigact) { /* Yes.. then use this thread. The requirement is this: @@ -191,11 +183,11 @@ static int group_signal_handler(pid_t pid, FAR void *arg) } #endif -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: group_signal * * Description: @@ -213,7 +205,7 @@ static int group_signal_handler(pid_t pid, FAR void *arg) * this function may be called indirectly in the context of an interrupt * handler. * - *****************************************************************************/ + ****************************************************************************/ int group_signal(FAR struct task_group_s *group, FAR siginfo_t *siginfo) { diff --git a/sched/group/group_waiter.c b/sched/group/group_waiter.c new file mode 100644 index 0000000000000000000000000000000000000000..9baa5cd65b2531f4df30cdc12714b41f98de05f1 --- /dev/null +++ b/sched/group/group_waiter.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * sched/group/group_waiter.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nuttx/sched.h" +#include "group/group.h" + +#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: group_addwaiter + * + * Description: + * Increment the number of instances of waitpid that are waiting for this + * group to exit. + * + * Assumptions: + * Caller has assured mutually exclusive access to the group. + * + ****************************************************************************/ + +void group_addwaiter(FAR struct task_group_s *group) +{ + group->tg_nwaiters++; + DEBUGASSERT(group->tg_nwaiters > 0); +} + +/**************************************************************************** + * Name: group_addwaiter + * + * Description: + * Decrement the number of instances of waitpid that are waiting for this + * group to exit. If the count goes to zero and deletion is pending, the + * call group_free to release the dangling resources. + * + * Assumptions: + * Caller has assured mutually exclusive access to the group. + * + ****************************************************************************/ + +void group_delwaiter(FAR struct task_group_s *group) +{ + DEBUGASSERT(group->tg_nwaiters > 0); + group->tg_nwaiters--; + if (group->tg_nwaiters == 0 && (group->tg_flags & GROUP_FLAG_DELETED) != 0) + { + /* Release the group container (all other resources have already been + * freed). + */ + + sched_kfree(group); + } +} + +#endif /* CONFIG_SCHED_WAITPID && !CONFIG_SCHED_HAVE_PARENT */ diff --git a/sched/group/group_zalloc.c b/sched/group/group_zalloc.c index 2fcea0d5ed2bcc731be69f1055e3eb591569c6dc..eb7794eaceb6ff9ce98c88305b7c7a529800aa27 100644 --- a/sched/group/group_zalloc.c +++ b/sched/group/group_zalloc.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/group/group_zalloc.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,31 +46,11 @@ #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: group_malloc * * Description: @@ -79,7 +59,7 @@ * that it is only accessed by privileged code; Otherwise, it must be * allocated so that it accessible by unprivileged code. * - ************************************************************************/ + ****************************************************************************/ FAR void *group_zalloc(FAR struct task_group_s *group, size_t nbytes) { diff --git a/sched/init/Make.defs b/sched/init/Make.defs index eae5e2fa877ab5546bcaa639f61ad46ccd0bc9ce..46c0718c8ed75e6370cf9c14284dfc658ff48348 100644 --- a/sched/init/Make.defs +++ b/sched/init/Make.defs @@ -35,6 +35,10 @@ CSRCS += os_start.c os_bringup.c +ifeq ($(CONFIG_SMP),y) +CSRCS += os_smpstart.c +endif + # Include init build support DEPPATH += --dep-path init diff --git a/sched/init/init.h b/sched/init/init.h index d3f3ae913208f07516e34416bba5097a8371bbfe..4724c83392f37335e1184574f7c9dd11b4ea558b 100644 --- a/sched/init/init.h +++ b/sched/init/init.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/init/init.h * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,21 +42,10 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ + /**************************************************************************** * Name: os_start * @@ -75,6 +64,65 @@ void os_start(void); +/**************************************************************************** + * Name: os_smp_start + * + * Description: + * In an SMP configution, only one CPU is initially active (CPU 0). System + * initialization occurs on that single thread. At the completion of the + * initialization of the OS, just before beginning normal multitasking, + * the additional CPUs would be started by calling this function. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero on success; a negater errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int os_smp_start(void); +#endif + +/**************************************************************************** + * Name: os_idle_trampoline + * + * Description: + * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). + * It is equivalent to the CPU 0 IDLE logic in os_start.c + * + * Input Parameters: + * Standard task arguments. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +void os_idle_trampoline(void); +#endif + +/**************************************************************************** + * Name: os_idle_task + * + * Description: + * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). + * It is equivalent to the CPU 0 IDLE logic in os_start.c + * + * Input Parameters: + * Standard task arguments. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +int os_idle_task(int argc, FAR char *argv[]); +#endif + /**************************************************************************** * Name: os_bringup * diff --git a/sched/init/os_bringup.c b/sched/init/os_bringup.c index 405b93d0a92b13e51071e1aecbc8ff0a9718b3df..1652a36b7fdb1a8e267fb349280a9189f448c173 100644 --- a/sched/init/os_bringup.c +++ b/sched/init/os_bringup.c @@ -124,22 +124,6 @@ # undef CONFIG_LIB_USRWORK #endif -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/sched/init/os_smpstart.c b/sched/init/os_smpstart.c new file mode 100644 index 0000000000000000000000000000000000000000..f613344b5f13d62434cee67d313fbb2c48fb5ebd --- /dev/null +++ b/sched/init/os_smpstart.c @@ -0,0 +1,240 @@ +/**************************************************************************** + * sched/init/os_smpstart.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "group/group.h" +#include "sched/sched.h" +#include "init/init.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct os_tcballoc_s +{ + struct task_tcb_s tcb; /* IDLE task TCB */ + FAR char *idleargv[2]; /* Argument list */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if CONFIG_TASK_NAME_SIZE < 1 +static const char g_idlename[] = "CPUn Idle" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: os_idle_trampoline + * + * Description: + * This is the common start-up logic for the IDLE task for CPUs 1 through + * (CONFIG_SMP_NCPUS-1). Having a start-up function such as this for the + * IDLE is not really an architectural necessity. It is used only for + * symmetry with now other threads are started (see task_start() and + * pthread_start()). + * + * Input Parameters: + * None. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +void os_idle_trampoline(void) +{ +#ifdef CONFIG_SCHED_INSTRUMENTATION + FAR struct tcb_s *tcb = this_task(); +#endif + + /* Perform architecture-specific initialization for this CPU */ + + up_cpu_initialize(); + +#ifdef CONFIG_SCHED_INSTRUMENTATION + /* Announce that the IDLE task has started */ + + sched_note_start(tcb); +#endif + + /* Then transfer control to the IDLE task */ + + (void)os_idle_task(0, NULL); + + /* The IDLE task should never return */ + + PANIC(); +} + +/**************************************************************************** + * Name: os_idle_task + * + * Description: + * This is the common IDLE task for CPUs 1 through (CONFIG_SMP_NCPUS-1). + * It is equivalent to the CPU 0 IDLE logic in os_start.c + * + * Input Parameters: + * Standard task arguments. + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +int os_idle_task(int argc, FAR char *argv[]) +{ + /* Enter the IDLE loop */ + + sdbg("CPU%d: Beginning Idle Loop\n", this_cpu()); + + for (; ; ) + { + /* Perform garbage collection (if it is not being done by the worker + * thread). This cleans-up memory de-allocations that were queued + * because they could not be freed in that execution context (for + * example, if the memory was freed from an interrupt handler). + */ + +#ifndef CONFIG_SCHED_WORKQUEUE + /* We must have exclusive access to the memory manager to do this + * BUT the idle task cannot wait on a semaphore. So we only do + * the cleanup now if we can get the semaphore -- this should be + * possible because if the IDLE thread is running, no other task is! + * + * WARNING: This logic could have undesirable side-effects if priority + * inheritance is enabled. Imaginee the possible issues if the + * priority of the IDLE thread were to get boosted! Moral: If you + * use priority inheritance, then you should also enable the work + * queue so that is done in a safer context. + */ + + if (sched_have_garbage() && kmm_trysemaphore() == 0) + { + sched_garbage_collection(); + kmm_givesemaphore(); + } +#endif + + /* Perform any processor-specific idle state operations */ + + up_idle(); + } +} + +/**************************************************************************** + * Name: os_smp_start + * + * Description: + * In an SMP configution, only one CPU is initially active (CPU 0). System + * initialization occurs on that single thread. At the completion of the + * initialization of the OS, just before beginning normal multitasking, + * the additional CPUs would be started by calling this function. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero on success; a negater errno value on failure. + * + * Assumption: + * Runs before the full initialization sequence has completed. Runs after + * all OS facilities are set up, but before multi-tasking has been started. + * + ****************************************************************************/ + +int os_smp_start(void) +{ + int ret; + int cpu; + + /* Create a stack for all CPU IDLE threads (except CPU0 which already has + * a stack). + */ + + for (cpu = 1; cpu < CONFIG_SMP_NCPUS; cpu++) + { + FAR struct tcb_s *tcb = current_task(cpu); + DEBUGASSERT(tcb != NULL); + + ret = up_create_stack(tcb, CONFIG_SMP_IDLETHREAD_STACKSIZE, + TCB_FLAG_TTYPE_KERNEL); + if (ret < 0) + { + sdbg("ERROR: Failed to allocate stack for CPU%d\n", cpu); + return ret; + } + } + + /* Then start all of the other CPUs after we have completed the memory + * allocations. CPU0 is already running. + */ + + for (cpu = 1; cpu < CONFIG_SMP_NCPUS; cpu++) + { + /* Start the CPU */ + + ret = up_cpu_start(cpu); + if (ret < 0) + { + sdbg("ERROR: Failed to start CPU%d: %d\n", cpu, ret); + return ret; + } + } + + return OK; +} + +#endif /* CONFIG_SMP */ diff --git a/sched/init/os_start.c b/sched/init/os_start.c index 511e5870c7aa08cfb1124b2e2fd2d47ee8ffa7a1..a8456c008a1a9e467483d541f1d20bc34a045bb4 100644 --- a/sched/init/os_start.c +++ b/sched/init/os_start.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/init/os_start.c * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,19 +39,21 @@ #include #include +#include #include #include #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include "sched/sched.h" @@ -76,12 +78,14 @@ * Pre-processor Definitions ****************************************************************************/ -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ +#ifdef CONFIG_SMP +/* This set of all CPUs */ + +# define SCHED_ALL_CPUS ((1 << CONFIG_SMP_NCPUS) - 1) +#endif /* CONFIG_SMP */ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /* Task Lists ***************************************************************/ @@ -89,17 +93,53 @@ * and by a series of task lists. All of these tasks lists are declared * below. Although it is not always necessary, most of these lists are * prioritized so that common list handling logic can be used (only the - * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists need - * to be prioritized). + * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists + * need to be prioritized). */ -/* This is the list of all tasks that are ready to run. The head of this - * list is the currently active task; the tail of this list is always the - * IDLE task. +/* This is the list of all tasks that are ready to run. This is a + * prioritized list with head of the list holding the highest priority + * (unassigned) task. In the non-SMP cae, the head of this list is the + * currently active task and the tail of this list, the lowest priority + * task, is always the IDLE task. */ volatile dq_queue_t g_readytorun; +#ifdef CONFIG_SMP +/* In order to support SMP, the function of the g_readytorun list changes, + * The g_readytorun is still used but in the SMP cae it will contain only: + * + * - Only tasks/threads that are eligible to run, but not currently running, + * and + * - Tasks/threads that have not been assigned to a CPU. + * + * Otherwise, the TCB will be reatined in an assigned task list, + * g_assignedtasks. As its name suggests, on 'g_assignedtasks queue for CPU + * 'n' would contain only tasks/threads that are assigned to CPU 'n'. Tasks/ + * threads would be assigned a particular CPU by one of two mechanisms: + * + * - (Semi-)permanently through an RTOS interfaces such as + * pthread_attr_setaffinity(), or + * - Temporarily through scheduling logic when a previously unassigned task + * is made to run. + * + * Tasks/threads that are assigned to a CPU via an interface like + * pthread_attr_setaffinity() would never go into the g_readytorun list, but + * would only go into the g_assignedtasks[n] list for the CPU 'n' to which + * the thread has been assigned. Hence, the g_readytorun list would hold + * only unassigned tasks/threads. + * + * Like the g_readytorun list in in non-SMP case, each g_assignedtask[] list + * is prioritized: The head of the list is the currently active task on this + * CPU. Tasks after the active task are ready-to-run and assigned to this + * CPU. The tail of this assigned task list, the lowest priority task, is + * always the CPU's IDLE task. + */ + +volatile dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS]; +#endif + /* This is the list of all tasks that are ready-to-run, but cannot be placed * in the g_readytorun list because: (1) They are higher priority than the * currently active task at the head of the g_readytorun list, and (2) the @@ -152,21 +192,31 @@ volatile dq_queue_t g_inactivetasks; * while it is within an interrupt handler. */ -volatile sq_queue_t g_delayed_kufree; - #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) volatile sq_queue_t g_delayed_kfree; #endif +#ifndef CONFIG_BUILD_KERNEL +/* REVISIT: It is not safe to defer user allocation in the kernel mode + * build. Why? Because the correct user context will not be in place + * when these deferred de-allocations are performed. In order to make this + * work, we would need to do something like: (1) move g_delayed_kufree + * into the group structure, then traverse the groups to collect garbage + * on a group-by-group basis. + */ + +volatile sq_queue_t g_delayed_kufree; +#endif + /* This is the value of the last process ID assigned to a task */ volatile pid_t g_lastpid; /* The following hash table is used for two things: * - * 1. This hash table greatly speeds the determination of - * a new unique process ID for a task, and + * 1. This hash table greatly speeds the determination of a new unique + * process ID for a task, and * 2. Is used to quickly map a process ID into a TCB. * It has the side effects of using more memory and limiting * @@ -175,58 +225,123 @@ volatile pid_t g_lastpid; struct pidhash_s g_pidhash[CONFIG_MAX_TASKS]; -/* This is a table of task lists. This table is indexed by - * the task state enumeration type (tstate_t) and provides - * a pointer to the associated static task list (if there - * is one) as well as a boolean indication as to if the list - * is an ordered list or not. +/* This is a table of task lists. This table is indexed by the task stat + * enumeration type (tstate_t) and provides a pointer to the associated + * static task list (if there is one) as well as a a set of attribute flags + * indicating properities of the list, for example, if the list is an + * ordered list or not. */ const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] = { - { NULL, false }, /* TSTATE_TASK_INVALID */ - { &g_pendingtasks, true }, /* TSTATE_TASK_PENDING */ - { &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */ - { &g_readytorun, true }, /* TSTATE_TASK_RUNNING */ - { &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */ - { &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */ + { /* TSTATE_TASK_INVALID */ + NULL, + 0 + }, + { /* TSTATE_TASK_PENDING */ + &g_pendingtasks, + TLIST_ATTR_PRIORITIZED + }, +#ifdef CONFIG_SMP + { /* TSTATE_TASK_READYTORUN */ + &g_readytorun, + TLIST_ATTR_PRIORITIZED + }, + { /* TSTATE_TASK_ASSIGNED */ + g_assignedtasks, + TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE + }, + { /* TSTATE_TASK_RUNNING */ + g_assignedtasks, + TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED | TLIST_ATTR_RUNNABLE + }, +#else + { /* TSTATE_TASK_READYTORUN */ + &g_readytorun, + TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE + }, + { /* TSTATE_TASK_RUNNING */ + &g_readytorun, + TLIST_ATTR_PRIORITIZED | TLIST_ATTR_RUNNABLE + }, +#endif + { /* TSTATE_TASK_INACTIVE */ + &g_inactivetasks, + 0 + }, + { /* TSTATE_WAIT_SEM */ + &g_waitingforsemaphore, + TLIST_ATTR_PRIORITIZED + } #ifndef CONFIG_DISABLE_SIGNALS , - { &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */ + { /* TSTATE_WAIT_SIG */ + &g_waitingforsignal, + 0 + } #endif #ifndef CONFIG_DISABLE_MQUEUE , - { &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */ - { &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */ + { /* TSTATE_WAIT_MQNOTEMPTY */ + &g_waitingformqnotempty, + TLIST_ATTR_PRIORITIZED + }, + { /* TSTATE_WAIT_MQNOTFULL */ + &g_waitingformqnotfull, + TLIST_ATTR_PRIORITIZED + } #endif #ifdef CONFIG_PAGING , - { &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */ + { /* TSTATE_WAIT_PAGEFILL */ + &g_waitingforfill, + TLIST_ATTR_PRIORITIZED + } #endif }; +/* This is the current initialization state. The level of initialization + * is only important early in the start-up sequence when certain OS or + * hardware resources may not yet be available to the kernel logic. + */ + +uint8_t g_os_initstate; /* See enum os_initstate_e */ + /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ -/* This is the task control block for this thread of execution. This thread - * of execution is the IDLE task. NOTE: the system boots into the IDLE - * task. The IDLE task spawns the user initialization task and that user - * initialization task is responsible for bringing up the rest of the system. +/* This is an arry of task control block (TCB) for the IDLE thread of each + * CPU. For the non-SMP case, this is a a single TCB; For the SMP case, + * there is one TCB per CPU. NOTE: The system boots on CPU0 into the IDLE + * task. The IDLE task later starts the other CPUs and spawns the user + * initialization task. That user initialization task is responsible for + * bringing up the rest of the system. */ -static FAR struct task_tcb_s g_idletcb; +#ifdef CONFIG_SMP +static struct task_tcb_s g_idletcb[CONFIG_SMP_NCPUS]; +#else +static struct task_tcb_s g_idletcb[1]; +#endif /* This is the name of the idle task */ -static FAR const char g_idlename[] = "Idle Task"; - -/* This the IDLE idle threads argument list. */ +#ifdef CONFIG_SMP +static const char g_idlename[] = "CPU Idle"; +#else +static const char g_idlename[] = "Idle Task"; +#endif -static FAR char *g_idleargv[2]; +/* This the IDLE idle threads argument list. NOTE: Normally the argument + * list is created on the stack prior to starting the task. We have to + * do things s little differently here for the IDLE tasks. + */ -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ +#ifdef CONFIG_SMP +static FAR char *g_idleargv[CONFIG_SMP_NCPUS][2]; +#else +static FAR char *g_idleargv[1][2]; +#endif /**************************************************************************** * Public Functions @@ -250,10 +365,19 @@ static FAR char *g_idleargv[2]; void os_start(void) { +#ifdef CONFIG_SMP + int cpu; +#else +# define cpu 0 +#endif int i; slldbg("Entry\n"); + /* Boot up is complete */ + + g_os_initstate = OSINIT_BOOT; + /* Initialize RTOS Data ***************************************************/ /* Initialize all task lists */ @@ -271,11 +395,20 @@ void os_start(void) dq_init(&g_waitingforfill); #endif dq_init(&g_inactivetasks); - sq_init(&g_delayed_kufree); #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) sq_init(&g_delayed_kfree); #endif +#ifndef CONFIG_BUILD_KERNEL + sq_init(&g_delayed_kufree); +#endif + +#ifdef CONFIG_SMP + for (i = 0; i < CONFIG_SMP_NCPUS; i++) + { + dq_init(&g_assignedtasks[i]); + } +#endif /* Initialize the logic that determine unique process IDs. */ @@ -286,54 +419,116 @@ void os_start(void) g_pidhash[i].pid = INVALID_PROCESS_ID; } - /* Assign the process ID of ZERO to the idle task */ + /* Initialize the IDLE task TCB *******************************************/ + +#ifdef CONFIG_SMP + for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++, g_lastpid++) +#endif + { + FAR dq_queue_t *tasklist; + int hashndx; + + /* Assign the process ID(s) of ZERO to the idle task(s) */ - g_pidhash[PIDHASH(0)].tcb = &g_idletcb.cmn; - g_pidhash[PIDHASH(0)].pid = 0; + hashndx = PIDHASH(g_lastpid); + g_pidhash[hashndx].tcb = &g_idletcb[cpu].cmn; + g_pidhash[hashndx].pid = g_lastpid; - /* Initialize the IDLE task TCB *******************************************/ - /* Initialize a TCB for this thread of execution. NOTE: The default - * value for most components of the g_idletcb are zero. The entire - * structure is set to zero. Then only the (potentially) non-zero - * elements are initialized. NOTE: The idle task is the only task in - * that has pid == 0 and sched_priority == 0. - */ + /* Initialize a TCB for this thread of execution. NOTE: The default + * value for most components of the g_idletcb are zero. The entire + * structure is set to zero. Then only the (potentially) non-zero + * elements are initialized. NOTE: The idle task is the only task in + * that has pid == 0 and sched_priority == 0. + */ - bzero((void*)&g_idletcb, sizeof(struct task_tcb_s)); - g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING; - g_idletcb.cmn.entry.main = (main_t)os_start; - g_idletcb.cmn.flags = TCB_FLAG_TTYPE_KERNEL; + bzero((void *)&g_idletcb[cpu], sizeof(struct task_tcb_s)); + g_idletcb[cpu].cmn.pid = g_lastpid; + g_idletcb[cpu].cmn.task_state = TSTATE_TASK_RUNNING; - /* Set the IDLE task name */ + /* Set the entry point. This is only for debug purposes. NOTE: that + * the start_t entry point is not saved. That is acceptable, however, + * becaue it can be used only for restarting a task: The IDLE task + * cannot be restarted. + */ + +#ifdef CONFIG_SMP + if (cpu > 0) + { + g_idletcb[cpu].cmn.start = os_idle_trampoline; + g_idletcb[cpu].cmn.entry.main = os_idle_task; + } + else +#endif + { + g_idletcb[cpu].cmn.start = (start_t)os_start; + g_idletcb[cpu].cmn.entry.main = (main_t)os_start; + } + + /* Set the task flags to indicate that this is a kernel thread and, if + * configured for SMP, that this task is locked to this CPU. + */ + +#ifdef CONFIG_SMP + g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED); + g_idletcb[cpu].cmn.cpu = cpu; +#else + g_idletcb[cpu].cmn.flags = TCB_FLAG_TTYPE_KERNEL; +#endif + +#ifdef CONFIG_SMP + /* Set the affinity mask to allow the thread to run on all CPUs. No, + * this IDLE thread can only run on its assigned CPU. That is + * enforced by the TCB_FLAG_CPU_LOCKED which overrides the affinity + * mask. This is essential because all tasks inherit the affinity + * mask from their parent and, ultimately, the parent of all tasks is + * the IDLE task. + */ + + g_idletcb[cpu].cmn.affinity = SCHED_ALL_CPUS; +#endif #if CONFIG_TASK_NAME_SIZE > 0 - strncpy(g_idletcb.cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE); - g_idletcb.cmn.name[CONFIG_TASK_NAME_SIZE] = '\0'; -#endif /* CONFIG_TASK_NAME_SIZE */ + /* Set the IDLE task name */ - /* Configure the task name in the argument list. The IDLE task does - * not really have an argument list, but this name is still useful - * for things like the NSH PS command. - * - * In the kernel mode build, the arguments are saved on the task's stack - * and there is no support that yet. - */ +# ifdef CONFIG_SMP + snprintf(g_idletcb[cpu].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", cpu); +# else + strncpy(g_idletcb[cpu].cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE); + g_idletcb[cpu].cmn.name[CONFIG_TASK_NAME_SIZE] = '\0'; +# endif +#endif + + /* Configure the task name in the argument list. The IDLE task does + * not really have an argument list, but this name is still useful + * for things like the NSH PS command. + * + * In the kernel mode build, the arguments are saved on the task's + * stack and there is no support that yet. + */ #if CONFIG_TASK_NAME_SIZE > 0 - g_idleargv[0] = g_idletcb.cmn.name; + g_idleargv[cpu][0] = g_idletcb[cpu].cmn.name; #else - g_idleargv[0] = (FAR char *)g_idlename; + g_idleargv[cpu][0] = (FAR char *)g_idlename; #endif /* CONFIG_TASK_NAME_SIZE */ - g_idleargv[1] = NULL; - g_idletcb.argv = g_idleargv; + g_idleargv[cpu][1] = NULL; + g_idletcb[cpu].argv = &g_idleargv[cpu][0]; - /* Then add the idle task's TCB to the head of the ready to run list */ + /* Then add the idle task's TCB to the head of the corrent ready to + * run list. + */ - dq_addfirst((FAR dq_entry_t*)&g_idletcb, (FAR dq_queue_t*)&g_readytorun); +#ifdef CONFIG_SMP + tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING, cpu); +#else + tasklist = TLIST_HEAD(TSTATE_TASK_RUNNING); +#endif + dq_addfirst((FAR dq_entry_t *)&g_idletcb[cpu], tasklist); - /* Initialize the processor-specific portion of the TCB */ + /* Initialize the processor-specific portion of the TCB */ - up_initial_state(&g_idletcb.cmn); + up_initial_state(&g_idletcb[cpu].cmn); + } /* Initialize RTOS facilities *********************************************/ /* Initialize the semaphore facility. This has to be done very early @@ -379,6 +574,10 @@ void os_start(void) } #endif + /* The memory manager is available */ + + g_os_initstate = OSINIT_MEMORY; + #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) /* Initialize tasking data structures */ @@ -485,6 +684,10 @@ void os_start(void) up_initialize(); + /* Hardware resources are available */ + + g_os_initstate = OSINIT_HARDWARE; + #ifdef CONFIG_NET /* Complete initialization the networking system now that interrupts * and timers have been configured by up_initialize(). @@ -506,39 +709,92 @@ void os_start(void) lib_initialize(); /* IDLE Group Initialization **********************************************/ + /* Announce that the CPU0 IDLE task has started */ + + sched_note_start(&g_idletcb[0].cmn); + +#ifdef CONFIG_SMP + /* Initialize the IDLE group for the IDLE task of each CPU */ + + for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++) +#endif + { #ifdef HAVE_TASK_GROUP - /* Allocate the IDLE group */ + /* Allocate the IDLE group */ - DEBUGVERIFY(group_allocate(&g_idletcb, g_idletcb.cmn.flags)); + DEBUGVERIFY(group_allocate(&g_idletcb[cpu], g_idletcb[cpu].cmn.flags)); #endif #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 - /* Create stdout, stderr, stdin on the IDLE task. These will be - * inherited by all of the threads created by the IDLE task. - */ +#ifdef CONFIG_SMP + if (cpu > 0) + { + /* Clone stdout, stderr, stdin from the CPU0 IDLE task. */ + + DEBUGVERIFY(group_setuptaskfiles(&g_idletcb[cpu])); + } + else +#endif + { + /* Create stdout, stderr, stdin on the CPU0 IDLE task. These + * will be inherited by all of the threads created by the CPU0 + * IDLE task. + */ - DEBUGVERIFY(group_setupidlefiles(&g_idletcb)); + DEBUGVERIFY(group_setupidlefiles(&g_idletcb[cpu])); + } #endif #ifdef HAVE_TASK_GROUP - /* Complete initialization of the IDLE group. Suppress retention - * of child status in the IDLE group. - */ + /* Complete initialization of the IDLE group. Suppress retention + * of child status in the IDLE group. + */ - DEBUGVERIFY(group_initialize(&g_idletcb)); - g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; + DEBUGVERIFY(group_initialize(&g_idletcb[cpu])); + g_idletcb[cpu].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; #endif +} + +#ifdef CONFIG_SMP + /* Start all CPUs *********************************************************/ + + /* A few basic sanity checks */ + + DEBUGASSERT(this_cpu() == 0 && CONFIG_MAX_TASKS > CONFIG_SMP_NCPUS); + + /* Take the memory manager semaphore on this CPU so that it will not be + * available on the other CPUs until we have finished initialization. + */ + + DEBUGVERIFY(kmm_trysemaphore()); + + /* Then start the other CPUs */ + + DEBUGVERIFY(os_smp_start()); + +#endif /* CONFIG_SMP */ /* Bring Up the System ****************************************************/ + /* The OS is fully initialized and we are beginning multi-tasking */ + + g_os_initstate = OSINIT_OSREADY; + /* Create initial tasks and bring-up the system */ DEBUGVERIFY(os_bringup()); +#ifdef CONFIG_SMP + /* Let other threads have access to the memory manager */ + + kmm_givesemaphore(); + +#endif /* CONFIG_SMP */ + /* The IDLE Loop **********************************************************/ /* When control is return to this point, the system is idle. */ - sdbg("Beginning Idle Loop\n"); - for (;;) + sdbg("CPU0: Beginning Idle Loop\n"); + for (; ; ) { /* Perform garbage collection (if it is not being done by the worker * thread). This cleans-up memory de-allocations that were queued @@ -559,9 +815,9 @@ void os_start(void) * queue so that is done in a safer context. */ - if (kmm_trysemaphore() == 0) + if (sched_have_garbage() && kmm_trysemaphore() == 0) { - sched_garbagecollection(); + sched_garbage_collection(); kmm_givesemaphore(); } #endif diff --git a/sched/irq/Make.defs b/sched/irq/Make.defs index 706569f66b622f003966fca3d815b6a8367c2792..905720750ebedca510ea6411697ab0c9f6293af0 100644 --- a/sched/irq/Make.defs +++ b/sched/irq/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # sched/irq/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -35,6 +35,10 @@ CSRCS += irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c +ifeq ($(CONFIG_SMP),y) +CSRCS += irq_csection.c +endif + # Include irq build support DEPPATH += --dep-path irq diff --git a/sched/irq/irq.h b/sched/irq/irq.h index 25bda551e586b04bf6274791b2a6205d61b58845..544be675d2820d3a78b6dea436f5a7154a424b14 100644 --- a/sched/irq/irq.h +++ b/sched/irq/irq.h @@ -41,24 +41,37 @@ ****************************************************************************/ #include +#include + +#include #include #include -#include +#include /**************************************************************************** - * Pre-processor Definitions + * Public Data ****************************************************************************/ -/**************************************************************************** - * Public Type Declarations - ****************************************************************************/ +/* This is the list of interrupt handlers, one for each IRQ. This is used + * by irq_dispatch to transfer control to interrupt handlers after the + * occurrence of an interrupt. + */ extern FAR xcpt_t g_irqvector[NR_IRQS+1]; -/**************************************************************************** - * Public Variables - ****************************************************************************/ +#ifdef CONFIG_SMP +/* This is the spinlock that enforces critical sections when interrupts are + * disabled. + */ + +extern volatile spinlock_t g_cpu_irqlock; + +/* Used to keep track of which CPU(s) hold the IRQ lock. */ + +extern volatile spinlock_t g_cpu_irqsetlock; +extern volatile cpu_set_t g_cpu_irqset; +#endif /**************************************************************************** * Public Function Prototypes @@ -72,7 +85,25 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Name: irq_initialize + * + * Description: + * Configure the IRQ subsystem + * + ****************************************************************************/ + void weak_function irq_initialize(void); + +/**************************************************************************** + * Name: irq_unexpected_isr + * + * Description: + * An interrupt has been received for an IRQ that was never registered + * with the system. + * + ****************************************************************************/ + int irq_unexpected_isr(int irq, FAR void *context); #undef EXTERN @@ -81,4 +112,3 @@ int irq_unexpected_isr(int irq, FAR void *context); #endif #endif /* __SCHED_IRQ_IRQ_H */ - diff --git a/sched/irq/irq_attach.c b/sched/irq/irq_attach.c index 8e7d2d275e4306e93be15d3b2c4ef068b48209f5..d111eeb5c7874026afce141f8412fb9c797be896 100644 --- a/sched/irq/irq_attach.c +++ b/sched/irq/irq_attach.c @@ -52,11 +52,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -83,14 +83,14 @@ int irq_attach(int irq, xcpt_t isr) if ((unsigned)irq < NR_IRQS) { - irqstate_t state; + irqstate_t flags; /* If the new ISR is NULL, then the ISR is being detached. * In this case, disable the ISR and direct any interrupts * to the unexpected interrupt handler. */ - state = irqsave(); + flags = enter_critical_section(); if (isr == NULL) { /* Disable the interrupt if we can before detaching it. We might @@ -116,7 +116,7 @@ int irq_attach(int irq, xcpt_t isr) /* Save the new ISR in the table. */ g_irqvector[irq] = isr; - irqrestore(state); + leave_critical_section(flags); ret = OK; } diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c new file mode 100644 index 0000000000000000000000000000000000000000..414238045e2dce10f1f4862ae81c56438e9ed6da --- /dev/null +++ b/sched/irq/irq_csection.c @@ -0,0 +1,215 @@ +/**************************************************************************** + * sched/irq/irq_csection.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include "sched/sched.h" +#include "irq/irq.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* This is the spinlock that enforces critical sections when interrupts are + * disabled. + */ + +volatile spinlock_t g_cpu_irqlock = SP_UNLOCKED; + +/* Used to keep track of which CPU(s) hold the IRQ lock. */ + +volatile spinlock_t g_cpu_irqsetlock; +volatile cpu_set_t g_cpu_irqset; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: enter_critical_section + * + * Description: + * Take the CPU IRQ lock and disable interrupts on all CPUs. A thread- + * specific counter is increment to indicate that the thread has IRQs + * disabled and to support nested calls to enter_critical_section(). + * + ****************************************************************************/ + +irqstate_t enter_critical_section(void) +{ + FAR struct tcb_s *rtcb; + + /* Do nothing if called from an interrupt handler */ + + if (up_interrupt_context()) + { + /* The value returned does not matter. We assume only that it is a + * scalar here. + */ + + return (irqstate_t)0; + } + + /* Do we already have interrupts disabled? */ + + rtcb = this_task(); + if (rtcb->irqcount > 0) + { + /* Yes... make sure that the spinlock is set and increment the IRQ + * lock count. + */ + + DEBUGASSERT(g_cpu_irqlock == SP_LOCKED && rtcb->irqcount < INT16_MAX); + rtcb->irqcount++; + } + else + { + /* NO.. Take the spinlock to get exclusive access and set the lock + * count to 1. + * + * We must avoid that case where a context occurs between taking the + * g_cpu_irqlock and disabling interrupts. Also interrupts disables + * must follow a stacked order. We cannot other context switches to + * re-order the enabling/disabling of interrupts. + * + * The scheduler accomplishes this by treating the irqcount like + * lockcount: Both will disable pre-emption. + */ + + spin_setbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, + &g_cpu_irqlock); + rtcb->irqcount = 1; + +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION + /* Note that we have entered the critical section */ + + sched_note_csection(rtcb, true); +#endif + } + + /* Then disable interrupts (they may already be disabled, be we need to + * return valid interrupt status in any event). + */ + + return up_irq_save(); +} + +/**************************************************************************** + * Name: leave_critical_section + * + * Description: + * Decrement the IRQ lock count and if it decrements to zero then release + * the spinlock. + * + ****************************************************************************/ + +void leave_critical_section(irqstate_t flags) +{ + /* Do nothing if called from an interrupt handler */ + + if (!up_interrupt_context()) + { + FAR struct tcb_s *rtcb = this_task(); + + DEBUGASSERT(rtcb->irqcount > 0); + + /* Will we still have interrupts disabled after decrementing the + * count? + */ + + if (rtcb->irqcount > 1) + { + /* Yes... make sure that the spinlock is set */ + + DEBUGASSERT(g_cpu_irqlock == SP_LOCKED); + rtcb->irqcount--; + } + else + { +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION + /* No.. Note that we have entered the critical section */ + + sched_note_csection(rtcb, false); +#endif + /* Decrement our count on the lock. If all CPUs have released, + * then unlock the spinlock. + */ + + rtcb->irqcount = 0; + spin_clrbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, + &g_cpu_irqlock); + + /* Have all CPUs release the lock? */ + + if (!spin_islocked(&g_cpu_irqlock)) + { + /* Check if there are pending tasks and that pre-emption is + * also enabled. + */ + + if (g_pendingtasks.head != NULL && !spin_islocked(&g_cpu_schedlock)) + { + /* Release any ready-to-run tasks that have collected in + * g_pendingtasks if the scheduler is not locked. + * + * NOTE: This operation has a very high likelihood of causing + * this task to be switched out! + */ + + up_release_pending(); + } + } + } + + /* Restore the previous interrupt state which may still be interrupts + * disabled (but we don't have a mechanism to verify that now) + */ + + up_irq_restore(flags); + } +} + +#endif /* CONFIG_SMP */ diff --git a/sched/irq/irq_dispatch.c b/sched/irq/irq_dispatch.c index 1da5d49c1ae2722acdcb5a3e5bebd19aaff0668a..4d18ac34fdbb233d72f921579b12e89e03626bca 100644 --- a/sched/irq/irq_dispatch.c +++ b/sched/irq/irq_dispatch.c @@ -54,11 +54,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -77,7 +77,7 @@ * order to dispatch an interrupt to the appropriate, registered handling * logic. * - ***************************************************************************/ + ****************************************************************************/ void irq_dispatch(int irq, FAR void *context) { diff --git a/sched/irq/irq_initialize.c b/sched/irq/irq_initialize.c index f9e97e933da3e5f39b0b7126ce962336909947f2..d558ff97e1874e6bb4b28fff01bd9461e2aa125d 100644 --- a/sched/irq/irq_initialize.c +++ b/sched/irq/irq_initialize.c @@ -44,27 +44,11 @@ #include "irq/irq.h" /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ FAR xcpt_t g_irqvector[NR_IRQS+1]; -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -88,4 +72,3 @@ void irq_initialize(void) g_irqvector[i] = irq_unexpected_isr; } } - diff --git a/sched/irq/irq_unexpectedisr.c b/sched/irq/irq_unexpectedisr.c index d4eacbee1df9eaaeb237f2de7698e027e8b968b2..191d0a21940c27fde966c770dd182086ed3cab1a 100644 --- a/sched/irq/irq_unexpectedisr.c +++ b/sched/irq/irq_unexpectedisr.c @@ -45,26 +45,6 @@ #include "irq/irq.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,7 +60,7 @@ int irq_unexpected_isr(int irq, FAR void *context) { - (void)irqsave(); + (void)up_irq_save(); lldbg("irq: %d\n", irq); PANIC(); return OK; /* Won't get here */ diff --git a/sched/module/Make.defs b/sched/module/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..00f8467560636fd54489180ba523621f4da63e2c --- /dev/null +++ b/sched/module/Make.defs @@ -0,0 +1,62 @@ +############################################################################ +# sched/module/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_MODULE),y) + +# OS module interfaces + +CSRCS += mod_insmod.c mod_rmmod.c + +# loadable module library + +CSRCS += mod_bind.c mod_init.c mod_iobuffer.c mod_load.c mod_read.c +CSRCS += mod_registry.c mod_sections.c mod_symbols.c mod_symtab.c +CSRCS += mod_uninit.c mod_unload.c mod_verify.c + +# procfs support + +ifeq ($(CONFIG_FS_PROCFS),y) +ifneq ($(CONFIG_FS_PROCFS_EXCLUDE_MODULE),y) +CSRCS += mod_procfs.c +endif +endif + +# Hook the module subdirectory into the build + +VPATH += module +SUBDIRS += module +DEPPATH += --dep-path module + +endif diff --git a/sched/module/gnu-elf.ld b/sched/module/gnu-elf.ld new file mode 100644 index 0000000000000000000000000000000000000000..0bf39b9649227d0aef3bf3f693995a548ddf220e --- /dev/null +++ b/sched/module/gnu-elf.ld @@ -0,0 +1,97 @@ +/**************************************************************************** + * sched/module/gnu-elf.ld + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +SECTIONS +{ + .text 0x00000000 : + { + _stext = . ; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.glue_7) + *(.glue_7t) + *(.jcr) + _etext = . ; + } + + .rodata : + { + _srodata = . ; + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + _erodata = . ; + } + + .data : + { + _sdata = . ; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + _edata = . ; + } + + .bss : + { + _sbss = . ; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + _ebss = . ; + } + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/sched/module/mod_bind.c b/sched/module/mod_bind.c new file mode 100644 index 0000000000000000000000000000000000000000..75d8e1b56a4a7f26e7debf72dd9720e8bc45a950 --- /dev/null +++ b/sched/module/mod_bind.c @@ -0,0 +1,299 @@ +/**************************************************************************** + * sched/module/mod_bind.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_readrel + * + * Description: + * Read the ELF32_Rel structure into memory. + * + ****************************************************************************/ + +static inline int mod_readrel(FAR struct mod_loadinfo_s *loadinfo, + FAR const Elf32_Shdr *relsec, + int index, FAR Elf32_Rel *rel) +{ + off_t offset; + + /* Verify that the symbol table index lies within symbol table */ + + if (index < 0 || index > (relsec->sh_size / sizeof(Elf32_Rel))) + { + sdbg("Bad relocation symbol index: %d\n", index); + return -EINVAL; + } + + /* Get the file offset to the symbol table entry */ + + offset = relsec->sh_offset + sizeof(Elf32_Rel) * index; + + /* And, finally, read the symbol table entry into memory */ + + return mod_read(loadinfo, (FAR uint8_t *)rel, sizeof(Elf32_Rel), offset); +} + +/**************************************************************************** + * Name: mod_relocate and mod_relocateadd + * + * Description: + * Perform all relocations associated with a section. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static int mod_relocate(FAR struct mod_loadinfo_s *loadinfo, int relidx) + +{ + FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx]; + FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; + Elf32_Rel rel; + Elf32_Sym sym; + FAR Elf32_Sym *psym; + uintptr_t addr; + int symidx; + int ret; + int i; + + /* Examine each relocation in the section. 'relsec' is the section + * containing the relations. 'dstsec' is the section containing the data + * to be relocated. + */ + + for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++) + { + psym = &sym; + + /* Read the relocation entry into memory */ + + ret = mod_readrel(loadinfo, relsec, i, &rel); + if (ret < 0) + { + sdbg("Section %d reloc %d: Failed to read relocation entry: %d\n", + relidx, i, ret); + return ret; + } + + /* Get the symbol table index for the relocation. This is contained + * in a bit-field within the r_info element. + */ + + symidx = ELF32_R_SYM(rel.r_info); + + /* Read the symbol table entry into memory */ + + ret = mod_readsym(loadinfo, symidx, &sym); + if (ret < 0) + { + sdbg("Section %d reloc %d: Failed to read symbol[%d]: %d\n", + relidx, i, symidx, ret); + return ret; + } + + /* Get the value of the symbol (in sym.st_value) */ + + ret = mod_symvalue(loadinfo, &sym); + if (ret < 0) + { + /* The special error -ESRCH is returned only in one condition: The + * symbol has no name. + * + * There are a few relocations for a few architectures that do + * no depend upon a named symbol. We don't know if that is the + * case here, but we will use a NULL symbol pointer to indicate + * that case to up_relocate(). That function can then do what + * is best. + */ + + if (ret == -ESRCH) + { + sdbg("Section %d reloc %d: Undefined symbol[%d] has no name: %d\n", + relidx, i, symidx, ret); + psym = NULL; + } + else + { + sdbg("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n", + relidx, i, symidx, ret); + return ret; + } + } + + /* Calculate the relocation address. */ + + if (rel.r_offset < 0 || rel.r_offset > dstsec->sh_size - sizeof(uint32_t)) + { + sdbg("Section %d reloc %d: Relocation address out of range, offset %d size %d\n", + relidx, i, rel.r_offset, dstsec->sh_size); + return -EINVAL; + } + + addr = dstsec->sh_addr + rel.r_offset; + + /* Now perform the architecture-specific relocation */ + + ret = up_relocate(&rel, psym, addr); + if (ret < 0) + { + sdbg("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret); + return ret; + } + } + + return OK; +} + +static int mod_relocateadd(FAR struct mod_loadinfo_s *loadinfo, int relidx) +{ + sdbg("Not implemented\n"); + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_bind + * + * Description: + * Bind the imported symbol names in the loaded module described by + * 'loadinfo' using the exported symbol values provided by mod_setsymtab(). + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_bind(FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + int i; + + /* Find the symbol and string tables */ + + ret = mod_findsymtab(loadinfo); + if (ret < 0) + { + return ret; + } + + /* Allocate an I/O buffer. This buffer is used by mod_symname() to + * accumulate the variable length symbol name. + */ + + ret = mod_allocbuffer(loadinfo); + if (ret < 0) + { + sdbg("mod_allocbuffer failed: %d\n", ret); + return -ENOMEM; + } + + /* Process relocations in every allocated section */ + + for (i = 1; i < loadinfo->ehdr.e_shnum; i++) + { + /* Get the index to the relocation section */ + + int infosec = loadinfo->shdr[i].sh_info; + if (infosec >= loadinfo->ehdr.e_shnum) + { + continue; + } + + /* Make sure that the section is allocated. We can't relocated + * sections that were not loaded into memory. + */ + + if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0) + { + continue; + } + + /* Process the relocations by type */ + + if (loadinfo->shdr[i].sh_type == SHT_REL) + { + ret = mod_relocate(loadinfo, i); + } + else if (loadinfo->shdr[i].sh_type == SHT_RELA) + { + ret = mod_relocateadd(loadinfo, i); + } + + if (ret < 0) + { + break; + } + } + +#if defined(CONFIG_ARCH_HAVE_COHERENT_DCACHE) + /* Ensure that the I and D caches are coherent before starting the newly + * loaded module by cleaning the D cache (i.e., flushing the D cache + * contents to memory and invalidating the I cache). + */ + + up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize); + up_coherent_dcache(loadinfo->datastart, loadinfo->datasize); + +#endif + + return ret; +} diff --git a/sched/module/mod_init.c b/sched/module/mod_init.c new file mode 100644 index 0000000000000000000000000000000000000000..c16069caf52f10a8b5b7a50888674c6fe86c01a1 --- /dev/null +++ b/sched/module/mod_init.c @@ -0,0 +1,204 @@ +/**************************************************************************** + * sched/module/mod_init.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "module.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_MODULE_DUMPBUFFER have to + * be defined or CONFIG_MODULE_DUMPBUFFER does nothing. + */ + +#if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_MODULE_DUMPBUFFER) +# undef CONFIG_MODULE_DUMPBUFFER +#endif + +#ifdef CONFIG_MODULE_DUMPBUFFER +# define mod_dumpbuffer(m,b,n) svdbgdumpbuffer(m,b,n) +#else +# define mod_dumpbuffer(m,b,n) +#endif + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_filelen + * + * Description: + * Get the size of the ELF file + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static inline int mod_filelen(FAR struct mod_loadinfo_s *loadinfo, + FAR const char *filename) +{ + struct stat buf; + int ret; + + /* Get the file stats */ + + ret = stat(filename, &buf); + if (ret < 0) + { + int errval = errno; + sdbg("Failed to stat file: %d\n", errval); + return -errval; + } + + /* Verify that it is a regular file */ + + if (!S_ISREG(buf.st_mode)) + { + sdbg("Not a regular file. mode: %d\n", buf.st_mode); + return -ENOENT; + } + + /* TODO: Verify that the file is readable. Not really important because + * we will detect this when we try to open the file read-only. + */ + + /* Return the size of the file in the loadinfo structure */ + + loadinfo->filelen = buf.st_size; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_initialize + * + * Description: + * This function is called to configure the library to process an ELF + * program binary. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_initialize(FAR const char *filename, + FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + + svdbg("filename: %s loadinfo: %p\n", filename, loadinfo); + + /* Clear the load info structure */ + + memset(loadinfo, 0, sizeof(struct mod_loadinfo_s)); + + /* Get the length of the file. */ + + ret = mod_filelen(loadinfo, filename); + if (ret < 0) + { + sdbg("mod_filelen failed: %d\n", ret); + return ret; + } + + /* Open the binary file for reading (only) */ + + loadinfo->filfd = open(filename, O_RDONLY); + if (loadinfo->filfd < 0) + { + int errval = errno; + sdbg("Failed to open ELF binary %s: %d\n", filename, errval); + return -errval; + } + + /* Read the ELF ehdr from offset 0 */ + + ret = mod_read(loadinfo, (FAR uint8_t *)&loadinfo->ehdr, + sizeof(Elf32_Ehdr), 0); + if (ret < 0) + { + sdbg("Failed to read ELF header: %d\n", ret); + return ret; + } + + mod_dumpbuffer("ELF header", (FAR const uint8_t *)&loadinfo->ehdr, + sizeof(Elf32_Ehdr)); + + /* Verify the ELF header */ + + ret = mod_verifyheader(&loadinfo->ehdr); + if (ret < 0) + { + /* This may not be an error because we will be called to attempt loading + * EVERY binary. If mod_verifyheader() does not recognize the ELF header, + * it will -ENOEXEC whcih simply informs the system that the file is not an + * ELF file. mod_verifyheader() will return other errors if the ELF header + * is not correctly formed. + */ + + sdbg("Bad ELF header: %d\n", ret); + return ret; + } + + return OK; +} diff --git a/sched/module/mod_insmod.c b/sched/module/mod_insmod.c new file mode 100644 index 0000000000000000000000000000000000000000..9242c5419efbad38eef2ace7d14f067c9490ac60 --- /dev/null +++ b/sched/module/mod_insmod.c @@ -0,0 +1,296 @@ +/**************************************************************************** + * sched/module/mod_insmod.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "module/module.h" + +#ifdef CONFIG_MODULE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE, and CONFIG_DEBUG_BINFMT have to be + * defined or CONFIG_MODULE_DUMPBUFFER does nothing. + */ + +#if !defined(CONFIG_DEBUG_VERBOSE) || !defined (CONFIG_DEBUG_BINFMT) +# undef CONFIG_MODULE_DUMPBUFFER +#endif + +#ifdef CONFIG_MODULE_DUMPBUFFER +# define mod_dumpbuffer(m,b,n) svdbgdumpbuffer(m,b,n) +#else +# define mod_dumpbuffer(m,b,n) +#endif + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_dumploadinfo + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT) +static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) +{ + int i; + + sdbg("LOAD_INFO:\n"); + sdbg(" textalloc: %08lx\n", (long)loadinfo->textalloc); + sdbg(" datastart: %08lx\n", (long)loadinfo->datastart); + sdbg(" textsize: %ld\n", (long)loadinfo->textsize); + sdbg(" datasize: %ld\n", (long)loadinfo->datasize); + sdbg(" filelen: %ld\n", (long)loadinfo->filelen); + sdbg(" filfd: %d\n", loadinfo->filfd); + sdbg(" symtabidx: %d\n", loadinfo->symtabidx); + sdbg(" strtabidx: %d\n", loadinfo->strtabidx); + + sdbg("ELF Header:\n"); + sdbg(" e_ident: %02x %02x %02x %02x\n", + loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1], + loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]); + sdbg(" e_type: %04x\n", loadinfo->ehdr.e_type); + sdbg(" e_machine: %04x\n", loadinfo->ehdr.e_machine); + sdbg(" e_version: %08x\n", loadinfo->ehdr.e_version); + sdbg(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry); + sdbg(" e_phoff: %d\n", loadinfo->ehdr.e_phoff); + sdbg(" e_shoff: %d\n", loadinfo->ehdr.e_shoff); + sdbg(" e_flags: %08x\n" , loadinfo->ehdr.e_flags); + sdbg(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize); + sdbg(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize); + sdbg(" e_phnum: %d\n", loadinfo->ehdr.e_phnum); + sdbg(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize); + sdbg(" e_shnum: %d\n", loadinfo->ehdr.e_shnum); + sdbg(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx); + + if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0) + { + for (i = 0; i < loadinfo->ehdr.e_shnum; i++) + { + FAR Elf32_Shdr *shdr = &loadinfo->shdr[i]; + sdbg("Sections %d:\n", i); + sdbg(" sh_name: %08x\n", shdr->sh_name); + sdbg(" sh_type: %08x\n", shdr->sh_type); + sdbg(" sh_flags: %08x\n", shdr->sh_flags); + sdbg(" sh_addr: %08x\n", shdr->sh_addr); + sdbg(" sh_offset: %d\n", shdr->sh_offset); + sdbg(" sh_size: %d\n", shdr->sh_size); + sdbg(" sh_link: %d\n", shdr->sh_link); + sdbg(" sh_info: %d\n", shdr->sh_info); + sdbg(" sh_addralign: %d\n", shdr->sh_addralign); + sdbg(" sh_entsize: %d\n", shdr->sh_entsize); + } + } +} +#else +# define mod_dumploadinfo(i) +#endif + +/**************************************************************************** + * Name: mod_dumpinitializer + ****************************************************************************/ + +#ifdef CONFIG_MODULE_DUMPBUFFER +static void mod_dumpinitializer(mod_initializer_t initializer, + FAR struct mod_loadinfo_s *loadinfo) +{ + mod_dumpbuffer("Initializer code", (FAR const uint8_t *)initializer, + MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); +} +#else +# define mod_dumpinitializer(b,l) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: insmod + * + * Description: + * Verify that the file is an ELF module binary and, if so, load the + * module into kernel memory and initialize it for use. + * + * NOTE: mod_setsymtab had to have been called in board-specific OS logic + * prior to calling this function from application logic (perhaps via + * boardctl(BOARDIOC_OS_SYMTAB). Otherwise, insmod will be unable to + * resolve symbols in the OS module. + * + * Input Parameters: + * + * filename - Full path to the module binary to be loaded + * modulename - The name that can be used to refer to the module after + * it has been loaded. + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int insmod(FAR const char *filename, FAR const char *modulename) +{ + struct mod_loadinfo_s loadinfo; + FAR struct module_s *modp; + mod_initializer_t initializer; + int ret; + + DEBUGASSERT(filename != NULL && modulename != NULL); + svdbg("Loading file: %s\n", filename); + + /* Get exclusive access to the module registry */ + + mod_registry_lock(); + + /* Check if this module is already installed */ + + if (mod_registry_find(modulename) != NULL) + { + mod_registry_unlock(); + ret = -EEXIST; + goto errout_with_lock; + } + + /* Initialize the ELF library to load the program binary. */ + + ret = mod_initialize(filename, &loadinfo); + mod_dumploadinfo(&loadinfo); + if (ret != 0) + { + sdbg("ERROR: Failed to initialize to load module: %d\n", ret); + goto errout_with_lock; + } + + /* Allocate a module registry entry to hold the module data */ + + modp = (FAR struct module_s *)kmm_zalloc(sizeof(struct module_s)); + if (ret != 0) + { + sdbg("Failed to initialize for load of ELF program: %d\n", ret); + goto errout_with_loadinfo; + } + + /* Save the module name in the registry entry */ + + strncpy(modp->modulename, modulename, MODULENAME_MAX); + + /* Load the program binary */ + + ret = mod_load(&loadinfo); + mod_dumploadinfo(&loadinfo); + if (ret != 0) + { + sdbg("Failed to load ELF program binary: %d\n", ret); + goto errout_with_registry_entry; + } + + /* Bind the program to the kernel symbol table */ + + ret = mod_bind(&loadinfo); + if (ret != 0) + { + sdbg("Failed to bind symbols program binary: %d\n", ret); + goto errout_with_load; + } + + /* Return the load information */ + + modp->alloc = (FAR void *)loadinfo.textalloc; +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + modp->textsize = loadinfo.textsize; + modp->datasize = loadinfo.datasize; +#endif + + /* Get the module initializer entry point */ + + initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry); +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + modp->initializer = initializer; +#endif + mod_dumpinitializer(initializer, &loadinfo); + + /* Call the module initializer */ + + ret = initializer(&modp->uninitializer, &modp->arg); + if (ret < 0) + { + sdbg("Failed to initialize the module: %d\n", ret); + goto errout_with_load; + } + + /* Add the new module entry to the registry */ + + mod_registry_add(modp); + + mod_uninitialize(&loadinfo); + mod_registry_unlock(); + return OK; + +errout_with_load: + mod_unload(&loadinfo); +errout_with_registry_entry: + kmm_free(modp); +errout_with_loadinfo: + mod_uninitialize(&loadinfo); +errout_with_lock: + mod_registry_unlock(); + set_errno(-ret); + return ERROR; +} + +#endif /* CONFIG_MODULE */ diff --git a/sched/module/mod_iobuffer.c b/sched/module/mod_iobuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..0a8c4bc4ef5d0d5cf3c153c8263cb68b1ad1398e --- /dev/null +++ b/sched/module/mod_iobuffer.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * sched/module/mod_iobuffer.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_allocbuffer + * + * Description: + * Perform the initial allocation of the I/O buffer, if it has not already + * been allocated. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_allocbuffer(FAR struct mod_loadinfo_s *loadinfo) +{ + /* Has a buffer been allocated> */ + + if (!loadinfo->iobuffer) + { + /* No.. allocate one now */ + + loadinfo->iobuffer = (FAR uint8_t *)kmm_malloc(CONFIG_MODULE_BUFFERSIZE); + if (!loadinfo->iobuffer) + { + sdbg("Failed to allocate an I/O buffer\n"); + return -ENOMEM; + } + + loadinfo->buflen = CONFIG_MODULE_BUFFERSIZE; + } + + return OK; +} + +/**************************************************************************** + * Name: mod_reallocbuffer + * + * Description: + * Increase the size of I/O buffer by the specified buffer increment. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_reallocbuffer(FAR struct mod_loadinfo_s *loadinfo, size_t increment) +{ + FAR void *buffer; + size_t newsize; + + /* Get the new size of the allocation */ + + newsize = loadinfo->buflen + increment; + + /* And perform the reallocation */ + + buffer = kmm_realloc((FAR void *)loadinfo->iobuffer, newsize); + if (!buffer) + { + sdbg("Failed to reallocate the I/O buffer\n"); + return -ENOMEM; + } + + /* Save the new buffer info */ + + loadinfo->iobuffer = buffer; + loadinfo->buflen = newsize; + return OK; +} + diff --git a/sched/module/mod_load.c b/sched/module/mod_load.c new file mode 100644 index 0000000000000000000000000000000000000000..cce6ac0cb20cd4b905d10e8568f561162d2107f9 --- /dev/null +++ b/sched/module/mod_load.c @@ -0,0 +1,291 @@ +/**************************************************************************** + * sched/module/mod_load.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ELF_ALIGN_MASK ((1 << CONFIG_MODULE_ALIGN_LOG2) - 1) +#define ELF_ALIGNUP(a) (((unsigned long)(a) + ELF_ALIGN_MASK) & ~ELF_ALIGN_MASK) +#define ELF_ALIGNDOWN(a) ((unsigned long)(a) & ~ELF_ALIGN_MASK) + +#ifndef MAX +# define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +#ifndef MIN +# define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_elfsize + * + * Description: + * Calculate total memory allocation for the ELF file. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static void mod_elfsize(struct mod_loadinfo_s *loadinfo) +{ + size_t textsize; + size_t datasize; + int i; + + /* Accumulate the size each section into memory that is marked SHF_ALLOC */ + + textsize = 0; + datasize = 0; + + for (i = 0; i < loadinfo->ehdr.e_shnum; i++) + { + FAR Elf32_Shdr *shdr = &loadinfo->shdr[i]; + + /* SHF_ALLOC indicates that the section requires memory during + * execution. + */ + + if ((shdr->sh_flags & SHF_ALLOC) != 0) + { + /* SHF_WRITE indicates that the section address space is write- + * able + */ + + if ((shdr->sh_flags & SHF_WRITE) != 0) + { + datasize += ELF_ALIGNUP(shdr->sh_size); + } + else + { + textsize += ELF_ALIGNUP(shdr->sh_size); + } + } + } + + /* Save the allocation size */ + + loadinfo->textsize = textsize; + loadinfo->datasize = datasize; +} + +/**************************************************************************** + * Name: mod_loadfile + * + * Description: + * Read the section data into memory. Section addresses in the shdr[] are + * updated to point to the corresponding position in the memory. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static inline int mod_loadfile(FAR struct mod_loadinfo_s *loadinfo) +{ + FAR uint8_t *text; + FAR uint8_t *data; + FAR uint8_t **pptr; + int ret; + int i; + + /* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */ + + svdbg("Loaded sections:\n"); + text = (FAR uint8_t *)loadinfo->textalloc; + data = (FAR uint8_t *)loadinfo->datastart; + + for (i = 0; i < loadinfo->ehdr.e_shnum; i++) + { + FAR Elf32_Shdr *shdr = &loadinfo->shdr[i]; + + /* SHF_ALLOC indicates that the section requires memory during + * execution */ + + if ((shdr->sh_flags & SHF_ALLOC) == 0) + { + continue; + } + + /* SHF_WRITE indicates that the section address space is write- + * able + */ + + if ((shdr->sh_flags & SHF_WRITE) != 0) + { + pptr = &data; + } + else + { + pptr = &text; + } + + /* SHT_NOBITS indicates that there is no data in the file for the + * section. + */ + + if (shdr->sh_type != SHT_NOBITS) + { + /* Read the section data from sh_offset to the memory region */ + + ret = mod_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset); + if (ret < 0) + { + sdbg("ERROR: Failed to read section %d: %d\n", i, ret); + return ret; + } + } + + /* If there is no data in an allocated section, then the allocated + * section must be cleared. + */ + + else + { + memset(*pptr, 0, shdr->sh_size); + } + + /* Update sh_addr to point to copy in memory */ + + svdbg("%d. %08lx->%08lx\n", i, + (unsigned long)shdr->sh_addr, (unsigned long)*pptr); + + shdr->sh_addr = (uintptr_t)*pptr; + + /* Setup the memory pointer for the next time through the loop */ + + *pptr += ELF_ALIGNUP(shdr->sh_size); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_load + * + * Description: + * Loads the binary into memory, allocating memory, performing relocations + * and initializing the data and bss segments. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_load(FAR struct mod_loadinfo_s *loadinfo) +{ + int ret; + + svdbg("loadinfo: %p\n", loadinfo); + DEBUGASSERT(loadinfo && loadinfo->filfd >= 0); + + /* Load section headers into memory */ + + ret = mod_loadshdrs(loadinfo); + if (ret < 0) + { + sdbg("ERROR: mod_loadshdrs failed: %d\n", ret); + goto errout_with_buffers; + } + + /* Determine total size to allocate */ + + mod_elfsize(loadinfo); + + /* Allocate (and zero) memory for the ELF file. */ + + /* Allocate memory to hold the ELF image */ + + loadinfo->textalloc = (uintptr_t)kmm_zalloc(loadinfo->textsize + loadinfo->datasize); + if (!loadinfo->textalloc) + { + sdbg("ERROR: Failed to allocate memory for the module\n"); + ret = -ENOMEM; + goto errout_with_buffers; + } + + loadinfo->datastart = loadinfo->textalloc + loadinfo->textsize; + + /* Load ELF section data into memory */ + + ret = mod_loadfile(loadinfo); + if (ret < 0) + { + sdbg("ERROR: mod_loadfile failed: %d\n", ret); + goto errout_with_buffers; + } + + return OK; + + /* Error exits */ + +errout_with_buffers: + mod_unload(loadinfo); + return ret; +} diff --git a/sched/module/mod_procfs.c b/sched/module/mod_procfs.c new file mode 100644 index 0000000000000000000000000000000000000000..411cb1eccdee6450ce5ca686034c0b22c0fcfd33 --- /dev/null +++ b/sched/module/mod_procfs.c @@ -0,0 +1,318 @@ +/**************************************************************************** + * sched/module/mod_procfs.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "module.h" + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ + !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ + +#define MOD_LINELEN 64 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct modprocfs_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + + /* Read helpers */ + + FAR char *buffer; /* User buffer pointer */ + size_t buflen; /* Size of the user buffer */ + size_t remaining; /* Space remaining in user buffer */ + size_t totalsize; /* Total size returned by read() */ + off_t offset; /* Offset skip on output */ + char line[MOD_LINELEN]; /* Buffer for line formatting */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* File system methods */ + +static int modprocfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode); +static int modprocfs_close(FAR struct file *filep); +static ssize_t modprocfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int modprocfs_dup(FAR const struct file *oldp, + FAR struct file *newp); +static int modprocfs_stat(FAR const char *relpath, FAR struct stat *buf); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* See include/nutts/fs/procfs.h + * We use the old-fashioned kind of initializers so that this will compile + * with any compiler. + */ + +const struct procfs_operations module_operations = +{ + modprocfs_open, /* open */ + modprocfs_close, /* close */ + modprocfs_read, /* read */ + NULL, /* write */ + modprocfs_dup, /* dup */ + + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + + modprocfs_stat /* stat */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modprocfs_callback + ****************************************************************************/ + +static int modprocfs_callback(FAR struct module_s *modp, FAR void *arg) +{ + FAR struct modprocfs_file_s *priv; + size_t linesize; + size_t copysize; + + DEBUGASSERT(modp != NULL && arg != NULL); + priv = (FAR struct modprocfs_file_s *)arg; + + linesize = snprintf(priv->line, MOD_LINELEN, "%s,%p,%p,%p,%p,%lu,%p,%lu\n", + modp->modulename, modp->initializer, + modp->uninitializer, modp->arg, + modp->alloc, (unsigned long)modp->textsize, + (FAR uint8_t *)modp->alloc + modp->textsize, + (unsigned long)modp->datasize); + copysize = procfs_memcpy(priv->line, linesize, priv->buffer, + priv->remaining, &priv->offset); + priv->totalsize += copysize; + priv->buffer += copysize; + priv->remaining -= copysize; + + return (priv->totalsize >= priv->buflen) ? 1 : 0; +} + +/**************************************************************************** + * Name: modprocfs_open + ****************************************************************************/ + +static int modprocfs_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct modprocfs_file_s *priv; + + fvdbg("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if (((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)) + { + fdbg("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* Allocate the open file structure */ + + priv = (FAR struct modprocfs_file_s *)kmm_zalloc(sizeof(struct modprocfs_file_s)); + if (!priv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the open file structure as the open-specific state in + * filep->f_priv. + */ + + filep->f_priv = (FAR void *)priv; + return OK; +} + +/**************************************************************************** + * Name: modprocfs_close + ****************************************************************************/ + +static int modprocfs_close(FAR struct file *filep) +{ + FAR struct modprocfs_file_s *priv; + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct modprocfs_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + /* Release the file attributes structure */ + + kmm_free(priv); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: modprocfs_read + ****************************************************************************/ + +static ssize_t modprocfs_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct modprocfs_file_s *priv; + int ret; + + fvdbg("buffer=%p buflen=%lu\n", buffer, (unsigned long)buflen); + + /* Recover our private data from the struct file instance */ + + priv = (FAR struct modprocfs_file_s *)filep->f_priv; + DEBUGASSERT(priv); + + /* Traverse all installed modules */ + + priv->remaining = buflen; + priv->totalsize = 0; + priv->buffer = buffer; + priv->buflen = buflen; + priv->offset = filep->f_pos; + + ret = mod_registry_foreach(modprocfs_callback, priv); + if (ret >= 0) + { + filep->f_pos += priv->totalsize; + return priv->totalsize; + } + + return ret; +} + +/**************************************************************************** + * Name: modprocfs_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int modprocfs_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct modprocfs_file_s *oldpriv; + FAR struct modprocfs_file_s *newpriv; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldpriv = (FAR struct modprocfs_file_s *)oldp->f_priv; + DEBUGASSERT(oldpriv); + + /* Allocate a new container to hold the task and attribute selection */ + + newpriv = (FAR struct modprocfs_file_s *)kmm_zalloc(sizeof(struct modprocfs_file_s)); + if (!newpriv) + { + fdbg("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attribtes from the old attributes to the new */ + + memcpy(newpriv, oldpriv, sizeof(struct modprocfs_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newpriv; + return OK; +} + +/**************************************************************************** + * Name: modprocfs_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int modprocfs_stat(FAR const char *relpath, FAR struct stat *buf) +{ + memset(buf, 0, sizeof(struct stat)); + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS && + * !CONFIG_FS_PROCFS_EXCLUDE_MODULE */ diff --git a/sched/module/mod_read.c b/sched/module/mod_read.c new file mode 100644 index 0000000000000000000000000000000000000000..8cad4adb8913cf30dce901a69e855ec2dc52be32 --- /dev/null +++ b/sched/module/mod_read.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * sched/module/mod_read.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "module.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef ELF_DUMP_READDATA /* Define to dump all file data read */ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_dumpreaddata + ****************************************************************************/ + +#if defined(ELF_DUMP_READDATA) +static inline void mod_dumpreaddata(FAR char *buffer, int buflen) +{ + FAR uint32_t *buf32 = (FAR uint32_t *)buffer; + int i; + int j; + + for (i = 0; i < buflen; i += 32) + { + syslog(LOG_DEBUG, "%04x:", i); + for (j = 0; j < 32; j += sizeof(uint32_t)) + { + syslog(LOG_DEBUG, " %08x", *buf32++); + } + + syslog(LOG_DEBUG, "\n"); + } +} +#else +# define mod_dumpreaddata(b,n) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_read + * + * Description: + * Read 'readsize' bytes from the object file at 'offset'. The data is + * read into 'buffer.' + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_read(FAR struct mod_loadinfo_s *loadinfo, FAR uint8_t *buffer, + size_t readsize, off_t offset) +{ + ssize_t nbytes; /* Number of bytes read */ + off_t rpos; /* Position returned by lseek */ + + svdbg("Read %ld bytes from offset %ld\n", (long)readsize, (long)offset); + + /* Loop until all of the requested data has been read. */ + + while (readsize > 0) + { + /* Seek to the next read position */ + + rpos = lseek(loadinfo->filfd, offset, SEEK_SET); + if (rpos != offset) + { + int errval = errno; + sdbg("Failed to seek to position %lu: %d\n", + (unsigned long)offset, errval); + return -errval; + } + + /* Read the file data at offset into the user buffer */ + + nbytes = read(loadinfo->filfd, buffer, readsize); + if (nbytes < 0) + { + int errval = errno; + + /* EINTR just means that we received a signal */ + + if (errval != EINTR) + { + sdbg("Read from offset %lu failed: %d\n", + (unsigned long)offset, errval); + return -errval; + } + } + else if (nbytes == 0) + { + sdbg("Unexpected end of file\n"); + return -ENODATA; + } + else + { + readsize -= nbytes; + buffer += nbytes; + offset += nbytes; + } + } + + mod_dumpreaddata(buffer, readsize); + return OK; +} diff --git a/sched/module/mod_registry.c b/sched/module/mod_registry.c new file mode 100644 index 0000000000000000000000000000000000000000..7df1168b350a07932e779a42cd0dd4d22d23ac0f --- /dev/null +++ b/sched/module/mod_registry.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * sched/module/mod_registry.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "module.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_mod_lock = SEM_INITIALIZER(1); +static FAR struct module_s *g_mod_registry; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_registry_lock + * + * Description: + * Get exclusive access to the module registry. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_registry_lock(void) +{ + while (sem_post(&g_mod_lock) < 0) + { + DEBUGASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: mod_registry_unlock + * + * Description: + * Relinquish the lock on the module registry + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_registry_unlock(void) +{ + sem_post(&g_mod_lock); +} + +/**************************************************************************** + * Name: mod_registry_add + * + * Description: + * Add a new entry to the module registry. + * + * Input Parameters: + * modp - The module data structure to be registered. + * + * Returned Value: + * None + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +void mod_registry_add(FAR struct module_s *modp) +{ + DEBUGASSERT(modp); + modp->flink = g_mod_registry; + g_mod_registry = modp; +} + +/**************************************************************************** + * Name: mod_registry_del + * + * Description: + * Remove a module entry from the registry + * + * Input Parameters: + * modp - The registry entry to be removed. + * + * Returned Value: + * Zero (OK) is returned if the registry entry was deleted. Otherwise, + * a negated errno value is returned. + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +int mod_registry_del(FAR struct module_s *modp) +{ + FAR struct module_s *prev; + FAR struct module_s *curr; + + for (prev = NULL, curr = g_mod_registry; + curr != NULL && curr != modp; + prev = curr, curr = curr->flink); + + if (curr == NULL) + { + sdbg("ERROR: Could not find module entry\n"); + return -ENOENT; + } + + if (prev == NULL) + { + g_mod_registry = modp->flink; + } + else + { + prev->flink = modp->flink; + } + + modp->flink = NULL; + return OK; +} + +/**************************************************************************** + * Name: mod_registry_find + * + * Description: + * Find an entry in the module registry using the name of the module. + * + * Input Parameters: + * modulename - The name of the module to be found + * + * Returned Value: + * If the registry entry is found, a pointer to the module entry is + * returned. NULL is returned if the they entry is not found. + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +FAR struct module_s *mod_registry_find(FAR const char *modulename) +{ + FAR struct module_s *modp; + + for (modp = g_mod_registry; + modp != NULL && strncmp(modp->modulename, modulename, MODULENAME_MAX) != 0; + modp = modp->flink); + + return modp; +} + +/**************************************************************************** + * Name: mod_registry_foreach + * + * Description: + * Visit each module in the registry + * + * Input Parameters: + * callback - This callback function was be called for each entry in the + * registry. + * arg - This opaque argument will be passed to the callback function. + * + * Returned Value: + * This function normally returns zero (OK). If, however, any callback + * function returns a non-zero value, the traversal will be terminated and + * that non-zero value will be returned. + * + * Assumptions: + * The caller does *NOT* hold the lock on the module registry. + * + ****************************************************************************/ + +int mod_registry_foreach(mod_callback_t callback, FAR void *arg) +{ + FAR struct module_s *modp; + int ret; + + /* Get exclusive access to the module registry */ + + mod_registry_lock(); + + /* Visit each installed module */ + + for (modp = g_mod_registry; modp != NULL; modp = modp->flink) + { + /* Perform the callback */ + + ret = callback(modp, arg); + if (ret != 0) + { + return ret; + } + } + + mod_registry_unlock(); + return OK; +} \ No newline at end of file diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c new file mode 100644 index 0000000000000000000000000000000000000000..76fff1c7aab14d55642a5cbf9e4fe347ca34b18b --- /dev/null +++ b/sched/module/mod_rmmod.c @@ -0,0 +1,160 @@ +/**************************************************************************** + * sched/module/module.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "module/module.h" + +#ifdef CONFIG_MODULE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rmmod + * + * Description: + * Remove a previously installed module from memory. + * + * Input Parameters: + * + * modulename - The module name. This is the name module name that was + * provided to insmod when the module was loaded. + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int rmmod(FAR const char *modulename) +{ + FAR struct module_s *modp; + int ret = OK; + + DEBUGASSERT(modulename != NULL); + + /* Get exclusive access to the module registry */ + + mod_registry_lock(); + + /* Find the module entry for this modulename in the registry */ + + modp = mod_registry_find(modulename); + if (modp == NULL) + { + sdbg("ERROR: Failed to find module %s: %d\n", modulename, ret); + ret = -ENOENT; + goto errout_with_lock; + } + + /* Is there an uninitializer? */ + + if (modp->uninitializer != NULL) + { + /* Try to uninitializer the module */ + + ret = modp->uninitializer(modp->arg); + + /* Did the module sucessfully uninitialize? */ + + if (ret < 0) + { + sdbg("ERROR: Failed to uninitialize the module: %d\n", ret); + goto errout_with_lock; + } + + /* Nullify so that the uninitializer cannot be called again */ + +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + modp->initializer = NULL; +#endif + modp->uninitializer = NULL; + modp->arg = NULL; + } + + /* Release resources held by the module */ + + if (modp->alloc != NULL) + { + /* Free the module memory */ + + kmm_free((FAR void *)modp->alloc); + + /* Nullify so that the memory cannot be freed again */ + + modp->alloc = NULL; +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + modp->textsize = 0; + modp->datasize = 0; +#endif + } + + /* Remove the module from the registry */ + + ret = mod_registry_del(modp); + if (ret < 0) + { + sdbg("ERROR: Failed to remove the module from the registry: %d\n", ret); + goto errout_with_lock; + } + + mod_registry_unlock(); + + /* And free the registry entry */ + + kmm_free(modp); + return OK; + +errout_with_lock: + mod_registry_unlock(); + set_errno(-ret); + return ERROR; +} + +#endif /* CONFIG_MODULE */ diff --git a/sched/module/mod_sections.c b/sched/module/mod_sections.c new file mode 100644 index 0000000000000000000000000000000000000000..dcdb4de9918bf1f28d761717396e868a7e0cfa77 --- /dev/null +++ b/sched/module/mod_sections.c @@ -0,0 +1,279 @@ +/**************************************************************************** + * sched/module/mod_sections.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_sectname + * + * Description: + * Get the symbol name in loadinfo->iobuffer[]. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +static inline int mod_sectname(FAR struct mod_loadinfo_s *loadinfo, + FAR const Elf32_Shdr *shdr) +{ + FAR Elf32_Shdr *shstr; + FAR uint8_t *buffer; + off_t offset; + size_t readlen; + size_t bytesread; + int shstrndx; + int ret; + + /* Get the section header table index of the entry associated with the + * section name string table. If the file has no section name string table, + * this member holds the value SH_UNDEF. + */ + + shstrndx = loadinfo->ehdr.e_shstrndx; + if (shstrndx == SHN_UNDEF) + { + sdbg("No section header string table\n"); + return -EINVAL; + } + + /* Get the section name string table section header */ + + shstr = &loadinfo->shdr[shstrndx]; + + /* Get the file offset to the string that is the name of the section. This + * is the sum of: + * + * shstr->sh_offset: The file offset to the first byte of the section + * header string table data. + * shdr->sh_name: The offset to the name of the section in the section + * name table + */ + + offset = shstr->sh_offset + shdr->sh_name; + + /* Loop until we get the entire section name into memory */ + + buffer = loadinfo->iobuffer; + bytesread = 0; + + for (; ; ) + { + /* Get the number of bytes to read */ + + readlen = loadinfo->buflen - bytesread; + if (offset + readlen > loadinfo->filelen) + { + if (loadinfo->filelen <= offset) + { + sdbg("At end of file\n"); + return -EINVAL; + } + + readlen = loadinfo->filelen - offset; + } + + /* Read that number of bytes into the array */ + + buffer = &loadinfo->iobuffer[bytesread]; + ret = mod_read(loadinfo, buffer, readlen, offset); + if (ret < 0) + { + sdbg("Failed to read section name\n"); + return ret; + } + + bytesread += readlen; + + /* Did we read the NUL terminator? */ + + if (memchr(buffer, '\0', readlen) != NULL) + { + /* Yes, the buffer contains a NUL terminator. */ + + return OK; + } + + /* No.. then we have to read more */ + + ret = mod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR); + if (ret < 0) + { + sdbg("mod_reallocbuffer failed: %d\n", ret); + return ret; + } + } + + /* We will not get here */ + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_loadshdrs + * + * Description: + * Loads section headers into memory. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_loadshdrs(FAR struct mod_loadinfo_s *loadinfo) +{ + size_t shdrsize; + int ret; + + DEBUGASSERT(loadinfo->shdr == NULL); + + /* Verify that there are sections */ + + if (loadinfo->ehdr.e_shnum < 1) + { + sdbg("No sections(?)\n"); + return -EINVAL; + } + + /* Get the total size of the section header table */ + + shdrsize = (size_t)loadinfo->ehdr.e_shentsize * (size_t)loadinfo->ehdr.e_shnum; + if (loadinfo->ehdr.e_shoff + shdrsize > loadinfo->filelen) + { + sdbg("Insufficent space in file for section header table\n"); + return -ESPIPE; + } + + /* Allocate memory to hold a working copy of the sector header table */ + + loadinfo->shdr = (FAR FAR Elf32_Shdr *)kmm_malloc(shdrsize); + if (!loadinfo->shdr) + { + sdbg("Failed to allocate the section header table. Size: %ld\n", + (long)shdrsize); + return -ENOMEM; + } + + /* Read the section header table into memory */ + + ret = mod_read(loadinfo, (FAR uint8_t *)loadinfo->shdr, shdrsize, + loadinfo->ehdr.e_shoff); + if (ret < 0) + { + sdbg("Failed to read section header table: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: mod_findsection + * + * Description: + * A section by its name. + * + * Input Parameters: + * loadinfo - Load state information + * sectname - Name of the section to find + * + * Returned Value: + * On success, the index to the section is returned; A negated errno value + * is returned on failure. + * + ****************************************************************************/ + +int mod_findsection(FAR struct mod_loadinfo_s *loadinfo, + FAR const char *sectname) +{ + FAR const Elf32_Shdr *shdr; + int ret; + int i; + + /* Search through the shdr[] array in loadinfo for a section named 'sectname' */ + + for (i = 0; i < loadinfo->ehdr.e_shnum; i++) + { + /* Get the name of this section */ + + shdr = &loadinfo->shdr[i]; + ret = mod_sectname(loadinfo, shdr); + if (ret < 0) + { + sdbg("mod_sectname failed: %d\n", ret); + return ret; + } + + /* Check if the name of this section is 'sectname' */ + + svdbg("%d. Comparing \"%s\" and .\"%s\"\n", + i, loadinfo->iobuffer, sectname); + + if (strcmp((FAR const char *)loadinfo->iobuffer, sectname) == 0) + { + /* We found it... return the index */ + + return i; + } + } + + /* We failed to find a section with this name. */ + + return -ENOENT; +} diff --git a/sched/module/mod_symbols.c b/sched/module/mod_symbols.c new file mode 100644 index 0000000000000000000000000000000000000000..bc91a426e3e45d3471c056d9b83cd12a4a0d4da1 --- /dev/null +++ b/sched/module/mod_symbols.c @@ -0,0 +1,345 @@ +/**************************************************************************** + * sched/module/mod_symbols.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_MODULE_BUFFERINCR +# define CONFIG_MODULE_BUFFERINCR 32 +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_symname + * + * Description: + * Get the symbol name in loadinfo->iobuffer[]. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted). + * ESRCH - Symbol has no name + * + ****************************************************************************/ + +static int mod_symname(FAR struct mod_loadinfo_s *loadinfo, + FAR const Elf32_Sym *sym) +{ + FAR uint8_t *buffer; + off_t offset; + size_t readlen; + size_t bytesread; + int ret; + + /* Get the file offset to the string that is the name of the symbol. The + * st_name member holds an offset into the file's symbol string table. + */ + + if (sym->st_name == 0) + { + sdbg("Symbol has no name\n"); + return -ESRCH; + } + + offset = loadinfo->shdr[loadinfo->strtabidx].sh_offset + sym->st_name; + + /* Loop until we get the entire symbol name into memory */ + + bytesread = 0; + + for (; ; ) + { + /* Get the number of bytes to read */ + + readlen = loadinfo->buflen - bytesread; + if (offset + readlen > loadinfo->filelen) + { + if (loadinfo->filelen <= offset) + { + sdbg("At end of file\n"); + return -EINVAL; + } + + readlen = loadinfo->filelen - offset; + } + + /* Read that number of bytes into the array */ + + buffer = &loadinfo->iobuffer[bytesread]; + ret = mod_read(loadinfo, buffer, readlen, offset); + if (ret < 0) + { + sdbg("mod_read failed: %d\n", ret); + return ret; + } + + bytesread += readlen; + + /* Did we read the NUL terminator? */ + + if (memchr(buffer, '\0', readlen) != NULL) + { + /* Yes, the buffer contains a NUL terminator. */ + + return OK; + } + + /* No.. then we have to read more */ + + ret = mod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR); + if (ret < 0) + { + sdbg("mod_reallocbuffer failed: %d\n", ret); + return ret; + } + } + + /* We will not get here */ + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_findsymtab + * + * Description: + * Find the symbol table section. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_findsymtab(FAR struct mod_loadinfo_s *loadinfo) +{ + int i; + + /* Find the symbol table section header and its associated string table */ + + for (i = 1; i < loadinfo->ehdr.e_shnum; i++) + { + if (loadinfo->shdr[i].sh_type == SHT_SYMTAB) + { + loadinfo->symtabidx = i; + loadinfo->strtabidx = loadinfo->shdr[i].sh_link; + break; + } + } + + /* Verify that there is a symbol and string table */ + + if (loadinfo->symtabidx == 0) + { + sdbg("No symbols in ELF file\n"); + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: mod_readsym + * + * Description: + * Read the ELFT symbol structure at the specfied index into memory. + * + * Input Parameters: + * loadinfo - Load state information + * index - Symbol table index + * sym - Location to return the table entry + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, + FAR Elf32_Sym *sym) +{ + FAR Elf32_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx]; + off_t offset; + + /* Verify that the symbol table index lies within symbol table */ + + if (index < 0 || index > (symtab->sh_size / sizeof(Elf32_Sym))) + { + sdbg("Bad relocation symbol index: %d\n", index); + return -EINVAL; + } + + /* Get the file offset to the symbol table entry */ + + offset = symtab->sh_offset + sizeof(Elf32_Sym) * index; + + /* And, finally, read the symbol table entry into memory */ + + return mod_read(loadinfo, (FAR uint8_t *)sym, sizeof(Elf32_Sym), offset); +} + +/**************************************************************************** + * Name: mod_symvalue + * + * Description: + * Get the value of a symbol. The updated value of the symbol is returned + * in the st_value field of the symbol table entry. + * + * Input Parameters: + * loadinfo - Load state information + * sym - Symbol table entry (value might be undefined) + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted). + * ENOSYS - Symbol lies in common + * ESRCH - Symbol has no name + * ENOENT - Symbol undefined and not provided via a symbol table + * + ****************************************************************************/ + +int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym) +{ + FAR const struct symtab_s *symbol; + uintptr_t secbase; + int ret; + + switch (sym->st_shndx) + { + case SHN_COMMON: + { + /* NuttX ELF modules should be compiled with -fno-common. */ + + sdbg("SHN_COMMON: Re-compile with -fno-common\n"); + return -ENOSYS; + } + + case SHN_ABS: + { + /* st_value already holds the correct value */ + + svdbg("SHN_ABS: st_value=%08lx\n", (long)sym->st_value); + return OK; + } + + case SHN_UNDEF: + { + /* Get the name of the undefined symbol */ + + ret = mod_symname(loadinfo, sym); + if (ret < 0) + { + /* There are a few relocations for a few architectures that do + * no depend upon a named symbol. We don't know if that is the + * case here, but return and special error to the caller to + * indicate the nameless symbol. + */ + + sdbg("SHN_UNDEF: Failed to get symbol name: %d\n", ret); + return ret; + } + + /* Check if the base code exports a symbol of this name */ + +#ifdef CONFIG_SYMTAB_ORDEREDBYNAME + symbol = symtab_findorderedbyname(g_mod_symtab, + (FAR char *)loadinfo->iobuffer, + g_mod_nsymbols); +#else + symbol = symtab_findbyname(g_mod_symtab, + (FAR char *)loadinfo->iobuffer, + g_mod_nsymbols); +#endif + if (!symbol) + { + sdbg("SHN_UNDEF: Exported symbol \"%s\" not found\n", loadinfo->iobuffer); + return -ENOENT; + } + + /* Yes... add the exported symbol value to the ELF symbol table entry */ + + svdbg("SHN_ABS: name=%s %08x+%08x=%08x\n", + loadinfo->iobuffer, sym->st_value, symbol->sym_value, + sym->st_value + symbol->sym_value); + + sym->st_value += (Elf32_Word)((uintptr_t)symbol->sym_value); + } + break; + + default: + { + secbase = loadinfo->shdr[sym->st_shndx].sh_addr; + + svdbg("Other: %08x+%08x=%08x\n", + sym->st_value, secbase, sym->st_value + secbase); + + sym->st_value += secbase; + } + break; + } + + return OK; +} diff --git a/sched/module/mod_symtab.c b/sched/module/mod_symtab.c new file mode 100644 index 0000000000000000000000000000000000000000..0c0648f2944bce02012ca05b11949ad220dd3232 --- /dev/null +++ b/sched/module/mod_symtab.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * sched/module/mod_symtab.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +FAR const struct symtab_s *g_mod_symtab; +FAR int g_mod_nsymbols; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_getsymtab + * + * Description: + * Get the current kernel symbol table selection as an atomic operation. + * + * Input Parameters: + * symtab - The location to store the symbol table. + * nsymbols - The location to store the number of symbols in the symbol table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols) +{ + DEBUGASSERT(symtab != NULL && nsymbols != NULL); + + /* Borrow the registry lock to assure atomic access */ + + mod_registry_lock(); + *symtab = g_mod_symtab; + *nsymbols = g_mod_nsymbols; + mod_registry_lock(); +} + +/**************************************************************************** + * Name: mod_setsymtab + * + * Description: + * Select a new kernel symbol table selection as an atomic operation. + * + * Input Parameters: + * symtab - The new symbol table. + * nsymbols - The number of symbols in the symbol table. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_setsymtab(FAR const struct symtab_s *symtab, int nsymbols) +{ + /* Borrow the registry lock to assure atomic access */ + + mod_registry_lock(); + g_mod_symtab = symtab; + g_mod_nsymbols = nsymbols; + mod_registry_lock(); +} diff --git a/sched/module/mod_uninit.c b/sched/module/mod_uninit.c new file mode 100644 index 0000000000000000000000000000000000000000..dcb4bfa658cef78e37712c34c91ba2e8d3c8850d --- /dev/null +++ b/sched/module/mod_uninit.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * sched/module/mod_uninit.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_uninitialize + * + * Description: + * Releases any resources committed by mod_initialize(). This essentially + * undoes the actions of mod_initialize. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_uninitialize(struct mod_loadinfo_s *loadinfo) +{ + /* Free all working buffers */ + + mod_freebuffers(loadinfo); + + /* Close the ELF file */ + + if (loadinfo->filfd >= 0) + { + close(loadinfo->filfd); + } + + return OK; +} + +/**************************************************************************** + * Name: mod_freebuffers + * + * Description: + * Release all working buffers. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_freebuffers(struct mod_loadinfo_s *loadinfo) +{ + /* Release all working allocations */ + + if (loadinfo->shdr) + { + kmm_free((FAR void *)loadinfo->shdr); + loadinfo->shdr = NULL; + } + + if (loadinfo->iobuffer) + { + kmm_free((FAR void *)loadinfo->iobuffer); + loadinfo->iobuffer = NULL; + loadinfo->buflen = 0; + } + + return OK; +} diff --git a/sched/module/mod_unload.c b/sched/module/mod_unload.c new file mode 100644 index 0000000000000000000000000000000000000000..f44e3f4da19778ca726e4b9d355d7f8fff5b65ef --- /dev/null +++ b/sched/module/mod_unload.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * sched/module/mod_unload.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "module.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_unload + * + * Description: + * This function unloads the object from memory. This essentially undoes + * the actions of mod_load. It is called only under certain error + * conditions after the module has been loaded but not yet started. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_unload(struct mod_loadinfo_s *loadinfo) +{ + /* Free all working buffers */ + + mod_freebuffers(loadinfo); + + /* Release memory holding the relocated ELF image */ + + if (loadinfo->textalloc != 0) + { + kmm_free((FAR void *)loadinfo->textalloc); + } + + /* Clear out all indications of the allocated address environment */ + + loadinfo->textalloc = 0; + loadinfo->datastart = 0; + loadinfo->textsize = 0; + loadinfo->datasize = 0; + + return OK; +} diff --git a/sched/module/mod_verify.c b/sched/module/mod_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..a46d96f73d885d545ba50c890f0d73e587107ab6 --- /dev/null +++ b/sched/module/mod_verify.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * sched/module/mod_verify.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +static const char g_modmagic[EI_MAGIC_SIZE] = +{ + 0x7f, 'E', 'L', 'F' +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_verifyheader + * + * Description: + * Given the header from a possible ELF executable, verify that it + * is an ELF executable. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + * -ENOEXEC : Not an ELF file + * -EINVAL : Not a relocatable ELF file or not supported by the current, + * configured architecture. + * + ****************************************************************************/ + +int mod_verifyheader(FAR const Elf32_Ehdr *ehdr) +{ + if (!ehdr) + { + sdbg("NULL ELF header!"); + return -ENOEXEC; + } + + /* Verify that the magic number indicates an ELF file */ + + if (memcmp(ehdr->e_ident, g_modmagic, EI_MAGIC_SIZE) != 0) + { + svdbg("Not ELF magic {%02x, %02x, %02x, %02x}\n", + ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]); + return -ENOEXEC; + } + + /* Verify that this is a relocatable file */ + + if (ehdr->e_type != ET_REL) + { + sdbg("Not a relocatable file: e_type=%d\n", ehdr->e_type); + return -EINVAL; + } + + /* Verify that this file works with the currently configured architecture */ + + if (up_checkarch(ehdr)) + { + sdbg("Not a supported architecture\n"); + return -ENOEXEC; + } + + /* Looks good so far... we still might find some problems later. */ + + return OK; +} diff --git a/sched/module/module.h b/sched/module/module.h new file mode 100644 index 0000000000000000000000000000000000000000..9bccc0c6e1df65d5a43c866e95cfca56a81112c3 --- /dev/null +++ b/sched/module/module.h @@ -0,0 +1,447 @@ +/**************************************************************************** + * sched/module/module.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 __SCHED_MODULE_MODULE_H +#define __SCHED_MODULE_MODULE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the file to be loaded. */ + +struct symtab_s; +struct module_s +{ + FAR struct module_s *flink; /* Supports a singly linked list */ + FAR char modulename[MODULENAME_MAX]; /* Module name */ +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + mod_initializer_t initializer; /* Module initializer function */ +#endif + mod_uninitializer_t uninitializer; /* Module uninitializer function */ + FAR void *arg; /* Uninitializer argument */ + FAR void *alloc; /* Allocated kernel memory */ +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + size_t textsize; /* Size of the kernel .text memory allocation */ + size_t datasize; /* Size of the kernel .bss/.data memory allocation */ +#endif +}; + +/* This struct provides a description of the currently loaded instantiation + * of the kernel module. + */ + +struct mod_loadinfo_s +{ + /* elfalloc is the base address of the memory that is allocated to hold the + * module image. + * + * The alloc[] array in struct module_s will hold memory that persists after + * the module has been loaded. + */ + + uintptr_t textalloc; /* .text memory allocated when module was loaded */ + uintptr_t datastart; /* Start of.bss/.data memory in .text allocation */ + size_t textsize; /* Size of the module .text memory allocation */ + size_t datasize; /* Size of the module .bss/.data memory allocation */ + off_t filelen; /* Length of the entire module file */ + Elf32_Ehdr ehdr; /* Buffered module file header */ + FAR Elf32_Shdr *shdr; /* Buffered module section headers */ + uint8_t *iobuffer; /* File I/O buffer */ + + uint16_t symtabidx; /* Symbol table section index */ + uint16_t strtabidx; /* String table section index */ + uint16_t buflen; /* size of iobuffer[] */ + int filfd; /* Descriptor for the file being loaded */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +FAR const struct symtab_s *g_mod_symtab; +FAR int g_mod_nsymbols; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mod_initialize + * + * Description: + * This function is called to configure the library to process an kernel + * module. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_initialize(FAR const char *filename, + FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_uninitialize + * + * Description: + * Releases any resources committed by mod_init(). This essentially + * undoes the actions of mod_initialize. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_uninitialize(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_load + * + * Description: + * Loads the binary into memory, allocating memory, performing relocations + * and initializing the data and bss segments. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_load(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_bind + * + * Description: + * Bind the imported symbol names in the loaded module described by + * 'loadinfo' using the exported symbol values provided by mod_setsymtab(). + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_bind(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_unload + * + * Description: + * This function unloads the object from memory. This essentially undoes + * the actions of mod_load. It is called only under certain error + * conditions after the module has been loaded but not yet started. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_unload(struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_verifyheader + * + * Description: + * Given the header from a possible ELF executable, verify that it is + * an ELF executable. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_verifyheader(FAR const Elf32_Ehdr *header); + +/**************************************************************************** + * Name: mod_read + * + * Description: + * Read 'readsize' bytes from the object file at 'offset'. The data is + * read into 'buffer.' + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_read(FAR struct mod_loadinfo_s *loadinfo, FAR uint8_t *buffer, + size_t readsize, off_t offset); + +/**************************************************************************** + * Name: mod_loadshdrs + * + * Description: + * Loads section headers into memory. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_loadshdrs(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_findsection + * + * Description: + * A section by its name. + * + * Input Parameters: + * loadinfo - Load state information + * sectname - Name of the section to find + * + * Returned Value: + * On success, the index to the section is returned; A negated errno value + * is returned on failure. + * + ****************************************************************************/ + +int mod_findsection(FAR struct mod_loadinfo_s *loadinfo, + FAR const char *sectname); + +/**************************************************************************** + * Name: mod_findsymtab + * + * Description: + * Find the symbol table section. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_findsymtab(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_readsym + * + * Description: + * Read the ELFT symbol structure at the specfied index into memory. + * + * Input Parameters: + * loadinfo - Load state information + * index - Symbol table index + * sym - Location to return the table entry + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_readsym(FAR struct mod_loadinfo_s *loadinfo, int index, + FAR Elf32_Sym *sym); + +/**************************************************************************** + * Name: mod_symvalue + * + * Description: + * Get the value of a symbol. The updated value of the symbol is returned + * in the st_value field of the symbol table entry. + * + * Input Parameters: + * loadinfo - Load state information + * sym - Symbol table entry (value might be undefined) + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted) + * ENOSYS - Symbol lies in common + * ESRCH - Symbol has no name + * ENOENT - Symbol undefined and not provided via a symbol table + * + ****************************************************************************/ + +int mod_symvalue(FAR struct mod_loadinfo_s *loadinfo, FAR Elf32_Sym *sym); + +/**************************************************************************** + * Name: mod_freebuffers + * + * Description: + * Release all working buffers. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_freebuffers(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_allocbuffer + * + * Description: + * Perform the initial allocation of the I/O buffer, if it has not already + * been allocated. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_allocbuffer(FAR struct mod_loadinfo_s *loadinfo); + +/**************************************************************************** + * Name: mod_reallocbuffer + * + * Description: + * Increase the size of I/O buffer by the specified buffer increment. + * + * Returned Value: + * 0 (OK) is returned on success and a negated errno is returned on + * failure. + * + ****************************************************************************/ + +int mod_reallocbuffer(FAR struct mod_loadinfo_s *loadinfo, size_t increment); + +/**************************************************************************** + * Name: mod_registry_lock + * + * Description: + * Get exclusive access to the module registry. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_registry_lock(void); + +/**************************************************************************** + * Name: mod_registry_unlock + * + * Description: + * Relinquish the lock on the module registry + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void mod_registry_unlock(void); + +/**************************************************************************** + * Name: mod_registry_add + * + * Description: + * Add a new entry to the module registry. + * + * Input Parameters: + * modp - The module data structure to be registered. + * + * Returned Value: + * None + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +void mod_registry_add(FAR struct module_s *modp); + +/**************************************************************************** + * Name: mod_registry_del + * + * Description: + * Remove a module entry from the registry + * + * Input Parameters: + * modp - The registry entry to be removed. + * + * Returned Value: + * Zero (OK) is returned if the registry entry was deleted. Otherwise, + * a negated errno value is returned. + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +int mod_registry_del(FAR struct module_s *modp); + +/**************************************************************************** + * Name: mod_registry_find + * + * Description: + * Find an entry in the module registry using the name of the module. + * + * Input Parameters: + * modulename - The name of the module to be found + * + * Returned Value: + * If the registry entry is found, a pointer to the module entry is + * returned. NULL is returned if the they entry is not found. + * + * Assumptions: + * The caller holds the lock on the module registry. + * + ****************************************************************************/ + +FAR struct module_s *mod_registry_find(FAR const char *modulename); + +#endif /* __SCHED_MODULE_MODULE_H */ diff --git a/sched/mqueue/mq_desclose.c b/sched/mqueue/mq_desclose.c index ea77793d36363dfd6921f74e2ef51b39379dc9b3..1de8ae073e7004a925a39d9e7be75aeb5eb83f59 100644 --- a/sched/mqueue/mq_desclose.c +++ b/sched/mqueue/mq_desclose.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_desclose.c * - * Copyright (C) 2007, 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -48,22 +49,6 @@ #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -105,7 +90,7 @@ void mq_desclose(mqd_t mqdes) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)sched_self(); + FAR struct tcb_s *rtcb = (FAR struct tcb_s *)sched_self(); FAR struct task_group_s *group = rtcb->group; FAR struct mqueue_inode_s *msgq; @@ -115,7 +100,7 @@ void mq_desclose(mqd_t mqdes) * descriptors. */ - sq_rem((FAR sq_entry_t*)mqdes, &group->tg_msgdesq); + sq_rem((FAR sq_entry_t *)mqdes, &group->tg_msgdesq); /* Find the message queue associated with the message descriptor */ @@ -128,15 +113,14 @@ void mq_desclose(mqd_t mqdes) #ifndef CONFIG_DISABLE_SIGNALS if (msgq->ntmqdes == mqdes) { + memset(&msgq->ntevent, 0, sizeof(struct sigevent)); msgq->ntpid = INVALID_PROCESS_ID; - msgq->ntsigno = 0; - msgq->ntvalue.sival_int = 0; msgq->ntmqdes = NULL; } #endif - /* Deallocate the message descriptor */ + /* Deallocate the message descriptor */ - mq_desfree(mqdes); + mq_desfree(mqdes); } diff --git a/sched/mqueue/mq_descreate.c b/sched/mqueue/mq_descreate.c index df6c8fcdc329716006fe5b1773a0032bced232ca..211e0846fe9d481fef16720e829f2e687f046c45 100644 --- a/sched/mqueue/mq_descreate.c +++ b/sched/mqueue/mq_descreate.c @@ -56,22 +56,6 @@ #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -166,7 +150,7 @@ mqd_t mq_descreate(FAR struct tcb_s *mtcb, FAR struct mqueue_inode_s *msgq, /* And add it to the specified task's TCB */ - sq_addlast((FAR sq_entry_t*)mqdes, &group->tg_msgdesq); + sq_addlast((FAR sq_entry_t *)mqdes, &group->tg_msgdesq); } return mqdes; diff --git a/sched/mqueue/mq_getattr.c b/sched/mqueue/mq_getattr.c index 9e997dfe36bdf41b23d731065da00fbff4d213a6..3c0725320fec0246d5085eb82900f32f8243c243 100644 --- a/sched/mqueue/mq_getattr.c +++ b/sched/mqueue/mq_getattr.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_getattr.c * * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. @@ -31,22 +31,22 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Function: mq_getattr * * Description: @@ -62,7 +62,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat) { diff --git a/sched/mqueue/mq_initialize.c b/sched/mqueue/mq_initialize.c index fa0afa40ed45334e4905f70ecf9a04f099704683..b86c74c6d9465e621b3b5587b367855aa30938d2 100644 --- a/sched/mqueue/mq_initialize.c +++ b/sched/mqueue/mq_initialize.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_initialize.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,13 +45,9 @@ #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************************/ + ****************************************************************************/ /* This is a container for a list of message queue descriptors. */ @@ -61,9 +57,9 @@ struct mq_des_block_s struct mq_des mqdes[NUM_MSG_DESCRIPTORS]; }; -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ /* The g_msgfree is a list of messages that are available for general * use. The number of messages in this list is a system configuration @@ -85,9 +81,9 @@ sq_queue_t g_msgfreeirq; sq_queue_t g_desfree; -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ /* g_msgalloc is a pointer to the start of the allocated block of * messages. @@ -105,11 +101,11 @@ static struct mqueue_msg_s *g_msgfreeirqalloc; static sq_queue_t g_desalloc; -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_msgblockalloc * * Description: @@ -118,7 +114,7 @@ static sq_queue_t g_desalloc; * Inputs Parameters: * queue * - ************************************************************************/ + ****************************************************************************/ static struct mqueue_msg_s * mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs, @@ -130,7 +126,7 @@ mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs, * configured number of messages. */ - mqmsgblock = (FAR struct mqueue_msg_s*) + mqmsgblock = (FAR struct mqueue_msg_s *) kmm_malloc(sizeof(struct mqueue_msg_s) * nmsgs); if (mqmsgblock) @@ -141,18 +137,18 @@ mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs, for (i = 0; i < nmsgs; i++) { mqmsg->type = alloc_type; - sq_addlast((FAR sq_entry_t*)mqmsg++, queue); + sq_addlast((FAR sq_entry_t *)mqmsg++, queue); } } return mqmsgblock; } -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_initialize * * Description: @@ -166,7 +162,7 @@ mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs, * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_initialize(void) { @@ -195,7 +191,7 @@ void mq_initialize(void) mq_desblockalloc(); } -/************************************************************************ +/**************************************************************************** * Name: mq_desblockalloc * * Description: @@ -208,7 +204,7 @@ void mq_initialize(void) * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_desblockalloc(void) { @@ -225,13 +221,13 @@ void mq_desblockalloc(void) * we ever need to reclaim the memory. */ - sq_addlast((FAR sq_entry_t*)&mqdesblock->queue, &g_desalloc); + sq_addlast((FAR sq_entry_t *)&mqdesblock->queue, &g_desalloc); /* Then add each message queue descriptor to the free list */ for (i = 0; i < NUM_MSG_DESCRIPTORS; i++) { - sq_addlast((FAR sq_entry_t*)&mqdesblock->mqdes[i], &g_desfree); + sq_addlast((FAR sq_entry_t *)&mqdesblock->mqdes[i], &g_desfree); } } } diff --git a/sched/mqueue/mq_msgfree.c b/sched/mqueue/mq_msgfree.c index 1630c09d06ed4cb9a44c7070cb408cabb0c6c525..3aefca36d43fdc5ada7a8558497997e907c73223 100644 --- a/sched/mqueue/mq_msgfree.c +++ b/sched/mqueue/mq_msgfree.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_msgfree.c * - * Copyright (C) 2007, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,46 +31,27 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include +#include #include #include #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_msgfree * * Description: @@ -84,11 +65,11 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_msgfree(FAR struct mqueue_msg_s *mqmsg) { - irqstate_t saved_state; + irqstate_t flags; /* If this is a generally available pre-allocated message, * then just put it back in the free list. @@ -100,9 +81,9 @@ void mq_msgfree(FAR struct mqueue_msg_s *mqmsg) * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfree); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfree); + leave_critical_section(flags); } /* If this is a message pre-allocated for interrupts, @@ -115,9 +96,9 @@ void mq_msgfree(FAR struct mqueue_msg_s *mqmsg) * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfreeirq); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfreeirq); + leave_critical_section(flags); } /* Otherwise, deallocate it. Note: interrupt handlers diff --git a/sched/mqueue/mq_msgqalloc.c b/sched/mqueue/mq_msgqalloc.c index 280f1f1821a6b56ffb1bbb2ec1fca9144947c261..5bdfee47a3086107b68bb8453305a8eb7395fda2 100644 --- a/sched/mqueue/mq_msgqalloc.c +++ b/sched/mqueue/mq_msgqalloc.c @@ -49,26 +49,6 @@ #include "sched/sched.h" #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -109,7 +89,7 @@ FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode, /* Allocate memory for the new message queue. */ - msgq = (FAR struct mqueue_inode_s*) + msgq = (FAR struct mqueue_inode_s *) kmm_zalloc(sizeof(struct mqueue_inode_s)); if (msgq) diff --git a/sched/mqueue/mq_msgqfree.c b/sched/mqueue/mq_msgqfree.c index 4d899fb3c9e194bb3de966ec9fb6f3fb9d7ffd7e..53e73aef1a01cef85eb191446c06173af9494aed 100644 --- a/sched/mqueue/mq_msgqfree.c +++ b/sched/mqueue/mq_msgqfree.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_msgqfree.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,31 +43,11 @@ #include #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_msgqfree * * Description: @@ -83,7 +63,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_msgqfree(FAR struct mqueue_inode_s *msgq) { @@ -92,7 +72,7 @@ void mq_msgqfree(FAR struct mqueue_inode_s *msgq) /* Deallocate any stranded messages in the message queue. */ - curr = (FAR struct mqueue_msg_s*)msgq->msglist.head; + curr = (FAR struct mqueue_msg_s *)msgq->msglist.head; while (curr) { /* Deallocate the message structure. */ diff --git a/sched/mqueue/mq_notify.c b/sched/mqueue/mq_notify.c index 81852513d7641bada225cefe7da7819246a78fc4..cc5ac36b52f775a77279fd863c5d3a24eafb55cc 100644 --- a/sched/mqueue/mq_notify.c +++ b/sched/mqueue/mq_notify.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_notify.c * - * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,17 +31,18 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include #include +#include #include #include @@ -49,31 +50,11 @@ #include "sched/sched.h" #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_notify * * Description: @@ -93,7 +74,7 @@ * Parameters: * mqdes - Message queue descriptor * notification - Real-time signal structure containing: - * sigev_notify - Should be SIGEV_SIGNAL (but actually ignored) + * sigev_notify - Should be SIGEV_SIGNAL or SIGEV_THREAD * sigev_signo - The signo to use for the notification * sigev_value - Value associated with the signal * @@ -124,12 +105,12 @@ * message shall satisfy mq_receive()... The resulting behavior is as if * the message queue remains empty, and no notification shall be sent." * - ************************************************************************/ + ****************************************************************************/ -int mq_notify(mqd_t mqdes, const struct sigevent *notification) +int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification) { - struct tcb_s *rtcb; - struct mqueue_inode_s *msgq; + FAR struct tcb_s *rtcb; + FAR struct mqueue_inode_s *msgq; int errval; /* Was a valid message queue descriptor provided? */ @@ -149,7 +130,7 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification) /* Get the current process ID */ - rtcb = (struct tcb_s*)g_readytorun.head; + rtcb = this_task(); /* Is there already a notification attached */ @@ -171,10 +152,11 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification) /* Yes... Assign it to the current task. */ - msgq->ntvalue.sival_ptr = notification->sigev_value.sival_ptr; - msgq->ntsigno = notification->sigev_signo; - msgq->ntpid = rtcb->pid; - msgq->ntmqdes = mqdes; + memcpy(&msgq->ntevent, ¬ification->sigev_value, + sizeof(struct sigevent)); + + msgq->ntpid = rtcb->pid; + msgq->ntmqdes = mqdes; } } @@ -197,10 +179,9 @@ int mq_notify(mqd_t mqdes, const struct sigevent *notification) * thread to detach the notification. */ - msgq->ntpid = INVALID_PROCESS_ID; - msgq->ntsigno = 0; - msgq->ntvalue.sival_ptr = NULL; - msgq->ntmqdes = NULL; + memset(&msgq->ntevent, 0, sizeof(struct sigevent)); + msgq->ntpid = INVALID_PROCESS_ID; + msgq->ntmqdes = NULL; } sched_unlock(); diff --git a/sched/mqueue/mq_rcvinternal.c b/sched/mqueue/mq_rcvinternal.c index 9c69dfe6427a848b905ae60cb0de51588c37188b..c260c1183dd1fb00006be5e5f32489c967901408 100644 --- a/sched/mqueue/mq_rcvinternal.c +++ b/sched/mqueue/mq_rcvinternal.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_rcvinternal.c * - * Copyright (C) 2007, 2008, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2012-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,31 +48,12 @@ #include #include +#include #include #include "sched/sched.h" #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -166,7 +147,7 @@ FAR struct mqueue_msg_s *mq_waitreceive(mqd_t mqdes) /* Get the message from the head of the queue */ - while ((rcvmsg = (FAR struct mqueue_msg_s*)sq_remfirst(&msgq->msglist)) == NULL) + while ((rcvmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&msgq->msglist)) == NULL) { /* The queue is empty! Should we block until there the above condition * has been satisfied? @@ -176,7 +157,7 @@ FAR struct mqueue_msg_s *mq_waitreceive(mqd_t mqdes) { /* Yes.. Block and try again */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); rtcb->msgwaitq = msgq; msgq->nwaitnotempty++; @@ -249,7 +230,7 @@ ssize_t mq_doreceive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR char *ubuffer, int *prio) { FAR struct tcb_s *btcb; - irqstate_t saved_state; + irqstate_t flags; FAR struct mqueue_inode_s *msgq; ssize_t rcvmsglen; @@ -259,7 +240,7 @@ ssize_t mq_doreceive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, /* Copy the message into the caller's buffer */ - memcpy(ubuffer, (const void*)mqmsg->mail, rcvmsglen); + memcpy(ubuffer, (FAR const void *)mqmsg->mail, rcvmsglen); /* Copy the message priority as well (if a buffer is provided) */ @@ -283,8 +264,8 @@ ssize_t mq_doreceive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, * messages can be sent from interrupt handlers. */ - saved_state = irqsave(); - for (btcb = (FAR struct tcb_s*)g_waitingformqnotfull.head; + flags = enter_critical_section(); + for (btcb = (FAR struct tcb_s *)g_waitingformqnotfull.head; btcb && btcb->msgwaitq != msgq; btcb = btcb->flink); @@ -299,7 +280,7 @@ ssize_t mq_doreceive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, msgq->nwaitnotfull--; up_unblock_task(btcb); - irqrestore(saved_state); + leave_critical_section(flags); } /* Return the length of the message transferred to the user buffer */ diff --git a/sched/mqueue/mq_receive.c b/sched/mqueue/mq_receive.c index 8468daebd68b2e8ce64bdb06b16063fdbb05fc1c..4fed3b5afd2cc96701162fd0df34fabe39629f40 100644 --- a/sched/mqueue/mq_receive.c +++ b/sched/mqueue/mq_receive.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_receive.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,35 +44,17 @@ #include #include #include + +#include #include #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_receive * * Description: @@ -110,13 +92,13 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ ssize_t mq_receive(mqd_t mqdes, FAR char *msg, size_t msglen, FAR int *prio) { FAR struct mqueue_msg_s *mqmsg; - irqstate_t saved_state; + irqstate_t flags; ssize_t ret = ERROR; DEBUGASSERT(up_interrupt_context() == false); @@ -143,12 +125,12 @@ ssize_t mq_receive(mqd_t mqdes, FAR char *msg, size_t msglen, * because messages can be sent from interrupt level. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Get the message from the message queue */ mqmsg = mq_waitreceive(mqdes); - irqrestore(saved_state); + leave_critical_section(flags); /* Check if we got a message from the message queue. We might * not have a message if: diff --git a/sched/mqueue/mq_recover.c b/sched/mqueue/mq_recover.c index 3e1ce7e307da39f081859c011f07451a02b0cd10..b9a09881ebe6f2e8ece5594b32fd95e4f1daf84e 100644 --- a/sched/mqueue/mq_recover.c +++ b/sched/mqueue/mq_recover.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_recover.c * * Copyright (C) 2012 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,31 +46,11 @@ #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_recover * * Description: @@ -87,7 +67,7 @@ * Assumptions: * This function is called from task deletion logic in a safe context. * - ************************************************************************/ + ****************************************************************************/ void mq_recover(FAR struct tcb_s *tcb) { diff --git a/sched/mqueue/mq_release.c b/sched/mqueue/mq_release.c index 42276d124b6a2832aba35f4ee9a105654e89c0f1..9f2fbfbbeb9909dcd8963d5689f5acb669e6fa1a 100644 --- a/sched/mqueue/mq_release.c +++ b/sched/mqueue/mq_release.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_release.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,31 +43,11 @@ #include "mqueue/mqueue.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: mq_release * * Description: @@ -81,7 +61,7 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void mq_release(FAR struct task_group_s *group) { diff --git a/sched/mqueue/mq_send.c b/sched/mqueue/mq_send.c index 457b26922dccf7bf34add50d6cb9e8b34574d14b..84c22b5d765867d65bd4062a04e5ea90b220cccf 100644 --- a/sched/mqueue/mq_send.c +++ b/sched/mqueue/mq_send.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_send.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,30 +44,11 @@ #include #include +#include #include #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -119,7 +100,7 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio) { FAR struct mqueue_inode_s *msgq; FAR struct mqueue_msg_s *mqmsg = NULL; - irqstate_t saved_state; + irqstate_t flags; int ret = ERROR; /* Verify the input parameters -- setting errno appropriately @@ -143,14 +124,14 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio) * non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT. */ - saved_state = irqsave(); + flags = enter_critical_section(); if (up_interrupt_context() || /* In an interrupt handler */ msgq->nmsgs < msgq->maxmsgs || /* OR Message queue not full */ mq_waitsend(mqdes) == OK) /* OR Successfully waited for mq not full */ { /* Allocate the message */ - irqrestore(saved_state); + leave_critical_section(flags); mqmsg = mq_msgalloc(); } else @@ -162,7 +143,7 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio) * - When we tried waiting, the wait was unsuccessful. */ - irqrestore(saved_state); + leave_critical_section(flags); } /* Check if we were able to get a message structure -- this can fail diff --git a/sched/mqueue/mq_setattr.c b/sched/mqueue/mq_setattr.c index 858621a15cfb29b26e6e25c8cb97d8dabc80a58f..71fe8df72874c3ebce9b4d39790e33b47684ead7 100644 --- a/sched/mqueue/mq_setattr.c +++ b/sched/mqueue/mq_setattr.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/mqueue/mq_setattr.c * * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,11 +44,11 @@ #include -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Function: mq_setattr * * Description: @@ -71,7 +71,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat, struct mq_attr *oldstat) diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c index d70c165d2c2df201708a0f6ce0037fcab73dee06..782eb84e33320308168ab58c7374b934dd91ad0d 100644 --- a/sched/mqueue/mq_sndinternal.c +++ b/sched/mqueue/mq_sndinternal.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_send.c * - * Copyright (C) 2007, 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,35 +48,18 @@ #include #include +#include #include #include #include +#include + #include "sched/sched.h" #ifndef CONFIG_DISABLE_SIGNALS # include "signal/signal.h" #endif #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -163,7 +146,7 @@ int mq_verifysend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio) FAR struct mqueue_msg_s *mq_msgalloc(void) { FAR struct mqueue_msg_s *mqmsg; - irqstate_t saved_state; + irqstate_t flags; /* If we were called from an interrupt handler, then try to get the message * from generally available list of messages. If this fails, then try the @@ -174,12 +157,12 @@ FAR struct mqueue_msg_s *mq_msgalloc(void) { /* Try the general free list */ - mqmsg = (FAR struct mqueue_msg_s*)sq_remfirst(&g_msgfree); + mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); if (!mqmsg) { /* Try the free list reserved for interrupt handlers */ - mqmsg = (FAR struct mqueue_msg_s*)sq_remfirst(&g_msgfreeirq); + mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfreeirq); } } @@ -191,9 +174,9 @@ FAR struct mqueue_msg_s *mq_msgalloc(void) * Disable interrupts -- we might be called from an interrupt handler. */ - saved_state = irqsave(); - mqmsg = (FAR struct mqueue_msg_s*)sq_remfirst(&g_msgfree); - irqrestore(saved_state); + flags = enter_critical_section(); + mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); + leave_critical_section(flags); /* If we cannot a message from the free list, then we will have to allocate one. */ @@ -278,7 +261,7 @@ int mq_waitsend(mqd_t mqdes) * When we are unblocked, we will try again */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); rtcb->msgwaitq = msgq; msgq->nwaitnotfull++; @@ -293,7 +276,7 @@ int mq_waitsend(mqd_t mqdes) if (get_errno() != OK) { - return ERROR; + return ERROR; } } } @@ -332,7 +315,7 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, FAR struct mqueue_inode_s *msgq; FAR struct mqueue_msg_s *next; FAR struct mqueue_msg_s *prev; - irqstate_t saved_state; + irqstate_t flags; /* Get a pointer to the message queue */ @@ -346,17 +329,17 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, /* Copy the message data into the message */ - memcpy((void*)mqmsg->mail, (FAR const void*)msg, msglen); + memcpy((FAR void *)mqmsg->mail, (FAR const void *)msg, msglen); /* Insert the new message in the message queue */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Search the message list to find the location to insert the new * message. Each is list is maintained in ascending priority order. */ - for (prev = NULL, next = (FAR struct mqueue_msg_s*)msgq->msglist.head; + for (prev = NULL, next = (FAR struct mqueue_msg_s *)msgq->msglist.head; next && prio <= next->priority; prev = next, next = next->next); @@ -364,18 +347,18 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, if (prev) { - sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)mqmsg, + sq_addafter((FAR sq_entry_t *)prev, (FAR sq_entry_t *)mqmsg, &msgq->msglist); } else { - sq_addfirst((FAR sq_entry_t*)mqmsg, &msgq->msglist); + sq_addfirst((FAR sq_entry_t *)mqmsg, &msgq->msglist); } /* Increment the count of messages in the queue */ msgq->nmsgs++; - irqrestore(saved_state); + leave_critical_section(flags); /* Check if we need to notify any tasks that are attached to the * message queue @@ -384,36 +367,50 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, #ifndef CONFIG_DISABLE_SIGNALS if (msgq->ntmqdes) { + struct sigevent event; + pid_t pid; + /* Remove the message notification data from the message queue. */ -#ifdef CONFIG_CAN_PASS_STRUCTS - union sigval value = msgq->ntvalue; -#else - void *sival_ptr = msgq->ntvalue.sival_ptr; -#endif - int signo = msgq->ntsigno; - int pid = msgq->ntpid; + memcpy(&event, &msgq->ntevent, sizeof(struct sigevent)); + pid = msgq->ntpid; /* Detach the notification */ - msgq->ntpid = INVALID_PROCESS_ID; - msgq->ntsigno = 0; - msgq->ntvalue.sival_int = 0; - msgq->ntmqdes = NULL; + memset(&msgq->ntevent, 0, sizeof(struct sigevent)); + msgq->ntpid = INVALID_PROCESS_ID; + msgq->ntmqdes = NULL; + + /* Notification the client via signal? */ - /* Queue the signal -- What if this returns an error? */ + if (event.sigev_notify == SIGEV_SIGNAL) + { + /* Yes... Queue the signal -- What if this returns an error? */ #ifdef CONFIG_CAN_PASS_STRUCTS - sig_mqnotempty(pid, signo, value); + DEBUGVERIFY(sig_mqnotempty(pid, event.sigev_signo, + event.sigev_value)); #else - sig_mqnotempty(pid, signo, sival_ptr); + DEBUGVERIFY(sig_mqnotempty(pid, event.sigev_signo, + event.sigev_value.sival_ptr)); #endif + } + +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ + + else if (event.sigev_notify == SIGEV_THREAD) + { + DEBUGVERIFY(sig_notification(pid, &event)); + } +#endif + } #endif /* Check if any tasks are waiting for the MQ not empty event. */ - saved_state = irqsave(); + flags = enter_critical_section(); if (msgq->nwaitnotempty > 0) { /* Find the highest priority task that is waiting for @@ -422,7 +419,7 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, * interrupts should never cause a change in this list */ - for (btcb = (FAR struct tcb_s*)g_waitingformqnotempty.head; + for (btcb = (FAR struct tcb_s *)g_waitingformqnotempty.head; btcb && btcb->msgwaitq != msgq; btcb = btcb->flink); @@ -435,7 +432,7 @@ int mq_dosend(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, FAR const char *msg, up_unblock_task(btcb); } - irqrestore(saved_state); + leave_critical_section(flags); sched_unlock(); return OK; } diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c index eb1822f7e4fcddabe73c25cbb6d7ce7b295154e0..b5bb100b89a0ddc0fb80fe02d2c1db9b7e5ef0ec 100644 --- a/sched/mqueue/mq_timedreceive.c +++ b/sched/mqueue/mq_timedreceive.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_timedreceive.c * - * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -54,22 +55,6 @@ #include "clock/clock.h" #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -95,13 +80,13 @@ static void mq_rcvtimeout(int argc, wdparm_t pid) { FAR struct tcb_s *wtcb; - irqstate_t saved_state; + irqstate_t flags; /* Disable interrupts. This is necessary because an interrupt handler may * attempt to send a message while we are doing this. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Get the TCB associated with this pid. It is possible that task may no * longer be active when this watchdog goes off. @@ -122,7 +107,7 @@ static void mq_rcvtimeout(int argc, wdparm_t pid) /* Interrupts may now be re-enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } /**************************************************************************** @@ -182,9 +167,9 @@ static void mq_rcvtimeout(int argc, wdparm_t pid) ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen, FAR int *prio, FAR const struct timespec *abstime) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct mqueue_msg_s *mqmsg; - irqstate_t saved_state; + irqstate_t flags; int ret = ERROR; DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL); @@ -229,7 +214,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen, * because messages can be sent from interrupt level. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Check if the message queue is empty. If it is NOT empty, then we * will not need to start timer. @@ -258,7 +243,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen, if (result != OK) { - irqrestore(saved_state); + leave_critical_section(flags); sched_unlock(); wd_delete(rtcb->waitdog); @@ -285,7 +270,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen, /* We can now restore interrupts */ - irqrestore(saved_state); + leave_critical_section(flags); /* Check if we got a message from the message queue. We might * not have a message if: diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index 929a5bc610435ddb3080fbc338499eed8ef56386..860e6223db893d404ba0f71af4276fe0ea488c2f 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_timedsend.c * - * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -54,22 +55,6 @@ #include "sched/sched.h" #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -95,13 +80,13 @@ static void mq_sndtimeout(int argc, wdparm_t pid) { FAR struct tcb_s *wtcb; - irqstate_t saved_state; + irqstate_t flags; /* Disable interrupts. This is necessary because an interrupt handler may * attempt to send a message while we are doing this. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Get the TCB associated with this pid. It is possible that task may no * longer be active when this watchdog goes off. @@ -122,7 +107,7 @@ static void mq_sndtimeout(int argc, wdparm_t pid) /* Interrupts may now be re-enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } /**************************************************************************** @@ -183,10 +168,10 @@ static void mq_sndtimeout(int argc, wdparm_t pid) int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, FAR const struct timespec *abstime) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct mqueue_inode_s *msgq; FAR struct mqueue_msg_s *mqmsg = NULL; - irqstate_t saved_state; + irqstate_t flags; int ticks; int result; int ret = ERROR; @@ -274,7 +259,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, * disabled here so that this time stays valid until the wait begins. */ - saved_state = irqsave(); + flags = enter_critical_section(); result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks); /* If the time has already expired and the message queue is empty, @@ -290,7 +275,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, if (result != OK) { - goto errout_with_irqsave; + goto errout_in_critical_section; } /* Start the watchdog and begin the wait for MQ not full */ @@ -314,12 +299,12 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, /* mq_waitsend() will set the errno, but the error exit will reset it */ result = get_errno(); - goto errout_with_irqsave; + goto errout_in_critical_section; } /* That is the end of the atomic operations */ - irqrestore(saved_state); + leave_critical_section(flags); /* If any of the above failed, set the errno. Otherwise, there should * be space for another message in the message queue. NOW we can allocate @@ -340,8 +325,8 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, * 'result' */ -errout_with_irqsave: - irqrestore(saved_state); +errout_in_critical_section: + leave_critical_section(flags); wd_delete(rtcb->waitdog); rtcb->waitdog = NULL; diff --git a/sched/mqueue/mq_waitirq.c b/sched/mqueue/mq_waitirq.c index e22f67d2bb3f140ecc75c8f9f07c78f9aff0acca..10dada1af498eb044dff41b38096403162f9e236 100644 --- a/sched/mqueue/mq_waitirq.c +++ b/sched/mqueue/mq_waitirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/mqueue/mq_waitirq.c * - * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,31 +42,12 @@ #include #include +#include #include #include #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -93,13 +74,13 @@ void mq_waitirq(FAR struct tcb_s *wtcb, int errcode) { FAR struct mqueue_inode_s *msgq; - irqstate_t saved_state; + irqstate_t flags; /* Disable interrupts. This is necessary because an interrupt handler may * attempt to send a message while we are doing this. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* It is possible that an interrupt/context switch beat us to the punch and * already changed the task's state. NOTE: The operations within the if @@ -141,5 +122,5 @@ void mq_waitirq(FAR struct tcb_s *wtcb, int errcode) /* Interrupts may now be enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } diff --git a/sched/mqueue/mqueue.h b/sched/mqueue/mqueue.h index bd771e140e9fe96bd2ab882acb55e6b7fa890aa1..170fcd7a56a71db01693f799172fa1bc6c622d0e 100644 --- a/sched/mqueue/mqueue.h +++ b/sched/mqueue/mqueue.h @@ -102,7 +102,7 @@ struct mqueue_msg_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef __cplusplus diff --git a/sched/paging/paging.h b/sched/paging/paging.h index e25bd782b8d962c8b86f251d160ff64a4a06023e..cccda6e4ed94efefe8c3283fba98f1121bd0f02d 100644 --- a/sched/paging/paging.h +++ b/sched/paging/paging.h @@ -71,10 +71,6 @@ # warning "Page fill support requires signals" #endif -/**************************************************************************** - * Public Types - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/sched/paging/pg_miss.c b/sched/paging/pg_miss.c index 21717231a6044cc1ff92bb4dd66a63df35f34506..945678f99a98b11c7f8a4c01dc6999a441e39cdd 100644 --- a/sched/paging/pg_miss.c +++ b/sched/paging/pg_miss.c @@ -52,7 +52,7 @@ #include "paging/paging.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -121,7 +121,7 @@ void pg_miss(void) { - FAR struct tcb_s *ftcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *ftcb = this_task(); FAR struct tcb_s *wtcb; /* Sanity checking diff --git a/sched/paging/pg_worker.c b/sched/paging/pg_worker.c index 1ccc123d30156900cd1c2474bfb394ec19902be1..08c94fd17c7f32fba45cf156e53dd4526c7e0bf9 100644 --- a/sched/paging/pg_worker.c +++ b/sched/paging/pg_worker.c @@ -68,11 +68,7 @@ #endif /**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ /* This is the task ID of the page fill worker thread. This value was set in @@ -94,7 +90,7 @@ pid_t g_pgworker; FAR struct tcb_s *g_pftcb; /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ #ifndef CONFIG_PAGING_BLOCKINGFILL @@ -110,7 +106,7 @@ static int g_fillresult; */ #ifdef CONFIG_PAGING_TIMEOUT_TICKS -status uint32_t g_starttime; +static systime_t g_starttime; #endif #endif @@ -249,7 +245,7 @@ static inline bool pg_dequeue(void) { /* Remove the TCB from the head of the list (if any) */ - g_pftcb = (FAR struct tcb_s *)dq_remfirst((dq_queue_t*)&g_waitingforfill); + g_pftcb = (FAR struct tcb_s *)dq_remfirst((dq_queue_t *)&g_waitingforfill); pgllvdbg("g_pftcb: %p\n", g_pftcb); if (g_pftcb != NULL) { @@ -279,7 +275,7 @@ static inline bool pg_dequeue(void) * if a new higher priority fill is required). */ - FAR struct tcb_s *wtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *wtcb = this_task(); if (wtcb->sched_priority > CONFIG_PAGING_DEFPRIO && wtcb->sched_priority > g_pftcb->sched_priority) { @@ -456,7 +452,7 @@ static inline bool pg_startfill(void) static inline void pg_alldone(void) { - FAR struct tcb_s *wtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *wtcb = this_task(); g_pftcb = NULL; pgllvdbg("New worker priority. %d->%d\n", wtcb->sched_priority, CONFIG_PAGING_DEFPRIO); @@ -537,8 +533,8 @@ int pg_worker(int argc, char *argv[]) */ pglldbg("Started\n"); - (void)irqsave(); - for (;;) + (void)up_irq_save(); + for (; ; ) { /* Wait awhile. We will wait here until either the configurable timeout * elapses or until we are awakened by a signal (which terminates the @@ -585,7 +581,7 @@ int pg_worker(int argc, char *argv[]) */ pglldbg("Restarting TCB: %p\n", g_pftcb); - up_unblock_task(g_pftcb);; + up_unblock_task(g_pftcb); /* Yes .. Start the next asynchronous fill. Check the return * value to see a fill was actually started (false means that @@ -638,7 +634,7 @@ int pg_worker(int argc, char *argv[]) * pending fills have been processed. */ - for (;;) + for (; ; ) { /* Yes .. Start the fill and block until the fill completes. * Check the return value to see a fill was actually performed. @@ -648,9 +644,9 @@ int pg_worker(int argc, char *argv[]) pgllvdbg("Calling pg_startfill\n"); if (!pg_startfill()) { - /* Break out of the loop -- there is nothing more to do */ + /* Break out of the loop -- there is nothing more to do */ - break; + break; } /* Handle the page fill complete event by restarting the @@ -661,7 +657,7 @@ int pg_worker(int argc, char *argv[]) */ pgllvdbg("Restarting TCB: %p\n", g_pftcb); - up_unblock_task(g_pftcb);; + up_unblock_task(g_pftcb); } /* All queued fills have been processed */ diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index 89272b14b23d44e5ab224fcfd3c49a8e4b3143d9..d27938aa379220439ef47a96ad3da91c62ebd032 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # sched/pthread/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -51,6 +51,10 @@ ifneq ($(CONFIG_DISABLE_SIGNALS),y) CSRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c endif +ifeq ($(CONFIG_SMP),y) +CSRCS += pthread_setaffinity.c pthread_getaffinity.c +endif + # Include pthread build support DEPPATH += --dep-path pthread diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index a436bd090c2ef5654f72fd65724c35e5dd621113..6371e9df330984f9312d0b6727823ac13c6567c1 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -50,10 +50,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Public Type Declarations ****************************************************************************/ @@ -79,7 +75,7 @@ struct join_s }; /**************************************************************************** - * Public Variables + * Public Data ****************************************************************************/ #ifdef __cplusplus diff --git a/sched/pthread/pthread_barrierdestroy.c b/sched/pthread/pthread_barrierdestroy.c index b2535b0e41d1bd8d983d3ab12028d4aea07a7669..dbad57947a084be9314b11f405043fadc841da9e 100644 --- a/sched/pthread/pthread_barrierdestroy.c +++ b/sched/pthread/pthread_barrierdestroy.c @@ -44,26 +44,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/pthread/pthread_barrierinit.c b/sched/pthread/pthread_barrierinit.c index 4185d71807ed0b31ed5add73b5cdebae1931c5f9..adaca2876c2c25a668ef96cca77b6ed07182c107 100644 --- a/sched/pthread/pthread_barrierinit.c +++ b/sched/pthread/pthread_barrierinit.c @@ -44,26 +44,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/pthread/pthread_barrierwait.c b/sched/pthread/pthread_barrierwait.c index 7d0126eebe342542130210e395d19732fba0f25e..2d5a306df0aee5024aa5d8bd881066e0fd58e9fa 100644 --- a/sched/pthread/pthread_barrierwait.c +++ b/sched/pthread/pthread_barrierwait.c @@ -45,26 +45,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c index d8694eb5194d9baeeb1a53c207ff2a88802dd394..a8ba2ee4c9352290f8db65a24032a4ce16fca394 100644 --- a/sched/pthread/pthread_cancel.c +++ b/sched/pthread/pthread_cancel.c @@ -1,4 +1,4 @@ -/************************************************************************** +/**************************************************************************** * sched/pthread/pthread_cancel.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - **************************************************************************/ + ****************************************************************************/ -/************************************************************************** +/**************************************************************************** * Included Files - **************************************************************************/ + ****************************************************************************/ #include @@ -47,37 +47,13 @@ #include "sched/sched.h" #include "pthread/pthread.h" -/************************************************************************** - * Pre-processor Definitions - **************************************************************************/ - -/************************************************************************** - * Private Types - **************************************************************************/ - -/************************************************************************** - * Private Function Prototypes - **************************************************************************/ - -/************************************************************************** - * Global Variables - **************************************************************************/ - -/************************************************************************** - * Private Variables - **************************************************************************/ - -/************************************************************************** - * Private Functions - **************************************************************************/ - -/************************************************************************** +/**************************************************************************** * Public Functions - **************************************************************************/ + ****************************************************************************/ int pthread_cancel(pthread_t thread) { - struct tcb_s *tcb; + FAR struct tcb_s *tcb; /* First, make sure that the handle references a valid thread */ @@ -132,7 +108,7 @@ int pthread_cancel(pthread_t thread) * same as pthread_exit(PTHREAD_CANCELED). */ - if (tcb == (struct tcb_s*)g_readytorun.head) + if (tcb == this_task()) { pthread_exit(PTHREAD_CANCELED); } diff --git a/sched/pthread/pthread_completejoin.c b/sched/pthread/pthread_completejoin.c index 0546edf5b542ce56a054ed4fd17a063055de2c3c..2d9f3530e5987ac3a4bab672b1a42b53a4a85447 100644 --- a/sched/pthread/pthread_completejoin.c +++ b/sched/pthread/pthread_completejoin.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_completejoin.c * * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -49,27 +49,11 @@ #include "group/group.h" #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_notifywaiters * * Description: @@ -77,7 +61,7 @@ * exit data. This must be done by the child at child thread * destruction time. * - ************************************************************************/ + ****************************************************************************/ static bool pthread_notifywaiters(FAR struct join_s *pjoin) { @@ -122,7 +106,7 @@ static bool pthread_notifywaiters(FAR struct join_s *pjoin) return false; } -/************************************************************************ +/**************************************************************************** * Name: pthread_removejoininfo * * Description: @@ -137,7 +121,7 @@ static bool pthread_notifywaiters(FAR struct join_s *pjoin) * Assumptions: * The caller has provided protection from re-entrancy. * - ************************************************************************/ + ****************************************************************************/ static void pthread_removejoininfo(FAR struct task_group_s *group, pid_t pid) @@ -192,11 +176,11 @@ static void pthread_removejoininfo(FAR struct task_group_s *group, } } -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_completejoin * * Description: @@ -214,7 +198,7 @@ static void pthread_removejoininfo(FAR struct task_group_s *group, * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int pthread_completejoin(pid_t pid, FAR void *exit_value) { @@ -268,7 +252,7 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value) return OK; } -/************************************************************************ +/**************************************************************************** * Name: pthread_destroyjoin * * Description: @@ -282,7 +266,7 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value) * Assumptions: * The caller holds tg_joinsem * - ************************************************************************/ + ****************************************************************************/ void pthread_destroyjoin(FAR struct task_group_s *group, FAR struct join_s *pjoin) diff --git a/sched/pthread/pthread_condbroadcast.c b/sched/pthread/pthread_condbroadcast.c index 2983fb2e9e1c16cf69f14b2030f3aee66a842f6d..a86c3a8a14681e9abcc99e603a0c943387fd86c8 100644 --- a/sched/pthread/pthread_condbroadcast.c +++ b/sched/pthread/pthread_condbroadcast.c @@ -46,26 +46,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,7 +88,7 @@ int pthread_cond_broadcast(FAR pthread_cond_t *cond) /* Get the current value of the semaphore */ - if (sem_getvalue((sem_t*)&cond->sem, &sval) != OK) + if (sem_getvalue((FAR sem_t *)&cond->sem, &sval) != OK) { ret = EINVAL; } @@ -123,7 +103,7 @@ int pthread_cond_broadcast(FAR pthread_cond_t *cond) * Only the highest priority waiting thread will get to execute */ - ret = pthread_givesemaphore((sem_t*)&cond->sem); + ret = pthread_givesemaphore((FAR sem_t *)&cond->sem); /* Increment the semaphore count (as was done by the * above post). diff --git a/sched/pthread/pthread_conddestroy.c b/sched/pthread/pthread_conddestroy.c index 1b144be7283009721f6b3a4fef7c9ef2136c5db4..2584e8dbaee298d9f5d76223f510df0a3804ce6f 100644 --- a/sched/pthread/pthread_conddestroy.c +++ b/sched/pthread/pthread_conddestroy.c @@ -45,7 +45,7 @@ #include "pthread/pthread.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -75,9 +75,9 @@ int pthread_cond_destroy(FAR pthread_cond_t *cond) ret = EINVAL; } - /* Destroy the semaphore contained in the structure */ + /* Destroy the semaphore contained in the structure */ - else if (sem_destroy((sem_t*)&cond->sem) != OK) + else if (sem_destroy((FAR sem_t *)&cond->sem) != OK) { ret = EINVAL; } diff --git a/sched/pthread/pthread_condinit.c b/sched/pthread/pthread_condinit.c index ce7c1acbf2038a2e280c35137d07f7b6b9e0bf92..a73811e0782ac1e0580d1977d032d46226e157cb 100644 --- a/sched/pthread/pthread_condinit.c +++ b/sched/pthread/pthread_condinit.c @@ -46,7 +46,7 @@ #include "pthread/pthread.h" /**************************************************************************** - * Global Functions + * Public Functions ****************************************************************************/ /**************************************************************************** @@ -80,7 +80,7 @@ int pthread_cond_init(FAR pthread_cond_t *cond, FAR const pthread_condattr_t *at * with initial count = 0 */ - else if (sem_init((sem_t*)&cond->sem, 0, 0) != OK) + else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK) { ret = EINVAL; } diff --git a/sched/pthread/pthread_condsignal.c b/sched/pthread/pthread_condsignal.c index c798f0d2c165d8302c7dc40289ca78357ba917a5..b84ef5d55ca8368952032b03d29597157d1122de 100644 --- a/sched/pthread/pthread_condsignal.c +++ b/sched/pthread/pthread_condsignal.c @@ -45,26 +45,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -100,7 +80,7 @@ int pthread_cond_signal(FAR pthread_cond_t *cond) { /* Get the current value of the semaphore */ - if (sem_getvalue((sem_t*)&cond->sem, &sval) != OK) + if (sem_getvalue((FAR sem_t *)&cond->sem, &sval) != OK) { ret = EINVAL; } @@ -125,7 +105,7 @@ int pthread_cond_signal(FAR pthread_cond_t *cond) if (sval < 0) { sdbg("Signalling...\n"); - ret = pthread_givesemaphore((sem_t*)&cond->sem); + ret = pthread_givesemaphore((FAR sem_t *)&cond->sem); } } } diff --git a/sched/pthread/pthread_condtimedwait.c b/sched/pthread/pthread_condtimedwait.c index b9d266a763d2766b31036df37ca20417378242a9..0e8443b2fb160316a10ef0f5dad0252b9d16082d 100644 --- a/sched/pthread/pthread_condtimedwait.c +++ b/sched/pthread/pthread_condtimedwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_condtimedwait.c * - * Copyright (C) 2007-2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #include #include "sched/sched.h" @@ -56,22 +57,6 @@ #include "clock/clock.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -119,6 +104,7 @@ static void pthread_condtimedout(int argc, uint32_t pid, uint32_t signo) info.si_signo = signo; info.si_code = SI_QUEUE; + info.si_errno = ETIMEDOUT; info.si_value.sival_ptr = NULL; #ifdef CONFIG_SCHED_HAVE_PARENT info.si_pid = (pid_t)pid; @@ -181,10 +167,10 @@ static void pthread_condtimedout(int argc, uint32_t pid, uint32_t signo) int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, FAR const struct timespec *abstime) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); int ticks; int mypid = (int)getpid(); - irqstate_t int_state; + irqstate_t flags; int ret = OK; int status; @@ -235,7 +221,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, */ sched_lock(); - int_state = irqsave(); + flags = enter_critical_section(); /* Convert the timespec to clock ticks. We must disable pre-emption * here so that this time stays valid until the wait begins. @@ -248,7 +234,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, * we fall through the if/then/else */ - irqrestore(int_state); + leave_critical_section(flags); } else { @@ -263,7 +249,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, * if/then/else */ - irqrestore(int_state); + leave_critical_section(flags); ret = ETIMEDOUT; } else @@ -271,14 +257,14 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, /* Give up the mutex */ mutex->pid = -1; - ret = pthread_givesemaphore((sem_t*)&mutex->sem); + ret = pthread_givesemaphore((FAR sem_t *)&mutex->sem); if (ret) { /* Restore interrupts (pre-emption will be enabled when * we fall through the if/then/else) */ - irqrestore(int_state); + leave_critical_section(flags); } else { @@ -293,7 +279,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, * are started atomically. */ - status = sem_wait((sem_t*)&cond->sem); + status = sem_wait((FAR sem_t *)&cond->sem); /* Did we get the condition semaphore. */ @@ -321,13 +307,13 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, * handling! (bad) */ - irqrestore(int_state); + leave_critical_section(flags); } /* Reacquire the mutex (retaining the ret). */ sdbg("Re-locking...\n"); - status = pthread_takesemaphore((sem_t*)&mutex->sem); + status = pthread_takesemaphore((FAR sem_t *)&mutex->sem); if (!status) { mutex->pid = mypid; diff --git a/sched/pthread/pthread_condwait.c b/sched/pthread/pthread_condwait.c index 7460510a14dfe0bd0a7fef7e01b99e3d7356f83b..d60aece8ef8071097e12740577eacb7dac4db260 100644 --- a/sched/pthread/pthread_condwait.c +++ b/sched/pthread/pthread_condwait.c @@ -47,26 +47,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -114,17 +94,17 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) sched_lock(); mutex->pid = -1; - ret = pthread_givesemaphore((sem_t*)&mutex->sem); + ret = pthread_givesemaphore((FAR sem_t *)&mutex->sem); /* Take the semaphore */ - ret |= pthread_takesemaphore((sem_t*)&cond->sem); + ret |= pthread_takesemaphore((FAR sem_t *)&cond->sem); sched_unlock(); /* Reacquire the mutex */ sdbg("Reacquire mutex...\n"); - ret |= pthread_takesemaphore((sem_t*)&mutex->sem); + ret |= pthread_takesemaphore((FAR sem_t *)&mutex->sem); if (!ret) { mutex->pid = getpid(); diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index b5df6364c70a714c94b83d6ecec8689657c8e5e9..0869c56ed895481bc6ebdb6fb8c675aa07ee5061 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_create.c * - * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -165,9 +165,9 @@ static inline void pthread_addjoininfo(FAR struct task_group_s *group, static void pthread_start(void) { - FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s *)this_task(); FAR struct task_group_s *group = ptcb->cmn.group; - FAR struct join_s *pjoin = (FAR struct join_s*)ptcb->joininfo; + FAR struct join_s *pjoin = (FAR struct join_s *)ptcb->joininfo; pthread_addr_t exit_status; DEBUGASSERT(group && pjoin); @@ -269,8 +269,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, #ifdef CONFIG_ARCH_ADDRENV /* Share the address environment of the parent task group. */ - ret = up_addrenv_attach(ptcb->cmn.group, - (FAR struct tcb_s *)g_readytorun.head); + ret = up_addrenv_attach(ptcb->cmn.group, this_task()); if (ret < 0) { errcode = -ret; @@ -280,7 +279,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, /* Allocate a detachable structure to support pthread_join logic */ - pjoin = (FAR struct join_s*)kmm_zalloc(sizeof(struct join_s)); + pjoin = (FAR struct join_s *)kmm_zalloc(sizeof(struct join_s)); if (!pjoin) { sdbg("ERROR: Failed to allocate join\n"); @@ -405,6 +404,20 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, goto errout_with_join; } +#ifdef CONFIG_SMP + /* pthread_schedsetup() will set the affinity mask by inheriting the + * setting from the parent task. We need to override this setting + * with the value from the pthread attributes unless that value is + * zero: Zero is the default value and simply means to inherit the + * parent thread's affinity mask. + */ + + if (attr->affinity != 0) + { + ptcb->cmn.affinity = attr->affinity; + } +#endif + /* Configure the TCB for a pthread receiving on parameter * passed by value */ @@ -430,7 +443,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, /* Set the appropriate scheduling policy in the TCB */ - ptcb->cmn.flags &= TCB_FLAG_POLICY_MASK; + ptcb->cmn.flags &= ~TCB_FLAG_POLICY_MASK; switch (policy) { default: @@ -509,7 +522,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, else { sched_unlock(); - dq_rem((FAR dq_entry_t*)ptcb, (dq_queue_t*)&g_inactivetasks); + dq_rem((FAR dq_entry_t *)ptcb, (FAR dq_queue_t *)&g_inactivetasks); (void)sem_destroy(&pjoin->data_sem); (void)sem_destroy(&pjoin->exit_sem); diff --git a/sched/pthread/pthread_detach.c b/sched/pthread/pthread_detach.c index 450ff76a531d40bec8b62b40a149912f0424093b..6bc3585b487dbfddbfd531558882b268460e8091 100644 --- a/sched/pthread/pthread_detach.c +++ b/sched/pthread/pthread_detach.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_detach.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,31 +50,11 @@ #include "group/group.h" #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_detach * * Description: @@ -93,11 +73,11 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int pthread_detach(pthread_t thread) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; FAR struct join_s *pjoin; int ret; diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index 133cc52151d2bebcf1ae9843b5ec02f9e5038300..d742ef8fdd68e118f7beed9faf5beda44f08419b 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_exit.c * * Copyright (C) 2007, 2009, 2011-2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -53,31 +53,11 @@ #include "task/task.h" #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_exit * * Description: @@ -91,11 +71,11 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ void pthread_exit(FAR void *exit_value) { - struct tcb_s *tcb = (struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); int status; sdbg("exit_value=%p\n", exit_value); diff --git a/sched/pthread/pthread_findjoininfo.c b/sched/pthread/pthread_findjoininfo.c index df5c82b0336aa18e93c3392ac76c9a97ba9e8076..60769bc16dd91de7ece6cacfc74e8bbce559906a 100644 --- a/sched/pthread/pthread_findjoininfo.c +++ b/sched/pthread/pthread_findjoininfo.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * pthread_findjoininfo.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,31 +44,11 @@ #include "group/group.h" #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: thread_findjoininfo * * Description: @@ -84,7 +64,7 @@ * Assumptions: * The caller has provided protection from re-entrancy. * - ************************************************************************/ + ****************************************************************************/ FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group, pid_t pid) diff --git a/sched/pthread/pthread_getaffinity.c b/sched/pthread/pthread_getaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..04d19219105bb7c85996f95ba94f1b6cb0cdf8bd --- /dev/null +++ b/sched/pthread/pthread_getaffinity.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * pthread_getaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "pthread/pthread.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_getschedparam + * + * Description: + * The pthread_getaffinity_np() function returns the CPU affinity mask + * of the thread thread in the buffer pointed to by cpuset. + * + * The argument cpusetsize is the length (in bytes) of the buffer + * pointed to by cpuset. Typically, this argument would be specified as + * sizeof(cpu_set_t). + * + * Parameters: + * thread - The ID of thread whose affinity set will be retrieved. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - The location to return the thread's new affinity set. + * + * Return Value: + * 0 if successful. Otherwise, an errno value is returned indicating the + * nature of the failure. + * + ****************************************************************************/ + +int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, + FAR cpu_set_t *cpuset) +{ + int ret; + + sdbg("thread ID=%d cpusetsize=%d cpuset=%p\n", + (int)thread, (int)cpusetsize, cpusetsize); + + DEBUGASSERT(thread > 0 && cpusetsize == sizeof(cpu_set_t) && + cpuset != NULL); + + /* Let sched_getaffinity do all of the work */ + + ret = sched_getaffinity((pid_t)thread, cpusetsize, cpuset); + if (ret < 0) + { + /* If sched_getaffinity() fails, return the errno */ + + ret = get_errno(); + DEBUGASSERT(ret > 0); + } + + return ret; +} + +#endif /* CONFIG_SMP */ diff --git a/sched/pthread/pthread_getschedparam.c b/sched/pthread/pthread_getschedparam.c index 984902704cefecb35045fb0ba11673b19a3a6eca..fbb1be26b0a256bc6ba6186696850ee55a6109dd 100644 --- a/sched/pthread/pthread_getschedparam.c +++ b/sched/pthread/pthread_getschedparam.c @@ -44,29 +44,9 @@ #include #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: pthread_getschedparam @@ -89,7 +69,7 @@ * (SCHED_OTHER and SCHED_SPORADIC, in particular, are not supported). * The SCHED_FIFO and SCHED_RR policies will have a single scheduling * parameter, sched_priority. -* + * * Parameters: * thread - The ID of thread whose scheduling parameters will be queried. * policy - The location to store the thread's scheduling policy. diff --git a/sched/pthread/pthread_getspecific.c b/sched/pthread/pthread_getspecific.c index c616fb764f9daec33e8f77aa68809a3ac20c8b13..7ba16a9541438de5e2080e90553cd196062ab8ec 100644 --- a/sched/pthread/pthread_getspecific.c +++ b/sched/pthread/pthread_getspecific.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_getspecific.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -47,31 +47,11 @@ #include "sched/sched.h" #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_getspecific * * Description: @@ -99,12 +79,12 @@ * may be called from a thread-specific data destructor * function. * - ************************************************************************/ + ****************************************************************************/ FAR void *pthread_getspecific(pthread_key_t key) { #if CONFIG_NPTHREAD_KEYS > 0 - FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task(); FAR struct task_group_s *group = rtcb->cmn.group; FAR void *ret = NULL; diff --git a/sched/pthread/pthread_initialize.c b/sched/pthread/pthread_initialize.c index e946220b7b4e60ac7b7ab9a6529a3055d14ed597..0ced8d61819b3ef9b350c9b3795ec9c31f83e3fd 100644 --- a/sched/pthread/pthread_initialize.c +++ b/sched/pthread/pthread_initialize.c @@ -45,26 +45,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/pthread/pthread_join.c b/sched/pthread/pthread_join.c index 43843deed07213aeb47f9dc72cbd4fad09992e07..9bb9fa3fa0dde5f610e16d16e497b45d313b3458 100644 --- a/sched/pthread/pthread_join.c +++ b/sched/pthread/pthread_join.c @@ -47,26 +47,6 @@ #include "group/group.h" #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -102,7 +82,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; FAR struct join_s *pjoin; int ret; diff --git a/sched/pthread/pthread_keycreate.c b/sched/pthread/pthread_keycreate.c index 9e4dccdc25eb85f0d638250737520e12d6423dcf..60be2fb5e32de1a1f5687f8d84255e5ba692a59b 100644 --- a/sched/pthread/pthread_keycreate.c +++ b/sched/pthread/pthread_keycreate.c @@ -47,26 +47,6 @@ #include "sched/sched.h" #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,10 +88,11 @@ * ****************************************************************************/ -int pthread_key_create(FAR pthread_key_t *key, CODE void (*destructor)(void*)) +int pthread_key_create(FAR pthread_key_t *key, + CODE void (*destructor)(FAR void *)) { #if CONFIG_NPTHREAD_KEYS > 0 - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; int ret = EAGAIN; diff --git a/sched/pthread/pthread_keydelete.c b/sched/pthread/pthread_keydelete.c index ff1fba7bffd323c3e63f451a3748cfaf43d03910..57cd46309a411c9c1cf4e41b11bf061d749cf9b6 100644 --- a/sched/pthread/pthread_keydelete.c +++ b/sched/pthread/pthread_keydelete.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_keydelete.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,31 +45,11 @@ #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_key_delete * * Description: @@ -87,7 +67,7 @@ * * POSIX Compatibility: * - ************************************************************************/ + ****************************************************************************/ int pthread_key_delete(pthread_key_t key) { diff --git a/sched/pthread/pthread_kill.c b/sched/pthread/pthread_kill.c index 7c9609a4d6c327c3417af51f490964ab4e4278f8..a53842308af7adf18961ae1f2f08e6c023bf8f0e 100644 --- a/sched/pthread/pthread_kill.c +++ b/sched/pthread/pthread_kill.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_kill.c * * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,11 +50,11 @@ #include "sched/sched.h" #include "signal/signal.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_kill * * Description: @@ -81,7 +81,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int pthread_kill(pthread_t thread, int signo) { @@ -94,7 +94,7 @@ int pthread_kill(pthread_t thread, int signo) */ #ifdef CONFIG_SCHED_HAVE_PARENT - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #endif FAR struct tcb_s *stcb; siginfo_t info; @@ -116,6 +116,7 @@ int pthread_kill(pthread_t thread, int signo) info.si_signo = signo; info.si_code = SI_USER; + info.si_errno = EINTR; info.si_value.sival_ptr = NULL; #ifdef CONFIG_SCHED_HAVE_PARENT info.si_pid = rtcb->pid; diff --git a/sched/pthread/pthread_mutexdestroy.c b/sched/pthread/pthread_mutexdestroy.c index 3f768e1458fba374301b5b1da5981837f6f5e2eb..d7d5e7c898ad67df811c8f5bd8b31e12bf741bd9 100644 --- a/sched/pthread/pthread_mutexdestroy.c +++ b/sched/pthread/pthread_mutexdestroy.c @@ -47,26 +47,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -116,7 +96,7 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) { /* Destroy the semaphore */ - status = sem_destroy((sem_t*)&mutex->sem); + status = sem_destroy((FAR sem_t *)&mutex->sem); if (status != OK) { ret = EINVAL; diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index 0236830a060edc1f1beebb4bb4f96e06fbb9e300..c4355d41bd949ebcfc8c569aa48d1dc7ef6e7bcd 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -46,26 +46,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -119,7 +99,7 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t /* Initialize the mutex like a semaphore with initial count = 1 */ - status = sem_init((sem_t*)&mutex->sem, pshared, 1); + status = sem_init((FAR sem_t *)&mutex->sem, pshared, 1); if (status != OK) { ret = EINVAL; diff --git a/sched/pthread/pthread_mutexlock.c b/sched/pthread/pthread_mutexlock.c index dad492c8140cc41a1f5ab3ec03c7e3d402caa711..85e16adc473f71322898e9488f4c457d9138b205 100644 --- a/sched/pthread/pthread_mutexlock.c +++ b/sched/pthread/pthread_mutexlock.c @@ -47,26 +47,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -168,7 +148,7 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex) { /* Take the semaphore */ - ret = pthread_takesemaphore((sem_t*)&mutex->sem); + ret = pthread_takesemaphore((FAR sem_t *)&mutex->sem); /* If we succussfully obtained the semaphore, then indicate * that we own it. diff --git a/sched/pthread/pthread_mutextrylock.c b/sched/pthread/pthread_mutextrylock.c index ec6357ce3bb91d66f3cce5d4c4b7053aae8b47ec..249dd28d8c770a4c69c17dde9b8920271aa41268 100644 --- a/sched/pthread/pthread_mutextrylock.c +++ b/sched/pthread/pthread_mutextrylock.c @@ -48,26 +48,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -123,7 +103,7 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) /* Try to get the semaphore. */ - if (sem_trywait((sem_t*)&mutex->sem) == OK) + if (sem_trywait((FAR sem_t *)&mutex->sem) == OK) { /* If we successfully obtained the semaphore, then indicate * that we own it. diff --git a/sched/pthread/pthread_mutexunlock.c b/sched/pthread/pthread_mutexunlock.c index 0d340d08c793d9e2d7be22eaf73a2b3872a13133..3b508940509d91f1394b288b01089235b7f8db92 100644 --- a/sched/pthread/pthread_mutexunlock.c +++ b/sched/pthread/pthread_mutexunlock.c @@ -47,26 +47,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -152,7 +132,7 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) #ifdef CONFIG_MUTEX_TYPES mutex->nlocks = 0; #endif - ret = pthread_givesemaphore((sem_t*)&mutex->sem); + ret = pthread_givesemaphore((FAR sem_t *)&mutex->sem); } sched_unlock(); } diff --git a/sched/pthread/pthread_once.c b/sched/pthread/pthread_once.c index 1854515110afad91774bf0d14201d428b38e40e2..b8afe81112a880d70bb233d46fcc20e901fcac89 100644 --- a/sched/pthread/pthread_once.c +++ b/sched/pthread/pthread_once.c @@ -45,26 +45,6 @@ #include #include -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Type Declarations - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Function Prototypes - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/pthread/pthread_release.c b/sched/pthread/pthread_release.c index 183053145af4bcb1484f6e7128869362c8c4bbfb..7620afbcd96461be52cd5581b7dcfa087fd67273 100644 --- a/sched/pthread/pthread_release.c +++ b/sched/pthread/pthread_release.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_release.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,31 +46,11 @@ #include "pthread/pthread.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_release * * Description: @@ -88,7 +68,7 @@ * * POSIX Compatibility: * - ************************************************************************/ + ****************************************************************************/ void pthread_release(FAR struct task_group_s *group) { diff --git a/sched/pthread/pthread_setaffinity.c b/sched/pthread/pthread_setaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..3948bf9025833181f4375409e824d8a2a409cfd5 --- /dev/null +++ b/sched/pthread/pthread_setaffinity.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * sched/pthread/pthread_setaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "pthread/pthread.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_setaffinity + * + * Description: + * The pthread_setaffinity_np() function sets the CPU affinity mask of + * the thread thread to the CPU set pointed to by cpuset. If the call + * is successful, and the thread is not currently running on one of the + * CPUs in cpuset, then it is migrated to one of those CPUs. + + * The argument cpusetsize is the length (in bytes) of the buffer + * pointed to by cpuset. Typically, this argument would be specified as + * sizeof(cpu_set_t). + * + * Parameters: + * thread - The ID of thread whose affinity set will be modified. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - Provides the new affinity set for the thread. + * + * Return Value: + * 0 if successful. Otherwise, an errno value is returned indicating the + * nature of the failure. + * + ****************************************************************************/ + +int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, + FAR const cpu_set_t *cpuset) +{ + int ret; + + sdbg("thread ID=%d cpusetsize=%d cpuset=%p\n", + (int)thread, (int)cpusetsize, cpusetsize); + + DEBUGASSERT(thread > 0 && cpusetsize == sizeof(cpu_set_t) && + cpuset != NULL); + + /* Let sched_setaffinity do all of the work */ + + ret = sched_setaffinity((pid_t)thread, cpusetsize, cpuset); + if (ret < 0) + { + /* If sched_setaffinity() fails, return the errno */ + + ret = get_errno(); + DEBUGASSERT(ret > 0); + } + + return ret; +} + +#endif /* CONFIG_SMP */ diff --git a/sched/pthread/pthread_setcancelstate.c b/sched/pthread/pthread_setcancelstate.c index be157a9f0d01c9e990de9998eff0c6bcd295b55c..a17560224e93df5b65a6aafd1e0ea9b2783ba46a 100644 --- a/sched/pthread/pthread_setcancelstate.c +++ b/sched/pthread/pthread_setcancelstate.c @@ -41,30 +41,6 @@ #include #include "sched/sched.h" -/****************************************************************************************** - * Pre-processor Definitions - ******************************************************************************************/ - -/****************************************************************************************** - * Private Types - ******************************************************************************************/ - -/****************************************************************************************** - * Private Function Prototypes - ******************************************************************************************/ - -/****************************************************************************************** - * Global Variables - ******************************************************************************************/ - -/****************************************************************************************** - * Private Variables - ******************************************************************************************/ - -/****************************************************************************************** - * Private Functions - ******************************************************************************************/ - /****************************************************************************************** * Public Functions ******************************************************************************************/ @@ -75,7 +51,7 @@ int pthread_setcancelstate(int state, FAR int *oldstate) { - struct tcb_s *tcb = (struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); int ret = OK; /* Suppress context changes for a bit so that the flags are stable. (the @@ -106,7 +82,7 @@ int pthread_setcancelstate(int state, FAR int *oldstate) /* Clear the non-cancelable and cancel pending flags */ - tcb->flags &= ~(TCB_FLAG_NONCANCELABLE|TCB_FLAG_CANCEL_PENDING); + tcb->flags &= ~(TCB_FLAG_NONCANCELABLE | TCB_FLAG_CANCEL_PENDING); /* If the cancel was pending, then just exit as requested */ diff --git a/sched/pthread/pthread_setschedparam.c b/sched/pthread/pthread_setschedparam.c index 8ff54a0227bfc3109297633bf447a8202f7c9918..fe7ee0cdb116d189c3aa1c5786dc79b3729f3cbe 100644 --- a/sched/pthread/pthread_setschedparam.c +++ b/sched/pthread/pthread_setschedparam.c @@ -45,26 +45,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/pthread/pthread_setschedprio.c b/sched/pthread/pthread_setschedprio.c index 7813c5df97292e38270e32f8222368cda703038c..cf31d9f013f0f6fea3e2df79d6e5049df3e518aa 100644 --- a/sched/pthread/pthread_setschedprio.c +++ b/sched/pthread/pthread_setschedprio.c @@ -44,30 +44,6 @@ #include #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/pthread/pthread_setspecific.c b/sched/pthread/pthread_setspecific.c index f21c171bff2895145771092e206a6c6cea6dca5e..977f16ec2bd2b26687c76befef28a51960217756 100644 --- a/sched/pthread/pthread_setspecific.c +++ b/sched/pthread/pthread_setspecific.c @@ -47,26 +47,6 @@ #include "sched/sched.h" #include "pthread/pthread.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -115,7 +95,7 @@ int pthread_setspecific(pthread_key_t key, FAR const void *value) { #if CONFIG_NPTHREAD_KEYS > 0 - FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task(); FAR struct task_group_s *group = rtcb->cmn.group; int ret = EINVAL; @@ -128,7 +108,7 @@ int pthread_setspecific(pthread_key_t key, FAR const void *value) { /* Store the data in the TCB. */ - rtcb->pthread_data[key] = (FAR void*)value; + rtcb->pthread_data[key] = (FAR void *)value; /* Return success. */ diff --git a/sched/pthread/pthread_sigmask.c b/sched/pthread/pthread_sigmask.c index 2950a7957a6c51e5837ac62f40fadf7b788a7301..012024b71db196eb9ff6b8b749e7d708e137850f 100644 --- a/sched/pthread/pthread_sigmask.c +++ b/sched/pthread/pthread_sigmask.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_sigmask.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,31 +44,11 @@ #include #include -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_sigmask * * Description: @@ -94,7 +74,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) { diff --git a/sched/pthread/pthread_yield.c b/sched/pthread/pthread_yield.c index 0d5e99b3df5fc38017316612a9aacab27ef398a9..0577e21f83d7e0e9a4c1e25c3cb2d00db3008a7c 100644 --- a/sched/pthread/pthread_yield.c +++ b/sched/pthread/pthread_yield.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/pthread/pthread_yield.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,40 +31,20 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: pthread_yield * * Description: @@ -79,7 +59,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ void pthread_yield(void) { diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index 65710efdd2637bd6bb824f5d3799b82b1bb94c51..74ffabe1f35684d2dd8c2937dd9e8a0257c99cf7 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -47,6 +47,10 @@ ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sched_reprioritize.c endif +ifeq ($(CONFIG_SMP),y) +CSRCS += sched_getaffinity.c sched_setaffinity.c sched_cpuselect.c +endif + ifeq ($(CONFIG_SCHED_WAITPID),y) CSRCS += sched_waitpid.c ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) @@ -78,6 +82,10 @@ else CSRCS += sched_processtimer.c endif +ifeq ($(CONFIG_SCHED_INSTRUMENTATION_BUFFER),y) +CSRCS += sched_note.c +endif + # Include sched build support DEPPATH += --dep-path sched diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 826be4a708e557e446a4af4c684a0a1d1db6d200..504c949e8c900440d804ce1f60cff5583a5b87b7 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched.h * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,9 @@ #include #include +#include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -61,8 +63,44 @@ * tasks built into the design). */ -#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1) -#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK) +#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1) +#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK) + +/* These are macros to access the current CPU and the current task on a CPU. + * These macros are intended to support a future SMP implementation. + */ + +#ifdef CONFIG_SMP +# define current_task(cpu) ((FAR struct tcb_s *)g_assignedtasks[cpu].head) +# define this_cpu() up_cpu_index() +#else +# define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head) +# define this_cpu() (0) +#endif +#define this_task() (current_task(this_cpu())) + +/* List attribute flags */ + +#define TLIST_ATTR_PRIORITIZED (1 << 0) /* Bit 0: List is prioritized */ +#define TLIST_ATTR_INDEXED (1 << 1) /* Bit 1: List is indexed by CPU */ +#define TLIST_ATTR_RUNNABLE (1 << 2) /* Bit 2: List includes running tasks */ + +#define __TLIST_ATTR(s) g_tasklisttable[s].attr +#define TLIST_ISPRIORITIZED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 0) +#define TLIST_ISINDEXED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_INDEXED) != 0) +#define TLIST_ISRUNNABLE(s) ((__TLIST_ATTR(s) & TLIST_ATTR_RUNNABLE) != 0) + +#define __TLIST_HEAD(s) (FAR dq_queue_t *)g_tasklisttable[s].list +#define __TLIST_HEADINDEXED(s,c) (&(__TLIST_HEAD(s))[c]) + +#ifdef CONFIG_SMP +# define TLIST_HEAD(s,c) \ + ((TLIST_ISINDEXED(s)) ? __TLIST_HEADINDEXED(s,c) : __TLIST_HEAD(s)) +# define TLIST_BLOCKED(s) __TLIST_HEAD(s) +#else +# define TLIST_HEAD(s) __TLIST_HEAD(s) +# define TLIST_BLOCKED(s) __TLIST_HEAD(s) +#endif /**************************************************************************** * Public Type Definitions @@ -88,19 +126,18 @@ struct pidhash_s #endif }; -/* This structure defines an element of the g_tasklisttable[]. - * This table is used to map a task_state enumeration to the - * corresponding task list. +/* This structure defines an element of the g_tasklisttable[]. This table + * is used to map a task_state enumeration to the corresponding task list. */ struct tasklist_s { DSEG volatile dq_queue_t *list; /* Pointer to the task list */ - bool prioritized; /* true if the list is prioritized */ + uint8_t attr; /* List attribute flags */ }; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /* Declared in os_start.c ***************************************************/ @@ -109,17 +146,53 @@ struct tasklist_s * and by a series of task lists. All of these tasks lists are declared * below. Although it is not always necessary, most of these lists are * prioritized so that common list handling logic can be used (only the - * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists need - * to be prioritized). + * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists + * need to be prioritized). */ -/* This is the list of all tasks that are ready to run. The head of this - * list is the currently active task; the tail of this list is always the - * IDLE task. +/* This is the list of all tasks that are ready to run. This is a + * prioritized list with head of the list holding the highest priority + * (unassigned) task. In the non-SMP cae, the head of this list is the + * currently active task and the tail of this list, the lowest priority + * task, is always the IDLE task. */ extern volatile dq_queue_t g_readytorun; +#ifdef CONFIG_SMP +/* In order to support SMP, the function of the g_readytorun list changes, + * The g_readytorun is still used but in the SMP case it will contain only: + * + * - Only tasks/threads that are eligible to run, but not currently running, + * and + * - Tasks/threads that have not been assigned to a CPU. + * + * Otherwise, the TCB will be reatined in an assigned task list, + * g_assignedtasks. As its name suggests, on 'g_assignedtasks queue for CPU + * 'n' would contain only tasks/threads that are assigned to CPU 'n'. Tasks/ + * threads would be assigned a particular CPU by one of two mechanisms: + * + * - (Semi-)permanently through an RTOS interfaces such as + * pthread_attr_setaffinity(), or + * - Temporarily through scheduling logic when a previously unassigned task + * is made to run. + * + * Tasks/threads that are assigned to a CPU via an interface like + * pthread_attr_setaffinity() would never go into the g_readytorun list, but + * would only go into the g_assignedtasks[n] list for the CPU 'n' to which + * the thread has been assigned. Hence, the g_readytorun list would hold + * only unassigned tasks/threads. + * + * Like the g_readytorun list in in non-SMP case, each g_assignedtask[] list + * is prioritized: The head of the list is the currently active task on this + * CPU. Tasks after the active task are ready-to-run and assigned to this + * CPU. The tail of this assigned task list, the lowest priority task, is + * always the CPU's IDLE task. + */ + +extern volatile dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS]; +#endif + /* This is the list of all tasks that are ready-to-run, but cannot be placed * in the g_readytorun list because: (1) They are higher priority than the * currently active task at the head of the g_readytorun list, and (2) the @@ -172,13 +245,23 @@ extern volatile dq_queue_t g_inactivetasks; * while it is within an interrupt handler. */ -extern volatile sq_queue_t g_delayed_kufree; - #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) extern volatile sq_queue_t g_delayed_kfree; #endif +#ifndef CONFIG_BUILD_KERNEL +/* REVISIT: It is not safe to defer user allocation in the kernel mode + * build. Why? Because the correct user context will not be in place + * when these deferred de-allocations are performed. In order to make + * this work, we would need to do something like: (1) move g_delayed_kufree + * into the group structure, then traverse the groups to collect garbage on + * a group-by-group basis. + */ + +extern volatile sq_queue_t g_delayed_kufree; +#endif + /* This is the value of the last process ID assigned to a task */ extern volatile pid_t g_lastpid; @@ -195,10 +278,11 @@ extern volatile pid_t g_lastpid; extern struct pidhash_s g_pidhash[CONFIG_MAX_TASKS]; -/* This is a table of task lists. This table is indexed by the task state +/* This is a table of task lists. This table is indexed by the task stat * enumeration type (tstate_t) and provides a pointer to the associated - * static task list (if there is one) as well as a boolean indication as to - * if the list is an ordered list or not. + * static task list (if there is one) as well as a a set of attribute flags + * indicating properities of the list, for example, if the list is an + * ordered list or not. */ extern const struct tasklist_s g_tasklisttable[NUM_TASK_STATES]; @@ -211,10 +295,79 @@ extern const struct tasklist_s g_tasklisttable[NUM_TASK_STATES]; extern volatile uint32_t g_cpuload_total; #endif +/* Declared in sched_lock.c *************************************************/ +/* Pre-emption is disabled via the interface sched_lock(). sched_lock() + * works by preventing context switches from the currently executing tasks. + * This prevents other tasks from running (without disabling interrupts) and + * gives the currently executing task exclusive access to the (single) CPU + * resources. Thus, sched_lock() and its companion, sched_unlcok(), are + * used to implement some critical sections. + * + * In the single CPU case, Pre-emption is disabled using a simple lockcount + * in the TCB. When the scheduling is locked, the lockcount is incremented; + * when the scheduler is unlocked, the lockcount is decremented. If the + * lockcount for the task at the head of the g_readytorun list has a + * lockcount > 0, then pre-emption is disabled. + * + * No special protection is required since only the executing task can + * modify its lockcount. + */ + +#ifdef CONFIG_SMP +/* In the multiple CPU, SMP case, disabling context switches will not give a + * task exclusive access to the (multiple) CPU resources (at least without + * stopping the other CPUs): Even though pre-emption is disabled, other + * threads will still be executing on the other CPUS. + * + * There are additional rules for this multi-CPU case: + * + * 1. There is a global lock count 'g_cpu_lockset' that includes a bit for + * each CPU: If the bit is '1', then the corresponding CPU has the + * scheduler locked; if '0', then the CPU does not have the scheduler + * locked. + * 2. Scheduling logic would set the bit associated with the cpu in + * 'g_cpu_lockset' when the TCB at the head of the g_assignedtasks[cpu] + * list transitions has 'lockcount' > 0. This might happen when sched_lock() + * is called, or after a context switch that changes the TCB at the + * head of the g_assignedtasks[cpu] list. + * 3. Similarly, the cpu bit in the global 'g_cpu_lockset' would be cleared + * when the TCB at the head of the g_assignedtasks[cpu] list has + * 'lockcount' == 0. This might happen when sched_unlock() is called, or + * after a context switch that changes the TCB at the head of the + * g_assignedtasks[cpu] list. + * 4. Modification of the global 'g_cpu_lockset' must be protected by a + * spinlock, 'g_cpu_schedlock'. That spinlock would be taken when + * sched_lock() is called, and released when sched_unlock() is called. + * This assures that the scheduler does enforce the critical section. + * NOTE: Because of this spinlock, there should never be more than one + * bit set in 'g_cpu_lockset'; attempts to set additional bits should + * be cause the CPU to block on the spinlock. However, additional bits + * could get set in 'g_cpu_lockset' due to the context switches on the + * various CPUs. + * 5. Each the time the head of a g_assignedtasks[] list changes and the + * scheduler modifies 'g_cpu_lockset', it must also set 'g_cpu_schedlock' + * depending on the new state of 'g_cpu_lockset'. + * 5. Logic that currently uses the currently running tasks lockcount + * instead uses the global 'g_cpu_schedlock'. A value of SP_UNLOCKED + * means that no CPU has pre-emption disabled; SP_LOCKED means that at + * least one CPU has pre-emption disabled. + */ + +extern volatile spinlock_t g_cpu_schedlock; + +/* Used to keep track of which CPU(s) hold the IRQ lock. */ + +extern volatile spinlock_t g_cpu_locksetlock; +extern volatile cpu_set_t g_cpu_lockset; + +#endif /* CONFIG_SMP */ + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +/* Task list manipulation functions */ + bool sched_addreadytorun(FAR struct tcb_s *rtrtcb); bool sched_removereadytorun(FAR struct tcb_s *rtrtcb); bool sched_addprioritized(FAR struct tcb_s *newTcb, DSEG dq_queue_t *list); @@ -223,6 +376,8 @@ void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state); void sched_removeblocked(FAR struct tcb_s *btcb); int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority); +/* Priority inheritance support */ + #ifdef CONFIG_PRIORITY_INHERITANCE int sched_reprioritize(FAR struct tcb_s *tcb, int sched_priority); #else @@ -230,6 +385,8 @@ int sched_reprioritize(FAR struct tcb_s *tcb, int sched_priority); sched_setpriority(tcb,sched_priority) #endif +/* Support for tickless operation */ + #ifdef CONFIG_SCHED_TICKLESS unsigned int sched_timer_cancel(void); void sched_timer_resume(void); @@ -240,6 +397,8 @@ void sched_timer_reassess(void); # define sched_timer_reassess() #endif +/* Scheduler policy support */ + #if CONFIG_RR_INTERVAL > 0 uint32_t sched_roundrobin_process(FAR struct tcb_s *tcb, uint32_t ticks, bool noswitches); @@ -257,10 +416,23 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks, void sched_sporadic_lowpriority(FAR struct tcb_s *tcb); #endif +#ifdef CONFIG_SMP +int sched_cpu_select(cpu_set_t affinity); +# define sched_islocked(tcb) spin_islocked(&g_cpu_schedlock) +#else +# define sched_islocked(tcb) ((tcb)->lockcount > 0) +# define sched_cpu_select(a) (0) + +#endif + +/* CPU load measurement support */ + #if defined(CONFIG_SCHED_CPULOAD) && !defined(CONFIG_SCHED_CPULOAD_EXTCLK) void weak_function sched_process_cpuload(void); #endif +/* TCB operations */ + bool sched_verifytcb(FAR struct tcb_s *tcb); int sched_releasetcb(FAR struct tcb_s *tcb, uint8_t ttype); diff --git a/sched/sched/sched_addblocked.c b/sched/sched/sched_addblocked.c index 5f95a6c9f84f373ef9bcc548108142f566fdc8c7..34303681c5ce72cd9c546f0d44508ae8e966204f 100644 --- a/sched/sched/sched_addblocked.c +++ b/sched/sched/sched_addblocked.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_addblocked.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,31 +44,11 @@ #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_addblocked * * Description: @@ -86,33 +66,34 @@ * - The caller has established a critical section before * calling this function. * - ************************************************************************/ + ****************************************************************************/ void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state) { + FAR dq_queue_t *tasklist; + /* Make sure that we received a valid blocked state */ - ASSERT(task_state >= FIRST_BLOCKED_STATE && - task_state <= LAST_BLOCKED_STATE); + DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE && + task_state <= LAST_BLOCKED_STATE); + + /* Add the TCB to the blocked task list associated with this state. */ + + tasklist = TLIST_BLOCKED(task_state); - /* Add the TCB to the blocked task list associated with this state. - * First, determine if the task is to be added to a prioritized task - * list - */ + /* Determine if the task is to be added to a prioritized task list. */ - if (g_tasklisttable[task_state].prioritized) + if (TLIST_ISPRIORITIZED(task_state)) { /* Add the task to a prioritized list */ - sched_addprioritized(btcb, - (FAR dq_queue_t*)g_tasklisttable[task_state].list); + sched_addprioritized(btcb, tasklist); } else { /* Add the task to a non-prioritized list */ - dq_addlast((FAR dq_entry_t*)btcb, - (FAR dq_queue_t*)g_tasklisttable[task_state].list); + dq_addlast((FAR dq_entry_t *)btcb, tasklist); } /* Make sure the TCB's state corresponds to the list */ diff --git a/sched/sched/sched_addprioritized.c b/sched/sched/sched_addprioritized.c index d132f335e37a5ab15049bbf535bdebca3a389521..22907574eac346c974c0ba2a967e23b292933cd4 100644 --- a/sched/sched/sched_addprioritized.c +++ b/sched/sched/sched_addprioritized.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_addprioritized.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,31 +46,11 @@ #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_addprioritized * * Description: @@ -86,14 +66,14 @@ * Assumptions: * - The caller has established a critical section before * calling this function (calling sched_lock() first is NOT - * a good idea -- use irqsave()). + * a good idea -- use enter_critical_section()). * - The caller has already removed the input tcb from * whatever list it was in. * - The caller handles the condition that occurs if the * the head of the task list is changed. * - The caller must set the task_state field of the TCB to * match the state associated with the list. - ************************************************************************/ + ****************************************************************************/ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list) { @@ -110,7 +90,7 @@ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list) * Each is list is maintained in ascending sched_priority order. */ - for (next = (FAR struct tcb_s*)list->head; + for (next = (FAR struct tcb_s *)list->head; (next && sched_priority <= next->sched_priority); next = next->flink); @@ -123,15 +103,15 @@ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list) { /* The tcb goes at the end of the list. */ - prev = (FAR struct tcb_s*)list->tail; + prev = (FAR struct tcb_s *)list->tail; if (!prev) { /* Special case: The list is empty */ tcb->flink = NULL; tcb->blink = NULL; - list->head = (FAR dq_entry_t*)tcb; - list->tail = (FAR dq_entry_t*)tcb; + list->head = (FAR dq_entry_t *)tcb; + list->tail = (FAR dq_entry_t *)tcb; ret = true; } else @@ -141,14 +121,14 @@ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list) tcb->flink = NULL; tcb->blink = prev; prev->flink = tcb; - list->tail = (FAR dq_entry_t*)tcb; + list->tail = (FAR dq_entry_t *)tcb; } } else { /* The tcb goes just before next */ - prev = (FAR struct tcb_s*)next->blink; + prev = (FAR struct tcb_s *)next->blink; if (!prev) { /* Special case: Insert at the head of the list */ @@ -156,7 +136,7 @@ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list) tcb->flink = next; tcb->blink = NULL; next->blink = tcb; - list->head = (FAR dq_entry_t*)tcb; + list->head = (FAR dq_entry_t *)tcb; ret = true; } else diff --git a/sched/sched/sched_addreadytorun.c b/sched/sched/sched_addreadytorun.c index 04cc2afcb4652d9c8f34c98588b7163ea2189d42..987c91d486597a99ffdc3370edf18dbf4a0d8ff7 100644 --- a/sched/sched/sched_addreadytorun.c +++ b/sched/sched/sched_addreadytorun.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_addreadytorun.c * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,27 +43,10 @@ #include #include -#include "sched/sched.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ +#include -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ +#include "irq/irq.h" +#include "sched/sched.h" /**************************************************************************** * Public Functions @@ -73,12 +56,11 @@ * Name: sched_addreadytorun * * Description: - * This function adds a TCB to the ready to run - * list. If the currently active task has preemption disabled - * and the new TCB would cause this task to be pre-empted, the - * new task is added to the g_pendingtasks list instead. The - * pending tasks will be made ready-to-run when preemption - * is unlocked. + * This function adds a TCB to the ready to run list. If the currently + * active task has preemption disabled and the new TCB would cause this + * task to be pre-empted, the new task is added to the g_pendingtasks list + * instead. The pending tasks will be made ready-to-run when preemption is + * unlocked. * * Inputs: * btcb - Points to the blocked TCB that is ready-to-run @@ -88,50 +70,52 @@ * has changed. * * Assumptions: - * - The caller has established a critical section before - * calling this function (calling sched_lock() first is NOT - * a good idea -- use irqsave()). - * - The caller has already removed the input rtcb from - * whatever list it was in. - * - The caller handles the condition that occurs if the - * the head of the ready-to-run list is changed. + * - The caller has established a critical section before calling this + * function (calling sched_lock() first is NOT a good idea -- use + * enter_critical_section()). + * - The caller has already removed the input rtcb from whatever list it + * was in. + * - The caller handles the condition that occurs if the head of the + * ready-to-run list is changed. * ****************************************************************************/ +#ifndef CONFIG_SMP bool sched_addreadytorun(FAR struct tcb_s *btcb) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); bool ret; /* Check if pre-emption is disabled for the current running task and if * the new ready-to-run task would cause the current running task to be - * pre-empted. + * pre-empted. NOTE that IRQs disabled implies that pre-emption is + * also disabled. */ - if (rtcb->lockcount && rtcb->sched_priority < btcb->sched_priority) + if (rtcb->lockcount > 0 && rtcb->sched_priority < btcb->sched_priority) { /* Yes. Preemption would occur! Add the new ready-to-run task to the * g_pendingtasks task list for now. */ - sched_addprioritized(btcb, (FAR dq_queue_t*)&g_pendingtasks); + sched_addprioritized(btcb, (FAR dq_queue_t *)&g_pendingtasks); btcb->task_state = TSTATE_TASK_PENDING; ret = false; } /* Otherwise, add the new task to the ready-to-run task list */ - else if (sched_addprioritized(btcb, (FAR dq_queue_t*)&g_readytorun)) + else if (sched_addprioritized(btcb, (FAR dq_queue_t *)&g_readytorun)) { /* Inform the instrumentation logic that we are switching tasks */ sched_note_switch(rtcb, btcb); /* The new btcb was added at the head of the ready-to-run list. It - * is now to new active task! + * is now the new active task! */ - ASSERT(!rtcb->lockcount && btcb->flink != NULL); + DEBUGASSERT(rtcb->lockcount == 0 && btcb->flink != NULL); btcb->task_state = TSTATE_TASK_RUNNING; btcb->flink->task_state = TSTATE_TASK_READYTORUN; @@ -147,3 +131,256 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) return ret; } +#endif /* !CONFIG_SMP */ + +/**************************************************************************** + * Name: sched_addreadytorun + * + * Description: + * This function adds a TCB to one of the ready to run lists. That might + * be: + * + * 1. The g_readytorun list if the task is ready-to-run but not running + * and not assigned to a CPU. + * 2. The g_assignedtask[cpu] list if the task is running or if has been + * assigned to a CPU. + * + * If the currently active task has preemption disabled and the new TCB + * would cause this task to be pre-empted, the new task is added to the + * g_pendingtasks list instead. Thepending tasks will be made + * ready-to-run when preemption isunlocked. + * + * Inputs: + * btcb - Points to the blocked TCB that is ready-to-run + * + * Return Value: + * true if the currently active task (the head of the ready-to-run list) + * has changed. + * + * Assumptions: + * - The caller has established a critical section before calling this + * function (calling sched_lock() first is NOT a good idea -- use + * enter_critical_section()). + * - The caller has already removed the input rtcb from whatever list it + * was in. + * - The caller handles the condition that occurs if the head of the + * ready-to-run list is changed. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +bool sched_addreadytorun(FAR struct tcb_s *btcb) +{ + FAR struct tcb_s *rtcb; + FAR dq_queue_t *tasklist; + int task_state; + int cpu; + bool switched; + bool doswitch; + + /* Check if the blocked TCB is locked to this CPU */ + + if ((btcb->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + /* Yes.. that that is the CPU we must use */ + + cpu = btcb->cpu; + } + else + { + /* Otherwise, find the CPU that is executing the lowest priority task + * (possibly its IDLE task). + */ + + cpu = sched_cpu_select(btcb->affinity); + } + + /* Get the task currently running on the CPU (maybe the IDLE task) */ + + rtcb = (FAR struct tcb_s *)g_assignedtasks[cpu].head; + + /* Determine the desired new task state. First, if the new task priority + * is higher then the priority of the lowest priority, running task, then + * the new task will be running and a context switch switch will be required. + */ + + if (rtcb->sched_priority < btcb->sched_priority) + { + task_state = TSTATE_TASK_RUNNING; + } + + /* If it will not be running, but is locked to a CPU, then it will be in + * the assigned state. + */ + + else if ((btcb->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + task_state = TSTATE_TASK_ASSIGNED; + cpu = btcb->cpu; + } + + /* Otherwise, it will be ready-to-run, but not not yet running */ + + else + { + task_state = TSTATE_TASK_READYTORUN; + cpu = 0; /* CPU does not matter */ + } + + /* If the selected state is TSTATE_TASK_RUNNING, then we would like to + * start running the task. Be we cannot do that if pre-emption is disable. + */ + + if (spin_islocked(&g_cpu_schedlock) && task_state == TSTATE_TASK_RUNNING) + { + /* Preemption would occur! Add the new ready-to-run task to the + * g_pendingtasks task list for now. + */ + + sched_addprioritized(btcb, (FAR dq_queue_t *)&g_pendingtasks); + btcb->task_state = TSTATE_TASK_PENDING; + doswitch = false; + } + else if (task_state == TSTATE_TASK_READYTORUN) + { + /* The new btcb was added either (1) in the middle of the assigned + * task list (the btcb->cpu field is already valid) or (2) was + * added to the ready-to-run list (the btcb->cpu field does not + * matter). Either way, it won't be running. + * + * Add the task to the ready-to-run (but not running) task list + */ + + (void)sched_addprioritized(btcb, (FAR dq_queue_t *)&g_readytorun); + + btcb->task_state = TSTATE_TASK_READYTORUN; + doswitch = false; + } + else /* (task_state == TSTATE_TASK_ASSIGNED || task_state == TSTATE_TASK_RUNNING) */ + { + int me = this_cpu(); + + /* If we are modifying some assigned task list other than our own, we will + * need to stop that CPU. + */ + + if (cpu != me) + { + DEBUGVERIFY(up_cpu_pause(cpu)); + } + + /* Add the task to the list corresponding to the selected state + * and check if a context switch will occur + */ + + tasklist = (FAR dq_queue_t *)&g_assignedtasks[cpu]; + switched = sched_addprioritized(btcb, tasklist); + + /* If the selected task was the g_assignedtasks[] list, then a context + * switch will occur. + */ + + if (switched) + { + FAR struct tcb_s *next; + + /* The new btcb was added at the head of the ready-to-run list. It + * is now the new active task! + * + * Inform the instrumentation logic that we are switching tasks. + */ + + sched_note_switch(rtcb, btcb); + + /* Assign the CPU and set the running state */ + + DEBUGASSERT(task_state == TSTATE_TASK_RUNNING); + + btcb->cpu = cpu; + btcb->task_state = TSTATE_TASK_RUNNING; + + /* Adjust global pre-emption controls. If the lockcount is + * greater than zero, then this task/this CPU holds the scheduler + * lock. + */ + + if (btcb->lockcount > 0) + { + spin_setbit(&g_cpu_lockset, cpu, &g_cpu_locksetlock, + &g_cpu_schedlock); + } + else + { + spin_clrbit(&g_cpu_lockset, cpu, &g_cpu_locksetlock, + &g_cpu_schedlock); + } + + /* Adjust global IRQ controls. If irqcount is greater than zero, + * then this task/this CPU holds the IRQ lock + */ + + if (btcb->irqcount > 0) + { + spin_setbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock, + &g_cpu_irqlock); + } + else + { + spin_clrbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock, + &g_cpu_irqlock); + } + + /* If the following task is not locked to this CPU, then it must + * be moved to the g_readytorun list. Since it cannot be at the + * head of the list, we can do this without invoking any heavy + * lifting machinery. + */ + + DEBUGASSERT(btcb->flink != NULL); + next = (FAR struct tcb_s *)btcb->flink; + + if ((next->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + DEBUGASSERT(next->cpu == cpu); + next->task_state = TSTATE_TASK_ASSIGNED; + } + else + { + /* Remove the task from the assigned task list */ + + dq_rem((FAR dq_entry_t *)next, tasklist); + + /* Add the task to the g_readytorun list. It may be + * assigned to a different CPU the next time that it runs. + */ + + next->task_state = TSTATE_TASK_READYTORUN; + (void)sched_addprioritized(next, + (FAR dq_queue_t *)&g_readytorun); + } + + doswitch = true; + } + else + { + /* No context switch. Assign the CPU and set the assigned state */ + + DEBUGASSERT(task_state == TSTATE_TASK_ASSIGNED); + + btcb->cpu = cpu; + btcb->task_state = TSTATE_TASK_ASSIGNED; + } + + /* All done, restart the other CPU (if it was paused). */ + + if (cpu != me) + { + DEBUGVERIFY(up_cpu_resume(cpu)); + doswitch = false; + } + } + + return doswitch; +} + +#endif /* CONFIG_SMP */ diff --git a/sched/sched/sched_cpuload.c b/sched/sched/sched_cpuload.c index fe9305b3d2d1c3ebf4227ea67a5937b3e3e064cb..6cfe027bedbccf3c05338bb89d6e4288873802a9 100644 --- a/sched/sched/sched_cpuload.c +++ b/sched/sched/sched_cpuload.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_cpuload.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,15 +43,15 @@ #include #include -#include +#include #include "sched/sched.h" #ifdef CONFIG_SCHED_CPULOAD -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ /* Are we using the system timer, or an external clock? Get the rate * of the sampling in ticks per second for the selected timer. */ @@ -65,17 +65,17 @@ # define CPULOAD_TICKSPERSEC CLOCKS_PER_SEC #endif -/************************************************************************ +/**************************************************************************** * Private Type Declarations - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ /* This is the total number of clock tick counts. Essentially the * 'denominator' for all CPU load calculations. @@ -83,15 +83,15 @@ volatile uint32_t g_cpuload_total; -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_process_cpuload * * Description: @@ -107,11 +107,11 @@ volatile uint32_t g_cpuload_total; * This function is called from a timer interrupt handler with all * interrupts disabled. * - ************************************************************************/ + ****************************************************************************/ void weak_function sched_process_cpuload(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); int hash_index; int i; @@ -183,7 +183,7 @@ int clock_cpuload(int pid, FAR struct cpuload_s *cpuload) * synchronized when read. */ - flags = irqsave(); + flags = enter_critical_section(); /* Make sure that the entry is valid (TCB field is not NULL) and matches * the requested PID. The first check is needed if the thread has exited. @@ -205,7 +205,7 @@ int clock_cpuload(int pid, FAR struct cpuload_s *cpuload) ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/sched/sched/sched_cpuselect.c b/sched/sched/sched_cpuselect.c new file mode 100644 index 0000000000000000000000000000000000000000..efd5c8417bafc75b327c6a659ca7a9e93fc3555c --- /dev/null +++ b/sched/sched/sched_cpuselect.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * sched/sched/sched_cpuselect.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "sched/sched.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMPOSSIBLE_CPU 0xff + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_cpu_select + * + * Description: + * Return the index to the CPU with the lowest priority running task, + * possbily its IDLE task. + * + * Inputs: + * affinity - The set of CPUs on which the thread is permitted to run. + * + * Return Value: + * Index of the CPU with the lowest priority running task + * + * Assumptions: + * Called from within a critical section. + * + ****************************************************************************/ + +int sched_cpu_select(cpu_set_t affinity) +{ + uint8_t minprio; + int cpu; + int i; + + /* Otherwise, find the CPU that is executing the lowest priority task + * (possibly its IDLE task). + */ + + minprio = SCHED_PRIORITY_MAX; + cpu = IMPOSSIBLE_CPU; + + for (i = 0; i < CONFIG_SMP_NCPUS; i++) + { + /* If the thread permitted to run on this CPU? */ + + if ((affinity & (1 << i)) != 0) + { + FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_assignedtasks[i].head; + + /* If this thread is executing its IDLE task, the use it. The + * IDLE task is always the last task in the assigned task list. + */ + + if (rtcb->flink == NULL) + { + /* The IDLE task should always be assigned to this CPU and have + * a priority of zero. + */ + + DEBUGASSERT(rtcb->sched_priority == 0); + return i; + } + else if (rtcb->sched_priority < minprio) + { + DEBUGASSERT(rtcb->sched_priority > 0); + cpu = i; + } + } + } + + DEBUGASSERT(cpu != IMPOSSIBLE_CPU); + return cpu; +} + +#endif /* CONFIG_SMP */ diff --git a/sched/sched/sched_foreach.c b/sched/sched/sched_foreach.c index 016aef79bf107ed8c828de30f9a3718b4559ea95..1ee962d7728b89ce7552eed1e8f84443a166279f 100644 --- a/sched/sched/sched_foreach.c +++ b/sched/sched/sched_foreach.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_foreach.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,20 +31,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include + +#include + #include "sched/sched.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_foreach * * Description: @@ -61,24 +64,24 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ void sched_foreach(sched_foreach_t handler, FAR void *arg) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); int ndx; /* Vist each active task */ for (ndx = 0; ndx < CONFIG_MAX_TASKS; ndx++) { - if (g_pidhash[ndx].tcb) - { - handler(g_pidhash[ndx].tcb, arg); - } + if (g_pidhash[ndx].tcb) + { + handler(g_pidhash[ndx].tcb, arg); + } } - irqrestore(flags); + leave_critical_section(flags); } diff --git a/sched/sched/sched_free.c b/sched/sched/sched_free.c index d5c8dd8d09666e1b266109adf90c6af45cd040f1..cd1c5f37436cd90bff709863d8a0904d188236cd 100644 --- a/sched/sched/sched_free.c +++ b/sched/sched/sched_free.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_free.c * - * Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,48 +31,29 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include +#include #include #include #include #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_ufree and sched_kfree * * Description: @@ -81,12 +62,23 @@ * corner cases where the operating system may have to perform * deallocations from within an interrupt handler. * - ************************************************************************/ + ****************************************************************************/ void sched_ufree(FAR void *address) { - irqstate_t flags; +#ifdef CONFIG_BUILD_KERNEL + /* REVISIT: It is not safe to defer user allocation in the kernel mode + * build. Why? Because the correct user context is in place now but + * will not be in place when the deferred de-allocation is performed. In + * order to make this work, we would need to do something like: (1) move + * g_delayed_kufree into the group structure, then traverse the groups to + * collect garbage on a group-by-group basis. + */ + + ASSERT(!up_interrupt_context()); + kumm_free(address); +#else /* Check if this is an attempt to deallocate memory from an exception * handler. If this function is called from the IDLE task, then we * must have exclusive access to the memory manager to do this. @@ -94,11 +86,13 @@ void sched_ufree(FAR void *address) if (up_interrupt_context() || kumm_trysemaphore() != 0) { + irqstate_t flags; + /* Yes.. Make sure that this is not a attempt to free kernel memory * using the user deallocator. */ - flags = irqsave(); + flags = enter_critical_section(); #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) DEBUGASSERT(!kmm_heapmember(address)); @@ -106,14 +100,15 @@ void sched_ufree(FAR void *address) /* Delay the deallocation until a more appropriate time. */ - sq_addlast((FAR sq_entry_t*)address, (sq_queue_t*)&g_delayed_kufree); + sq_addlast((FAR sq_entry_t *)address, + (FAR sq_queue_t *)&g_delayed_kufree); /* Signal the worker thread that is has some clean up to do */ #ifdef CONFIG_SCHED_WORKQUEUE work_signal(LPWORK); #endif - irqrestore(flags); + leave_critical_section(flags); } else { @@ -122,6 +117,7 @@ void sched_ufree(FAR void *address) kumm_free(address); kumm_givesemaphore(); } +#endif } #ifdef CONFIG_MM_KERNEL_HEAP @@ -140,19 +136,20 @@ void sched_kfree(FAR void *address) * using the kernel deallocator. */ - flags = irqsave(); + flags = enter_critical_section(); DEBUGASSERT(kmm_heapmember(address)); /* Delay the deallocation until a more appropriate time. */ - sq_addlast((FAR sq_entry_t*)address, (sq_queue_t*)&g_delayed_kfree); + sq_addlast((FAR sq_entry_t *)address, + (FAR sq_queue_t *)&g_delayed_kfree); /* Signal the worker thread that is has some clean up to do */ #ifdef CONFIG_SCHED_WORKQUEUE work_signal(LPWORK); #endif - irqrestore(flags); + leave_critical_section(flags); } else { diff --git a/sched/sched/sched_garbage.c b/sched/sched/sched_garbage.c index fb1cdeb8fac045f6b8f224913e406c5c7453190f..1fd3fbf05050539b34030691f6561cb576e658ad 100644 --- a/sched/sched/sched_garbage.c +++ b/sched/sched/sched_garbage.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_garbage.c * - * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -38,26 +38,11 @@ ****************************************************************************/ #include +#include #include #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -78,22 +63,32 @@ static inline void sched_kucleanup(void) { +#ifdef CONFIG_BUILD_KERNEL + /* REVISIT: It is not safe to defer user allocation in the kernel mode + * build. Why? Because the correct user context will not be in place + * when these deferred de-allocations are performed. In order to make + * this work, we would need to do something like: (1) move + * g_delayed_kufree into the group structure, then traverse the groups to + * collect garbage on a group-by-group basis. + */ + +#else irqstate_t flags; FAR void *address; - /* Test if the delayed deallocation queue is empty. No special protection - * is needed because this is an atomic test. - */ + /* Test if the delayed deallocation queue is empty. No special protection + * is needed because this is an atomic test. + */ - while (g_delayed_kufree.head) + while (g_delayed_kufree.head) { /* Remove the first delayed deallocation. This is not atomic and so * we must disable interrupts around the queue operation. */ - flags = irqsave(); - address = (FAR void*)sq_remfirst((FAR sq_queue_t*)&g_delayed_kufree); - irqrestore(flags); + flags = enter_critical_section(); + address = (FAR void *)sq_remfirst((FAR sq_queue_t *)&g_delayed_kufree); + leave_critical_section(flags); /* The address should always be non-NULL since that was checked in the * 'while' condition above. @@ -106,7 +101,31 @@ static inline void sched_kucleanup(void) kumm_free(address); } } +#endif +} + +/**************************************************************************** + * Name: sched_have_kugarbage + * + * Description: + * Return TRUE if there is user heap garbage to be collected. + * + * Input parameters: + * None + * + * Returned Value: + * TRUE if there is kernel heap garbage to be collected. + * + ****************************************************************************/ + +#ifndef CONFIG_BUILD_KERNEL +static inline bool sched_have_kugarbage(void) +{ + return (g_delayed_kufree.head != NULL); } +#else +# define sched_have_kugarbage() false +#endif /**************************************************************************** * Name: sched_kcleanup @@ -126,22 +145,22 @@ static inline void sched_kucleanup(void) defined(CONFIG_MM_KERNEL_HEAP) static inline void sched_kcleanup(void) { - irqstate_t flags; - FAR void *address; + irqstate_t flags; + FAR void *address; - /* Test if the delayed deallocation queue is empty. No special protection - * is needed because this is an atomic test. - */ + /* Test if the delayed deallocation queue is empty. No special protection + * is needed because this is an atomic test. + */ - while (g_delayed_kfree.head) + while (g_delayed_kfree.head) { /* Remove the first delayed deallocation. This is not atomic and so * we must disable interrupts around the queue operation. */ - flags = irqsave(); - address = (FAR void*)sq_remfirst((FAR sq_queue_t*)&g_delayed_kfree); - irqrestore(flags); + flags = enter_critical_section(); + address = (FAR void *)sq_remfirst((FAR sq_queue_t *)&g_delayed_kfree); + leave_critical_section(flags); /* The address should always be non-NULL since that was checked in the * 'while' condition above. @@ -159,11 +178,36 @@ static inline void sched_kcleanup(void) # define sched_kcleanup() #endif +/**************************************************************************** + * Name: sched_have_kgarbage + * + * Description: + * Return TRUE if there is kernal heap garbage to be collected. + * + * Input parameters: + * None + * + * Returned Value: + * TRUE if there is kernel heap garbage to be collected. + * + ****************************************************************************/ + +#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ + defined(CONFIG_MM_KERNEL_HEAP) +static inline bool sched_have_kgarbage(void) +{ + return (g_delayed_kfree.head != NULL); +} +#else +# define sched_have_kgarbage() false +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ + /**************************************************************************** - * Name: sched_garbagecollection + * Name: sched_garbage_collection * * Description: * Clean-up memory de-allocations that we queued because they could not @@ -184,13 +228,41 @@ static inline void sched_kcleanup(void) * ****************************************************************************/ -void sched_garbagecollection(void) +void sched_garbage_collection(void) { /* Handle deferred deallocations for the kernel heap */ sched_kcleanup(); - /* Handle deferred dealloctions for the user heap */ + /* Handle deferred deallocations for the user heap */ sched_kucleanup(); } + +/**************************************************************************** + * Name: sched_have_garbage + * + * Description: + * Return TRUE if there is garbage to be collected. + * + * Is is not a good idea for the IDLE threads to take the KMM semaphore. + * That can cause the IDLE thread to take processing time from higher + * priority tasks. The IDLE threads will only take the KMM semaphore if + * there is garbage to be collected. + * + * Certainly there is a race condition involved in sampling the garbage + * state. The looping nature of the IDLE loops should catch any missed + * garbage from the test on the next time arround. + * + * Input parameters: + * None + * + * Returned Value: + * TRUE if there is garbage to be collected. + * + ****************************************************************************/ + +bool sched_have_garbage(void) +{ + return (sched_have_kgarbage() || sched_have_kugarbage()); +} diff --git a/sched/sched/sched_getaffinity.c b/sched/sched/sched_getaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..e7d355b50fef628d72ca5b21040c5411a2c087e7 --- /dev/null +++ b/sched/sched/sched_getaffinity.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * sched/sched/sched_getaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_getscheduler + * + * Description: + * sched_getaffinity() writes the affinity mask of the thread whose ID + * is pid into the cpu_set_t pointed to by mask. The cpusetsize + * argument specifies the size (in bytes) of mask. If pid is zero, then + * the mask of the calling thread is returned. + * + * Inputs: + * pid - The ID of thread whose affinity set will be retrieved. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - The location to return the thread's new affinity set. + * + * Return Value: + * 0 if successful. Otherwise, ERROR (-1) is returned, and errno is + * set appropriately: + * + * ESRCH The task whose ID is pid could not be found. + * + ****************************************************************************/ + +int sched_getaffinity(pid_t pid, size_t cpusetsize, FAR cpu_set_t *mask) +{ + FAR struct tcb_s *tcb; + + DEBUGASSERT(cpusetsize == sizeof(cpu_set_t) && mask != NULL); + + /* Verify that the PID corresponds to a real task */ + + sched_lock(); + if (!pid) + { + tcb = this_task(); + } + else + { + tcb = sched_gettcb(pid); + } + + if (tcb == NULL) + { + set_errno(ESRCH); + return ERROR; + } + + /* Return the affinity mask from the TCB. */ + + *mask = tcb->affinity; + sched_unlock(); + return OK; +} diff --git a/sched/sched/sched_getfiles.c b/sched/sched/sched_getfiles.c index b31999371fefd67b162dec06efe5798d9d80587f..7e634053d925fe1588c393397570c38312f70671 100644 --- a/sched/sched/sched_getfiles.c +++ b/sched/sched/sched_getfiles.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_getfiles.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,25 +31,25 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include "sched/sched.h" -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_getfiles * * Description: @@ -63,13 +63,13 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 FAR struct filelist *sched_getfiles(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; /* The group may be NULL under certain conditions. For example, if diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c index b42c8316033e8a51988c013fd40b406ff3c22d5f..155049ff1f7e510c2b7a73dd06a439158db42c34 100644 --- a/sched/sched/sched_getparam.c +++ b/sched/sched/sched_getparam.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_getparam.c * * Copyright (C) 2007, 2009, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,35 +45,11 @@ #include "clock/clock.h" #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_getparam * * Description: @@ -95,7 +71,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int sched_getparam (pid_t pid, FAR struct sched_param *param) { @@ -110,12 +86,12 @@ int sched_getparam (pid_t pid, FAR struct sched_param *param) /* Check if the task to restart is the calling task */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); if ((pid == 0) || (pid == rtcb->pid)) { - /* Return the priority if the calling task. */ + /* Return the priority if the calling task. */ - param->sched_priority = (int)rtcb->sched_priority; + param->sched_priority = (int)rtcb->sched_priority; } /* Ths pid is not for the calling task, we will have to look it up */ diff --git a/sched/sched/sched_getscheduler.c b/sched/sched/sched_getscheduler.c index 58714df1554c505e72a8973c75cde9d2b9128e7c..47ba73fa9cc6c952999158673798cf20db7cbc4d 100644 --- a/sched/sched/sched_getscheduler.c +++ b/sched/sched/sched_getscheduler.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_getscheduler.c * * Copyright (C) 2007, 2009, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -47,35 +47,11 @@ #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_getscheduler * * Description: @@ -96,7 +72,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int sched_getscheduler(pid_t pid) { @@ -107,7 +83,7 @@ int sched_getscheduler(pid_t pid) if (!pid) { - tcb = (struct tcb_s*)g_readytorun.head; + tcb = this_task(); } else { diff --git a/sched/sched/sched_getsockets.c b/sched/sched/sched_getsockets.c index 764e2ffd2156c46d0cc33b24124de3f71c6dbf86..2601f90783a9b1343fe5c6e1950b7c8e4fa28993 100644 --- a/sched/sched/sched_getsockets.c +++ b/sched/sched/sched_getsockets.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_getsockets.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,15 +44,11 @@ #if CONFIG_NSOCKET_DESCRIPTORS > 0 -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_getsockets * * Description: @@ -66,11 +62,11 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ FAR struct socketlist *sched_getsockets(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; DEBUGASSERT(group); diff --git a/sched/sched/sched_getstreams.c b/sched/sched/sched_getstreams.c index a87c95306c8210e75f273f1fa69f67f71b637baf..91f3c9f6f35a8c147466879e480243b92b935408 100644 --- a/sched/sched/sched_getstreams.c +++ b/sched/sched/sched_getstreams.c @@ -41,10 +41,6 @@ #include #include "sched/sched.h" -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -69,7 +65,7 @@ FAR struct streamlist *sched_getstreams(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; DEBUGASSERT(group); diff --git a/sched/sched/sched_gettcb.c b/sched/sched/sched_gettcb.c index f54e51571d9ba42c5dd35953aa09fd6ad5a0db39..a5fc20c2787db7854fdafbd4bc3b17ddad0c9e65 100644 --- a/sched/sched/sched_gettcb.c +++ b/sched/sched/sched_gettcb.c @@ -43,26 +43,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -84,7 +64,7 @@ FAR struct tcb_s *sched_gettcb(pid_t pid) /* Verify that the PID is within range */ - if (pid >= 0 ) + if (pid >= 0) { /* Get the hash_ndx associated with the pid */ diff --git a/sched/sched/sched_lock.c b/sched/sched/sched_lock.c index e07a7433b141302b5ff9c29b59e4d519bf05d229..529ba4a07f04e3632014ac722f0721799a34c330 100644 --- a/sched/sched/sched_lock.c +++ b/sched/sched/sched_lock.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_lock.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,49 +31,98 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include +#include #include #include #include -#include "sched/sched.h" - -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ +#include -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ +#include "sched/sched.h" -/************************************************************************ - * Private Functionss - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ -/************************************************************************ +/* Pre-emption is disabled via the interface sched_lock(). sched_lock() + * works by preventing context switches from the currently executing tasks. + * This prevents other tasks from running (without disabling interrupts) and + * gives the currently executing task exclusive access to the (single) CPU + * resources. Thus, sched_lock() and its companion, sched_unlcok(), are + * used to implement some critical sections. + * + * In the single CPU case, Pre-emption is disabled using a simple lockcount + * in the TCB. When the scheduling is locked, the lockcount is incremented; + * when the scheduler is unlocked, the lockcount is decremented. If the + * lockcount for the task at the head of the g_readytorun list has a + * lockcount > 0, then pre-emption is disabled. + * + * No special protection is required since only the executing task can + * modify its lockcount. + */ + +#ifdef CONFIG_SMP +/* In the multiple CPU, SMP case, disabling context switches will not give a + * task exclusive access to the (multiple) CPU resources (at least without + * stopping the other CPUs): Even though pre-emption is disabled, other + * threads will still be executing on the other CPUS. + * + * There are additional rules for this multi-CPU case: + * + * 1. There is a global lock count 'g_cpu_lockset' that includes a bit for + * each CPU: If the bit is '1', then the corresponding CPU has the + * scheduler locked; if '0', then the CPU does not have the scheduler + * locked. + * 2. Scheduling logic would set the bit associated with the cpu in + * 'g_cpu_lockset' when the TCB at the head of the g_assignedtasks[cpu] + * list transitions has 'lockcount' > 0. This might happen when sched_lock() + * is called, or after a context switch that changes the TCB at the + * head of the g_assignedtasks[cpu] list. + * 3. Similarly, the cpu bit in the global 'g_cpu_lockset' would be cleared + * when the TCB at the head of the g_assignedtasks[cpu] list has + * 'lockcount' == 0. This might happen when sched_unlock() is called, or + * after a context switch that changes the TCB at the head of the + * g_assignedtasks[cpu] list. + * 4. Modification of the global 'g_cpu_lockset' must be protected by a + * spinlock, 'g_cpu_schedlock'. That spinlock would be taken when + * sched_lock() is called, and released when sched_unlock() is called. + * This assures that the scheduler does enforce the critical section. + * NOTE: Because of this spinlock, there should never be more than one + * bit set in 'g_cpu_lockset'; attempts to set additional bits should + * be cause the CPU to block on the spinlock. However, additional bits + * could get set in 'g_cpu_lockset' due to the context switches on the + * various CPUs. + * 5. Each the time the head of a g_assignedtasks[] list changes and the + * scheduler modifies 'g_cpu_lockset', it must also set 'g_cpu_schedlock' + * depending on the new state of 'g_cpu_lockset'. + * 5. Logic that currently uses the currently running tasks lockcount + * instead uses the global 'g_cpu_schedlock'. A value of SP_UNLOCKED + * means that no CPU has pre-emption disabled; SP_LOCKED means that at + * least one CPU has pre-emption disabled. + */ + +volatile spinlock_t g_cpu_schedlock = SP_UNLOCKED; + +/* Used to keep track of which CPU(s) hold the IRQ lock. */ + +volatile spinlock_t g_cpu_locksetlock; +volatile cpu_set_t g_cpu_lockset; + +#endif /* CONFIG_SMP */ + +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_lock * * Description: @@ -89,21 +138,72 @@ * Return Value: * OK on success; ERROR on failure * - ************************************************************************/ + ****************************************************************************/ int sched_lock(void) { - struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); - /* Check for some special cases: (1) rtcb may be NULL only during - * early boot-up phases, and (2) sched_lock() should have no - * effect if called from the interrupt level. + /* Check for some special cases: (1) rtcb may be NULL only during early + * boot-up phases, and (2) sched_lock() should have no effect if called + * from the interrupt level. */ if (rtcb && !up_interrupt_context()) { - ASSERT(rtcb->lockcount < MAX_LOCK_COUNT); - rtcb->lockcount++; + /* Catch attempts to increment the lockcount beyound the range of the + * integer type. + */ + + DEBUGASSERT(rtcb->lockcount < MAX_LOCK_COUNT); + +#ifdef CONFIG_SMP + /* We must hold the lock on this CPU before we increment the lockcount + * for the first time. Holding the lock is sufficient to lockout context + * switching. + */ + + if (rtcb->lockcount == 0) + { + /* We don't have the scheduler locked. But logic running on a + * different CPU may have the scheduler locked. It is not + * possible for some other task on this CPU to have the scheduler + * locked (or we would not be executing!). + * + * If the scheduler is locked on another CPU, then we for the lock. + */ + + spin_setbit(&g_cpu_lockset, this_cpu(), &g_cpu_locksetlock, + &g_cpu_schedlock); + } + else + { + /* If this thread already has the scheduler locked, then + * g_cpu_schedlock() should indicate that the scheduler is locked + * and g_cpu_lockset should include the bit setting for this CPU. + */ + + DEBUGASSERT(g_cpu_schedlock == SP_LOCKED && + (g_cpu_lockset & (1 << this_cpu())) != 0); + } +#endif + + /* A counter is used to support locking. This allows nested lock + * operations on this thread (on any CPU) + */ + + rtcb->lockcount++; + +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION + /* Check if we just acquired the lock */ + + if (rtcb->lockcount == 1) + { + /* Note that we have pre-emption locked */ + + sched_note_premption(rtcb, true); + } +#endif } return OK; diff --git a/sched/sched/sched_lockcount.c b/sched/sched/sched_lockcount.c index 72561650c4d08951b2fe8e651e3a44553c76b323..c3a8ef19030f8fa30c83a5003e12a82f037ffebb 100644 --- a/sched/sched/sched_lockcount.c +++ b/sched/sched/sched_lockcount.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_lockcount.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,35 +43,11 @@ #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ - * Private Functionss - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_lockcount * * Description: @@ -87,11 +63,10 @@ * Return Value: * lockcount * - ************************************************************************/ + ****************************************************************************/ int sched_lockcount(void) { - struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); return (int)rtcb->lockcount; } - diff --git a/sched/sched/sched_mergepending.c b/sched/sched/sched_mergepending.c index 6ba03662a0b7e6e1b6f0884495240da30fb4e57d..e314e31d69c9e35746bf75a8013b4746814e02cb 100644 --- a/sched/sched/sched_mergepending.c +++ b/sched/sched/sched_mergepending.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_mergepending.c * - * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,123 +44,113 @@ #include #include -#include "sched/sched.h" - -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ +#include -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ +#include "sched/sched.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_mergepending * * Description: * This function merges the prioritized g_pendingtasks list into the - * prioritized g_readytorun task list. + * prioritized ready-to-run task list. * * Inputs: * None * * Return Value: - * true if the head of the g_readytorun task list has changed. + * true if the head of the ready-to-run task list has changed indicating + * a context switch is needed. * * Assumptions: * - The caller has established a critical section before * calling this function (calling sched_lock() first is NOT - * a good idea -- use irqsave()). + * a good idea -- use enter_critical_section()). * - The caller handles the condition that occurs if the * the head of the sched_mergTSTATE_TASK_PENDINGs is changed. * - ************************************************************************/ + ****************************************************************************/ +#ifndef CONFIG_SMP bool sched_mergepending(void) { - FAR struct tcb_s *pndtcb; - FAR struct tcb_s *pndnext; - FAR struct tcb_s *rtrtcb; - FAR struct tcb_s *rtrprev; + FAR struct tcb_s *ptcb; + FAR struct tcb_s *pnext; + FAR struct tcb_s *rtcb; + FAR struct tcb_s *rprev; bool ret = false; /* Initialize the inner search loop */ - rtrtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); /* Process every TCB in the g_pendingtasks list */ - for (pndtcb = (FAR struct tcb_s*)g_pendingtasks.head; pndtcb; pndtcb = pndnext) + for (ptcb = (FAR struct tcb_s *)g_pendingtasks.head; + ptcb; + ptcb = pnext) { - pndnext = pndtcb->flink; + pnext = ptcb->flink; + + /* REVISIT: Why don't we just remove the ptcb from pending task list + * and call sched_addreadytorun? + */ - /* Search the g_readytorun list to find the location to insert the - * new pndtcb. Each is list is maintained in ascending sched_priority + /* Search the ready-to-run list to find the location to insert the + * new ptcb. Each is list is maintained in ascending sched_priority * order. */ for (; - (rtrtcb && pndtcb->sched_priority <= rtrtcb->sched_priority); - rtrtcb = rtrtcb->flink); + (rtcb && ptcb->sched_priority <= rtcb->sched_priority); + rtcb = rtcb->flink); - /* Add the pndtcb to the spot found in the list. Check if the - * pndtcb goes at the ends of the g_readytorun list. This would be + /* Add the ptcb to the spot found in the list. Check if the + * ptcb goes at the ends of the ready-to-run list. This would be * error condition since the idle test must always be at the end of - * the g_readytorun list! + * the ready-to-run list! */ - ASSERT(rtrtcb); + ASSERT(rtcb); - /* The pndtcb goes just before rtrtcb */ + /* The ptcb goes just before rtcb */ - rtrprev = rtrtcb->blink; - if (!rtrprev) + rprev = rtcb->blink; + if (!rprev) { - /* Special case: Inserting pndtcb at the head of the list */ + /* Special case: Inserting ptcb at the head of the list */ /* Inform the instrumentation layer that we are switching tasks */ - sched_note_switch(rtrtcb, pndtcb); + sched_note_switch(rtcb, ptcb); /* Then insert at the head of the list */ - pndtcb->flink = rtrtcb; - pndtcb->blink = NULL; - rtrtcb->blink = pndtcb; - g_readytorun.head = (FAR dq_entry_t*)pndtcb; - rtrtcb->task_state = TSTATE_TASK_READYTORUN; - pndtcb->task_state = TSTATE_TASK_RUNNING; - ret = true; + ptcb->flink = rtcb; + ptcb->blink = NULL; + rtcb->blink = ptcb; + g_readytorun.head = (FAR dq_entry_t *)ptcb; + rtcb->task_state = TSTATE_TASK_READYTORUN; + ptcb->task_state = TSTATE_TASK_RUNNING; + ret = true; } else { /* Insert in the middle of the list */ - pndtcb->flink = rtrtcb; - pndtcb->blink = rtrprev; - rtrprev->flink = pndtcb; - rtrtcb->blink = pndtcb; - pndtcb->task_state = TSTATE_TASK_READYTORUN; + ptcb->flink = rtcb; + ptcb->blink = rprev; + rprev->flink = ptcb; + rtcb->blink = ptcb; + ptcb->task_state = TSTATE_TASK_READYTORUN; } /* Set up for the next time through */ - rtrtcb = pndtcb; + rtcb = ptcb; } /* Mark the input list empty */ @@ -170,3 +160,48 @@ bool sched_mergepending(void) return ret; } +#endif /* !CONFIG_SMP */ + +/**************************************************************************** + * Name: sched_mergepending + * + * Description: + * This function merges the prioritized g_pendingtasks list into the + * prioritized ready-to-run task list. + * + * Inputs: + * None + * + * Return Value: + * true if the head of the ready-to-run task list has changed indicating + * a context switch is needed. + * + * Assumptions: + * - The caller has established a critical section before + * calling this function (calling sched_lock() first is NOT + * a good idea -- use enter_critical_section()). + * - The caller handles the condition that occurs if the + * the head of the sched_mergTSTATE_TASK_PENDINGs is changed. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +bool sched_mergepending(void) +{ + FAR struct tcb_s *ptcb; + bool ret = false; + + /* Remove and process every TCB in the g_pendingtasks list */ + + for (ptcb = (FAR struct tcb_s *)dq_remfirst((FAR dq_queue_t *)&g_pendingtasks); + ptcb != NULL; + ptcb = (FAR struct tcb_s *)dq_remfirst((FAR dq_queue_t *)&g_pendingtasks)) + { + /* Add the pending task to the correct ready-to-run list */ + + ret |= sched_addreadytorun(ptcb); + } + + return ret; +} +#endif /* CONFIG_SMP */ diff --git a/sched/sched/sched_note.c b/sched/sched/sched_note.c new file mode 100644 index 0000000000000000000000000000000000000000..83f14a637660c1bdd7008448f6df53f209f5b6f6 --- /dev/null +++ b/sched/sched/sched_note.c @@ -0,0 +1,548 @@ +/**************************************************************************** + * sched/sched/sched_note.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_SCHED_INSTRUMENTATION_BUFFER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct note_info_s +{ + unsigned int ni_head; + unsigned int ni_tail; + uint8_t ni_buffer[CONFIG_SCHED_NOTE_BUFSIZE]; +}; + +struct note_startalloc_s +{ + uint8_t nsa_length; + uint8_t nsa_type; + uint8_t nsa_systime[4]; + uint8_t nsa_pid[2]; +#if CONFIG_TASK_NAME_SIZE > 0 + char nsa_name[CONFIG_TASK_NAME_SIZE + 1]; +#endif +}; + +#if CONFIG_TASK_NAME_SIZE > 0 +# define SIZEOF_NOTE_START(n) (sizeof(struct note_start_s) + (n) - 1) +#else +# define SIZEOF_NOTE_START(n) (sizeof(struct note_start_s)) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct note_info_s g_note_info; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: note_next + * + * Description: + * Return the circular buffer index at offset from the specified index + * value, handling wraparound + * + * Input Parameters: + * ndx - Old circular buffer index + * + * Returned Value: + * New circular buffer index + * + ****************************************************************************/ + +static inline unsigned int note_next(unsigned int ndx, unsigned int offset) +{ + ndx += offset; + if (ndx >= CONFIG_SCHED_NOTE_BUFSIZE) + { + ndx -= CONFIG_SCHED_NOTE_BUFSIZE; + } + + return ndx; +} + +/**************************************************************************** + * Name: note_systime + * + * Description: + * Save the current system time in the note structure as a 32-bit value. + * + * Input Parameters: + * note - The note structure to use + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void note_systime(FAR struct note_common_s *note) +{ + uint32_t systime = (uint32_t)clock_systimer(); + + /* Save the LS 32-bits of the system timer in little endian order */ + + note->nc_systime[0] = (uint8_t)( systime & 0xff); + note->nc_systime[1] = (uint8_t)((systime >> 8) & 0xff); + note->nc_systime[2] = (uint8_t)((systime >> 16) & 0xff); + note->nc_systime[3] = (uint8_t)((systime >> 24) & 0xff); +} + +/**************************************************************************** + * Name: note_length + * + * Description: + * Length of data currently in circular buffer. + * + * Input Parameters: + * None + * + * Returned Value: + * Length of data currently in circular buffer. + * + ****************************************************************************/ + +static unsigned int note_length(void) +{ + unsigned int head = g_note_info.ni_head; + unsigned int tail = g_note_info.ni_tail; + + if (tail > head) + { + head += CONFIG_SCHED_NOTE_BUFSIZE; + } + + return head - tail; +} + +/**************************************************************************** + * Name: note_remove + * + * Description: + * Remove the variable length note from the tail of the circular buffer + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * We are within a critical section. + * + ****************************************************************************/ + +static void note_remove(void) +{ + FAR struct note_common_s *note; + unsigned int tail; + unsigned int length; + + /* Get the tail index of the circular buffer */ + + tail = g_note_info.ni_tail; + DEBUGASSERT(tail < CONFIG_SCHED_NOTE_BUFSIZE); + + /* Get the length of the note at the tail index */ + + note = (FAR struct note_common_s *)&g_note_info.ni_buffer[tail]; + length = note->nc_length; + DEBUGASSERT(length <= note_length()); + + /* Increment the tail index to remove the entire note from the circular + * buffer. + */ + + g_note_info.ni_tail = note_next(tail, length); +} + +/**************************************************************************** + * Name: note_add + * + * Description: + * Add the variable length note to the head of the circular buffer + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * We are within a critical section. + * + ****************************************************************************/ + +static void note_add(FAR const uint8_t *note, uint8_t notelen) +{ + unsigned int head; + unsigned int next; + + /* Get the index to the head of the circular buffer */ + + DEBUGASSERT(note != NULL && notelen < CONFIG_SCHED_NOTE_BUFSIZE); + head = g_note_info.ni_head; + + /* Loop until all bytes have been transferred to the circular buffer */ + + while (notelen > 0) + { + /* Get the next head index. Would it collide with the current tail + * index? + */ + + next = note_next(head, 1); + if (next == g_note_info.ni_tail) + { + /* Yes, then remove the note at the tail index */ + + note_remove(); + } + + /* Save the next byte at the head index */ + + g_note_info.ni_buffer[head] = *note++; + + head = next; + notelen--; + } + + g_note_info.ni_head = head; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_note_* + * + * Description: + * These are the hooks into the scheduling instrumentation logic. Each + * simply formats the note associated with the schedule event and adds + * that note to the circular buffer. + * + * Input Parameters: + * tcb - The TCB of the thread. + * + * Returned Value: + * None + * + * Assumptions: + * We are within a critical section. + * + ****************************************************************************/ + +void sched_note_start(FAR struct tcb_s *tcb) +{ + struct note_startalloc_s note; + unsigned int length; +#if CONFIG_TASK_NAME_SIZE > 0 + int namelen; +#endif + + /* Copy the task name (if possible) and get the length of the note */ + +#if CONFIG_TASK_NAME_SIZE > 0 + namelen = strlen(tcb->name); + + DEBUGASSERT(namelen <= CONFIG_TASK_NAME_SIZE); + strncpy(note.nsa_name, tcb->name, CONFIG_TASK_NAME_SIZE + 1); + + length = SIZEOF_NOTE_START(namelen + 1); +#else + length = SIZEOF_NOTE_START(0) +#endif + + /* Finish formatting the note */ + + note.nsa_length = length; + note.nsa_type = NOTE_START; + note.nsa_pid[0] = (uint8_t)(tcb->pid & 0xff); + note.nsa_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); + + note_systime((FAR struct note_common_s *)¬e); + + /* Add the note to circular buffer */ + + note_add((FAR const uint8_t *)¬e, length); +} + +void sched_note_stop(FAR struct tcb_s *tcb) +{ + struct note_stop_s note; + + /* Format the note */ + + note.nsp_length = sizeof(struct note_stop_s); + note.nsp_type = NOTE_STOP; + note.nsp_pid[0] = (uint8_t)(tcb->pid & 0xff); + note.nsp_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); + + note_systime((FAR struct note_common_s *)¬e); + + /* Add the note to circular buffer */ + + note_add((FAR const uint8_t *)¬e, sizeof(struct note_stop_s)); +} + +void sched_note_switch(FAR struct tcb_s *fromtcb, FAR struct tcb_s *totcb) +{ + struct note_switch_s note; + + /* Format the note */ + + note.nsw_length = sizeof(struct note_switch_s); + note.nsw_type = NOTE_SWITCH; + note.nsw_pidout[0] = (uint8_t)(fromtcb->pid & 0xff); + note.nsw_pidout[1] = (uint8_t)((fromtcb->pid >> 8) & 0xff); + note.nsw_pidin[0] = (uint8_t)(totcb->pid & 0xff); + note.nsw_pidin[1] = (uint8_t)((totcb->pid >> 8) & 0xff); + + note_systime((FAR struct note_common_s *)¬e); + + /* Add the note to circular buffer */ + + note_add((FAR const uint8_t *)¬e, sizeof(struct note_switch_s)); +} + +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION +void sched_note_premption(FAR struct tcb_s *tcb, bool locked) +{ + struct note_preempt_s note; + + /* Format the note */ + + note.npr_length = sizeof(struct note_preempt_s); + note.npr_type = locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK; + note.npr_pid[0] = (uint8_t)(tcb->pid & 0xff); + note.npr_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); + note.npr_count[0] = (uint8_t)(tcb->lockcount & 0xff); + note.npr_count[1] = (uint8_t)((tcb->lockcount >> 8) & 0xff); + + note_systime((FAR struct note_common_s *)¬e); + + /* Add the note to circular buffer */ + + note_add((FAR const uint8_t *)¬e, sizeof(struct note_preempt_s)); +} +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION +void sched_note_csection(FAR struct tcb_s *tcb, bool enter) +{ + struct note_preempt_s note; + + /* Format the note */ + + note.ncs_length = sizeof(struct note_preempt_s); + note.ncs_type = enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE; + note.ncs_pid[0] = (uint8_t)(tcb->pid & 0xff); + note.ncs_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); +#ifdef CONFIG_SMP + note.ncs_count[0] = (uint8_t)(tcb->irqcount & 0xff); + note.ncs_count[1] = (uint8_t)((tcb->irqcount >> 8) & 0xff); +#endif + + note_systime((FAR struct note_common_s *)¬e); + + /* Add the note to circular buffer */ + + note_add((FAR const uint8_t *)¬e, sizeof(struct note_preempt_s)); +} +#endif + +/**************************************************************************** + * Name: sched_note_get + * + * Description: + * Remove the next note from the tail of the circular buffer. The note + * is also removed from the circular buffer to make room for futher notes. + * + * Input Parameters: + * buffer - Location to return the next note + * buflen - The length of the user provided buffer. + * + * Returned Value: + * On success, the positive, non-zero length of the return note is + * provided. Zero is returned only if ther circular buffer is empty. A + * negated errno value is returned in the event of any failure. + * + ****************************************************************************/ + +ssize_t sched_note_get(FAR uint8_t *buffer, size_t buflen) +{ + FAR struct note_common_s *note; + irqstate_t flags; + unsigned int remaining; + unsigned int tail; + ssize_t notelen; + size_t circlen; + + DEBUGASSERT(buffer != NULL); + flags = enter_critical_section(); + + /* Verify that the circular buffer is not empty */ + + circlen = note_length(); + if (circlen <= 0) + { + notelen = 0; + goto errout_with_csection; + } + + /* Get the index to the tail of the circular buffer */ + + tail = g_note_info.ni_tail; + DEBUGASSERT(tail < CONFIG_SCHED_NOTE_BUFSIZE); + + /* Get the length of the note at the tail index */ + + note = (FAR struct note_common_s *)&g_note_info.ni_buffer[tail]; + notelen = note->nc_length; + DEBUGASSERT(notelen <= circlen); + + /* Is the user buffer large enough to hold the note? */ + + if (buflen < notelen) + { + /* Remove the large note so that we do not get constipated. */ + + note_remove(); + + /* and return and error */ + + notelen = -EFBIG; + goto errout_with_csection; + } + + /* Loop until the note has been transferred to the user buffer */ + + remaining = (unsigned int)notelen; + while (remaining > 0) + { + /* Copy the next byte at the tail index */ + + *buffer++ = g_note_info.ni_buffer[tail]; + + /* Adjust indices and counts */ + + tail = note_next(tail, 1); + remaining--; + } + + g_note_info.ni_tail = tail; + +errout_with_csection: + leave_critical_section(flags); + return notelen; +} + +/**************************************************************************** + * Name: sched_note_size + * + * Description: + * Return the size of the next note at the tail of the circular buffer. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero is returned if the circular buffer is empty. Otherwise, the size + * of the next note is returned. + * + ****************************************************************************/ + +ssize_t sched_note_size(void) +{ + FAR struct note_common_s *note; + irqstate_t flags; + unsigned int tail; + ssize_t notelen; + size_t circlen; + + DEBUGASSERT(buffer != NULL); + flags = enter_critical_section(); + + /* Verify that the circular buffer is not empty */ + + circlen = note_length(); + if (circlen <= 0) + { + notelen = 0; + goto errout_with_csection; + } + + /* Get the index to the tail of the circular buffer */ + + tail = g_note_info.ni_tail; + DEBUGASSERT(tail < CONFIG_SCHED_NOTE_BUFSIZE); + + /* Get the length of the note at the tail index */ + + note = (FAR struct note_common_s *)&g_note_info.ni_buffer[tail]; + notelen = note->nc_length; + DEBUGASSERT(notelen <= circlen); + +errout_with_csection: + leave_critical_section(flags); + return notelen; +} + +#endif /* CONFIG_SCHED_INSTRUMENTATION_BUFFER */ diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 05f9bfdf8bd842c5a0f9ac2bbf923fa12d88dbf3..33c3f583ac87ea13e1efde53dc7c9a95d06003b5 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_processtimer.c * * Copyright (C) 2007, 2009, 2014-2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -50,31 +50,19 @@ #include "wdog/wdog.h" #include "clock/clock.h" -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_SCHED_CPULOAD_TIMECONSTANT # define CONFIG_SCHED_CPULOAD_TIMECONSTANT 2 #endif -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_process_scheduler * * Description: @@ -87,12 +75,12 @@ * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ #if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) static inline void sched_process_scheduler(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #if CONFIG_RR_INTERVAL > 0 /* Check if the currently executing task uses round robin scheduling. */ @@ -124,19 +112,19 @@ static inline void sched_process_scheduler(void) # define sched_process_scheduler() #endif -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * System Timer Hooks * * These are standard interfaces that are exported by the OS * for use by the architecture specific logic * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_process_timer * * Description: @@ -152,7 +140,7 @@ static inline void sched_process_scheduler(void) * Return Value: * None * - ************************************************************************/ + ****************************************************************************/ void sched_process_timer(void) { diff --git a/sched/sched/sched_releasetcb.c b/sched/sched/sched_releasetcb.c index 79fcb20105573f9fdd1bc46ee530835c85fe289f..b7046aa790ae94516ff498ea92f474a853b32daa 100644 --- a/sched/sched/sched_releasetcb.c +++ b/sched/sched/sched_releasetcb.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_releasetcb.c * * Copyright (C) 2007, 2009, 2012-2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,16 +50,16 @@ #include "group/group.h" #include "timer/timer.h" -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_releasepid * * Description: When a task is destroyed, this function must * be called to make its process ID available for re-use. - ************************************************************************/ + ****************************************************************************/ static void sched_releasepid(pid_t pid) { @@ -84,11 +84,11 @@ static void sched_releasepid(pid_t pid) #endif } -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_releasetcb * * Description: @@ -108,7 +108,7 @@ static void sched_releasepid(pid_t pid) * Assumptions: * Interrupts are disabled. * - ************************************************************************/ + ****************************************************************************/ int sched_releasetcb(FAR struct tcb_s *tcb, uint8_t ttype) { @@ -124,7 +124,7 @@ int sched_releasetcb(FAR struct tcb_s *tcb, uint8_t ttype) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS - if (timer_deleteall != NULL) + if (timer_deleteall != NULL) #endif { timer_deleteall(tcb->pid); diff --git a/sched/sched/sched_removeblocked.c b/sched/sched/sched_removeblocked.c index b17ec045a186318fafd99c44db7ce60eaf8c7c6f..36c92e96f0893301032ab2825fe6e6892d563b02 100644 --- a/sched/sched/sched_removeblocked.c +++ b/sched/sched/sched_removeblocked.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_removeblocked.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,31 +44,11 @@ #include "sched/sched.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_removeblocked * * Description: @@ -85,7 +65,7 @@ * - The caller has established a critical section before * calling this function. * - ************************************************************************/ + ****************************************************************************/ void sched_removeblocked(FAR struct tcb_s *btcb) { @@ -93,14 +73,14 @@ void sched_removeblocked(FAR struct tcb_s *btcb) /* Make sure the TCB is in a valid blocked state */ - ASSERT(task_state >= FIRST_BLOCKED_STATE && - task_state <= LAST_BLOCKED_STATE); + DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE && + task_state <= LAST_BLOCKED_STATE); /* Remove the TCB from the blocked task list associated * with this state */ - dq_rem((FAR dq_entry_t*)btcb, (dq_queue_t*)g_tasklisttable[task_state].list); + dq_rem((FAR dq_entry_t *)btcb, TLIST_BLOCKED(task_state)); /* Make sure the TCB's state corresponds to not being in * any list @@ -108,4 +88,3 @@ void sched_removeblocked(FAR struct tcb_s *btcb) btcb->task_state = TSTATE_TASK_INVALID; } - diff --git a/sched/sched/sched_removereadytorun.c b/sched/sched/sched_removereadytorun.c index 0fdcc1a2947c0e43d58a467e158ce1f0d1c1f78d..84d3b25c111702f8aa1208057373ee6ce1566609 100644 --- a/sched/sched/sched_removereadytorun.c +++ b/sched/sched/sched_removereadytorun.c @@ -1,7 +1,7 @@ /**************************************************************************** * shced/sched_removereadytorun.c * - * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,31 +43,76 @@ #include #include +#include + +#include "irq/irq.h" #include "sched/sched.h" /**************************************************************************** - * Pre-processor Definitions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Private Type Declarations + * Name: sched_removereadytorun + * + * Description: + * This function removes a TCB from the ready to run list. + * + * Inputs: + * rtcb - Points to the TCB that is ready-to-run + * + * Return Value: + * true if the currently active task (the head of the ready-to-run list) + * has changed. + * + * Assumptions: + * - The caller has established a critical section before calling this + * function (calling sched_lock() first is NOT a good idea -- use + * enter_critical_section()). + * - The caller handles the condition that occurs if the head of the + * ready-to-run list is changed. + * ****************************************************************************/ -/**************************************************************************** - * Global Variables - ****************************************************************************/ +#ifndef CONFIG_SMP +bool sched_removereadytorun(FAR struct tcb_s *rtcb) +{ + bool doswitch = false; -/**************************************************************************** - * Private Variables - ****************************************************************************/ + /* Check if the TCB to be removed is at the head of the ready to run list. + * There is only one list, g_readytorun, and it always contains the + * currently running task. If we are removing the head of this list, + * then we are removing the currently active task. + */ -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ + if (rtcb->blink == NULL) + { + /* There must always be at least one task in the list (the IDLE task) + * after the TCB being removed. + */ -/**************************************************************************** - * Public Functions - ****************************************************************************/ + FAR struct tcb_s *ntcb = (FAR struct tcb_s *)rtcb->flink; + DEBUGASSERT(ntcb != NULL); + + /* Inform the instrumentation layer that we are switching tasks */ + + sched_note_switch(rtcb, ntcb); + ntcb->task_state = TSTATE_TASK_RUNNING; + doswitch = true; + } + + /* Remove the TCB from the ready-to-run list. In the non-SMP case, this + * is always the g_readytorun list. + */ + + dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun); + + /* Since the TCB is not in any list, it is now invalid */ + + rtcb->task_state = TSTATE_TASK_INVALID; + return doswitch; +} +#endif /* !CONFIG_SMP */ /**************************************************************************** * Name: sched_removereadytorun @@ -79,46 +124,145 @@ * rtcb - Points to the TCB that is ready-to-run * * Return Value: - * true if the currently active task (the head of the - * g_readytorun list) has changed. + * true if the currently active task (the head of the ready-to-run list) + * has changed. * * Assumptions: * - The caller has established a critical section before calling this - * function (calling sched_lock() first is NOT a good idea -- use irqsave()). - * - The caller handles the condition that occurs if the - * the head of the g_readytorun list is changed. + * function (calling sched_lock() first is NOT a good idea -- use + * enter_critical_section()). + * - The caller handles the condition that occurs if the head of the + * ready-to-run list is changed. * ****************************************************************************/ +#ifdef CONFIG_SMP bool sched_removereadytorun(FAR struct tcb_s *rtcb) { - FAR struct tcb_s *ntcb = NULL; - bool ret = false; + FAR dq_queue_t *tasklist; + bool doswitch = false; + int cpu; - /* Check if the TCB to be removed is at the head of the ready to run list. - * In this case, we are removing the currently active task. + /* Which CPU (if any) is the task running on? Which task list holds the + * TCB? + */ + + cpu = rtcb->cpu; + tasklist = TLIST_HEAD(rtcb->task_state, cpu); + + /* Check if the TCB to be removed is at the head of a ready to run list. + * For the case of SMP, there are two lists involved: (1) the + * g_readytorun list that holds non-running tasks that have not been + * assigned to a CPU, and (2) and the g_assignedtasks[] lists which hold + * tasks assigned a CPU, including the task that is currently running on + * that CPU. Only this latter list contains the currently active task + * only only removing the head of that list can result in a context + * switch. + * + * The tasklist RUNNABLE attribute will inform us if the list holds the + * currently executing and task and, hence, if a context switch could + * occur. */ - if (!rtcb->blink) + if (rtcb->blink == NULL && TLIST_ISRUNNABLE(rtcb->task_state)) { - /* There must always be at least one task in the list (the idle task) */ + FAR struct tcb_s *ntcb; + int me; + + /* There must always be at least one task in the list (the IDLE task) + * after the TCB being removed. + */ ntcb = (FAR struct tcb_s *)rtcb->flink; DEBUGASSERT(ntcb != NULL); + /* If we are modifying the head of some assigned task list other than + * our own, we will need to stop that CPU. + */ + + me = this_cpu(); + if (cpu != me) + { + DEBUGVERIFY(up_cpu_pause(cpu)); + } + + /* Will pre-emption be disabled after the switch? If the lockcount is + * greater than zero, then this task/this CPU holds the scheduler lock. + */ + + if (ntcb->lockcount > 0) + { + /* Yes... make sure that scheduling logic knows about this */ + + spin_setbit(&g_cpu_lockset, cpu, &g_cpu_locksetlock, + &g_cpu_schedlock); + } + else + { + /* No.. we may need to perform release our hold on the lock. */ + + spin_clrbit(&g_cpu_lockset, cpu, &g_cpu_locksetlock, + &g_cpu_schedlock); + } + + /* Interrupts may be disabled after the switch. If irqcount is greater + * than zero, then this task/this CPU holds the IRQ lock + */ + + if (ntcb->irqcount > 0) + { + /* Yes... make sure that scheduling logic knows about this */ + + spin_setbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock, + &g_cpu_irqlock); + } + else + { + /* No.. we may need to perform release our hold on the lock. */ + + spin_setbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock, + &g_cpu_irqlock); + } + /* Inform the instrumentation layer that we are switching tasks */ sched_note_switch(rtcb, ntcb); ntcb->task_state = TSTATE_TASK_RUNNING; - ret = true; - } - /* Remove the TCB from the ready-to-run list */ + /* The task is running but the CPU that it was running on has been + * paused. We can now safely remove its TCB from the ready-to-run + * task list. In the SMP case this may be either the g_readytorun() + * or the g_assignedtasks[cpu] list. + */ - dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun); + dq_rem((FAR dq_entry_t *)rtcb, tasklist); - /* Since the TCB is not in any list, it is now invalid */ + /* All done, restart the other CPU (if it was paused). */ + + doswitch = true; + if (cpu != me) + { + /* In this we will not want to report a context switch to this + * CPU. Only the other CPU is affected. + */ + + DEBUGVERIFY(up_cpu_resume(cpu)); + doswitch = false; + } + } + else + { + /* The task is not running. Just remove its TCB from the ready-to-run + * list. In the SMP case this may be either the g_readytorun() or the + * g_assignedtasks[cpu] list. + */ + + dq_rem((FAR dq_entry_t *)rtcb, tasklist); + } + + /* Since the TCB is no longer in any list, it is now invalid */ rtcb->task_state = TSTATE_TASK_INVALID; - return ret; + return doswitch; } +#endif /* CONFIG_SMP */ diff --git a/sched/sched/sched_reprioritize.c b/sched/sched/sched_reprioritize.c index 6728547d2aee1d3b0d3723a594cd2934fd2eb746..d9431cf165e83a98a904f7e8ab198a1112a5360f 100644 --- a/sched/sched/sched_reprioritize.c +++ b/sched/sched/sched_reprioritize.c @@ -47,30 +47,6 @@ #ifdef CONFIG_PRIORITY_INHERITANCE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -112,16 +88,16 @@ int sched_reprioritize(FAR struct tcb_s *tcb, int sched_priority) int ret = sched_setpriority(tcb, sched_priority); if (ret == 0) { - /* Reset the base_priority -- the priority that the thread would return - * to once it posts the semaphore. - */ + /* Reset the base_priority -- the priority that the thread would return + * to once it posts the semaphore. + */ - tcb->base_priority = (uint8_t)sched_priority; + tcb->base_priority = (uint8_t)sched_priority; - /* Discard any pending reprioritizations as well */ + /* Discard any pending reprioritizations as well */ #if CONFIG_SEM_NNESTPRIO > 0 - tcb->npend_reprio = 0; + tcb->npend_reprio = 0; #endif } diff --git a/sched/sched/sched_roundrobin.c b/sched/sched/sched_roundrobin.c index 0c369dd02eeef9451609a6c02961c5abe4658ae7..bf856004d67024d5882e22e28af0cc83b6916ed5 100644 --- a/sched/sched/sched_roundrobin.c +++ b/sched/sched/sched_roundrobin.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_roundrobin.c * - * Copyright (C) 2007, 2009, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -51,9 +51,9 @@ #if CONFIG_RR_INTERVAL > 0 -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ #ifndef MIN # define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -63,11 +63,11 @@ # define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_roundrobin_process * * Description: @@ -94,7 +94,7 @@ * - The task associated with TCB uses the round robin scheduling * policy * - ************************************************************************/ + ****************************************************************************/ uint32_t sched_roundrobin_process(FAR struct tcb_s *tcb, uint32_t ticks, bool noswitches) @@ -124,7 +124,7 @@ uint32_t sched_roundrobin_process(FAR struct tcb_s *tcb, uint32_t ticks, */ ret = tcb->timeslice; - if (tcb->timeslice <= 0 && tcb->lockcount == 0) + if (tcb->timeslice <= 0 && !sched_islocked(tcb)) { /* We will also suppress context switches if we were called via one * of the unusual cases handled by sched_timer_reasses(). In that diff --git a/sched/sched/sched_rrgetinterval.c b/sched/sched/sched_rrgetinterval.c index bb8a0152a201967b06bac25937882e2cbaf36f84..3faefb44d2d9f193e3d1580e2092c407239af08d 100644 --- a/sched/sched/sched_rrgetinterval.c +++ b/sched/sched/sched_rrgetinterval.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_rrgetinterval.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -48,11 +48,11 @@ #include "sched/sched.h" #include "clock/clock.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_rr_get_interval * * Description: @@ -78,7 +78,7 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int sched_rr_get_interval(pid_t pid, struct timespec *interval) { @@ -91,7 +91,7 @@ int sched_rr_get_interval(pid_t pid, struct timespec *interval) if (!pid) { - rrtcb = (FAR struct tcb_s*)g_readytorun.head; + rrtcb = this_task(); } /* Return a special error code on invalid PID */ diff --git a/sched/sched/sched_self.c b/sched/sched/sched_self.c index 75e4084cd8ee8a5dbe20e59176de86d58fc3f865..97ba42d6045a397164dc17f245094f7a1356fbd9 100644 --- a/sched/sched/sched_self.c +++ b/sched/sched/sched_self.c @@ -41,26 +41,6 @@ #include #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -77,7 +57,5 @@ FAR struct tcb_s *sched_self(void) { - return (FAR struct tcb_s*)g_readytorun.head; + return this_task(); } - - diff --git a/sched/sched/sched_setaffinity.c b/sched/sched/sched_setaffinity.c new file mode 100644 index 0000000000000000000000000000000000000000..c2d50af146d368dbd1a5e212ea7fe730e1db7fdf --- /dev/null +++ b/sched/sched/sched_setaffinity.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * sched/sched/sched_setaffinity.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_getscheduler + * + * Description: + * sched_setaffinity() sets the CPU affinity mask of the thread whose ID + * is pid to the value specified by mask. If pid is zero, then the + * calling thread is used. The argument cpusetsize is the length (i + * bytes) of the data pointed to by mask. Normally this argument would + * be specified as sizeof(cpu_set_t). + * + * If the thread specified by pid is not currently running on one of the + * CPUs specified in mask, then that thread is migrated to one of the + * CPUs specified in mask. + * + * Inputs: + * pid - The ID of thread whose affinity set will be modified. + * cpusetsize - Size of cpuset. MUST be sizeofcpu_set_t(). + * cpuset - The location to return the thread's new affinity set. + * + * Return Value: + * 0 if successful. Otherwise, ERROR (-1) is returned, and errno is + * set appropriately: + * + * ESRCH The task whose ID is pid could not be found. + * + ****************************************************************************/ + +int sched_setaffinity(pid_t pid, size_t cpusetsize, FAR const cpu_set_t *mask) +{ + FAR struct tcb_s *tcb; + irqstate_t flags; + int errcode = 0; + int ret; + + DEBUGASSERT(cpusetsize == sizeof(cpu_set_t) && mask != NULL); + + /* Verify that the PID corresponds to a real task */ + + sched_lock(); + if (!pid) + { + tcb = this_task(); + } + else + { + tcb = sched_gettcb(pid); + } + + if (tcb == NULL) + { + errcode = ESRCH; + goto errout_with_lock; + } + + /* Don't permit changing the affinity mask of any task locked to a CPU + * (i.e., an IDLE task) + */ + + flags = enter_critical_section(); + if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + errcode = EINVAL; + goto errout_with_csection; + } + + /* Set the new affinity mask. */ + + tcb->affinity = *mask; + + /* Is the task still executing a a CPU in its affinity mask? Will this + * change cause the task to be removed from its current assigned task + * list? + * + * First... is the task in an assigned task list? + */ + + if (tcb->task_state >= FIRST_ASSIGNED_STATE && + tcb->task_state <= LAST_ASSIGNED_STATE) + { + /* Yes... is the CPU associated with the assigned task in the new + * affinity mask? + */ + + if ((tcb->affinity & (1 << tcb->cpu)) == 0) + { + /* No.. then we will need to move the task from the the assigned + * task list to some other ready to run list. + * + * sched_setpriority() will do just what we want... it will remove + * the task from its current position in the some assigned task list + * and then simply put it back in the right place. This works even + * if the task is this task. + */ + + ret = sched_setpriority(tcb, tcb->sched_priority); + if (ret < 0) + { + errcode = get_errno(); + } + } + } + +errout_with_csection: + leave_critical_section(flags); +errout_with_lock: + sched_unlock(); + set_errno(errcode); + return ERROR; +} diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index fa355c884ae066bcc380223ff9279ad96e14d709..824d51b53b88ab75af65a3eea69a12c6f065e330 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_setparam.c * - * Copyright (C) 2007, 2009, 2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include #include +#include #include #include "clock/clock.h" @@ -106,7 +107,7 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) /* Check if the task to reprioritize is the calling task */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); if (pid == 0 || pid == rtcb->pid) { tcb = rtcb; @@ -179,7 +180,7 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) /* Stop/reset current sporadic scheduling */ - flags = irqsave(); + flags = enter_critical_section(); ret = sched_sporadic_reset(tcb); if (ret >= 0) { @@ -205,7 +206,7 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) /* Restore interrupts and handler errors */ - irqrestore(flags); + leave_critical_section(flags); if (ret < 0) { errcode = -ret; diff --git a/sched/sched/sched_setpriority.c b/sched/sched/sched_setpriority.c index a34fdba955b369d3b7e5fabdc59a6a0c4c9d36fe..9e2c9384aa9c434c7f067a15687d8a9b70f4c386 100644 --- a/sched/sched/sched_setpriority.c +++ b/sched/sched/sched_setpriority.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_setpriority.c * - * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,34 +42,203 @@ #include #include #include + +#include #include #include "sched/sched.h" /**************************************************************************** - * Pre-processor Definitions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Private Type Declarations + * Name: sched_running_setpriority + * + * Description: + * This function sets the priority of a running task. This does nothing + * if we are increasing the priority of a running task. If we are dropping + * the priority of a running task, then this could cause then next lower + * priority task to run, + * + * NOTE: Setting a task's priority to the same value has a similar effect + * to sched_yield() -- The task will be moved to after all other tasks + * with the same priority. + * + * Inputs: + * tcb - the TCB of task to reprioritize. + * sched_priority - The new task priority + * + * Return Value: + * None + * ****************************************************************************/ -/**************************************************************************** - * Global Variables - ****************************************************************************/ +static inline void sched_running_setpriority(FAR struct tcb_s *tcb, + int sched_priority) +{ + /* A context switch will occur if the new priority of the running + * task becomes less than OR EQUAL TO the next highest priority + * ready to run task. + */ -/**************************************************************************** - * Private Variables - ****************************************************************************/ + if (sched_priority <= tcb->flink->sched_priority) + { + /* A context switch will occur. */ + + up_reprioritize_rtr(tcb, (uint8_t)sched_priority); + } + + /* Otherwise, we can just change priority since it has no effect */ + + else + { + /* Change the task priority */ + + tcb->sched_priority = (uint8_t)sched_priority; + } +} /**************************************************************************** - * Private Function Prototypes + * Name: sched_readytorun_setpriority + * + * Description: + * This function sets the priority of a ready-to-run task. This may alter + * the position of the task in the ready-to-run list and if the priority + * is increased, may cause the task to become running. + * + * Inputs: + * tcb - the TCB of task to reprioritize. + * sched_priority - The new task priority + * + * Return Value: + * None + * ****************************************************************************/ +static void sched_readytorun_setpriority(FAR struct tcb_s *tcb, + int sched_priority) +{ + FAR struct tcb_s *rtcb; + +#ifdef CONFIG_SMP + int cpu; + + /* CASE 2a. The task is ready-to-run (but not running) but not assigned to + * a CPU. An increase in priority could cause a context switch may be caused + * by the re-prioritization. The task is not assigned and may run on any CPU. + */ + + if (tcb->task_state == TSTATE_TASK_READYTORUN) + { + cpu = sched_cpu_select(tcb->affinity); + } + + /* CASE 2b. The task is ready to run, and assigned to a CPU. An increase + * in priority could cause this task to become running but the task can + * only run on its assigned CPU. + */ + + else + { + cpu = tcb->cpu; + } + + /* The running task is the the task at the head of the g_assignedtasks[] + * associated with the selected CPU. + */ + + rtcb = current_task(cpu); + +#else + /* CASE 2. The task is ready-to-run (but not running) and a context switch + * may be caused by the re-prioritization. + */ + + rtcb = this_task(); +#endif + + /* A context switch will occur if the new priority of the ready-to-run + * task is (strictly) greater than the current running task + */ + + if (sched_priority > rtcb->sched_priority) + { + /* A context switch will occur. */ + + up_reprioritize_rtr(tcb, (uint8_t)sched_priority); + } + + /* Otherwise, we can just change priority and re-schedule (since it have + * no other effect). + */ + + else + { + /* Remove the TCB from the ready-to-run task list that it resides in */ + + ASSERT(!sched_removereadytorun(tcb)); + + /* Change the task priority */ + + tcb->sched_priority = (uint8_t)sched_priority; + + /* Put it back into the correct ready-to-run task list */ + + ASSERT(!sched_addreadytorun(tcb)); + } +} + /**************************************************************************** - * Private Functions + * Name: sched_blocked_setpriority + * + * Description: + * Change the priority of a blocked tasks. The only issue here is that + * the task may like in a prioritized or an non-prioritized queue. + * + * Inputs: + * tcb - the TCB of task to reprioritize. + * sched_priority - The new task priority + * + * Return Value: + * None + * ****************************************************************************/ +static inline void sched_blocked_setpriority(FAR struct tcb_s *tcb, + int sched_priority) +{ + FAR dq_queue_t *tasklist; + tstate_t task_state = tcb->task_state; + + /* CASE 3a. The task resides in a prioritized list. */ + + tasklist = TLIST_BLOCKED(task_state); + if (TLIST_ISPRIORITIZED(task_state)) + { + /* Remove the TCB from the prioritized task list */ + + dq_rem((FAR dq_entry_t *)tcb, tasklist); + + /* Change the task priority */ + + tcb->sched_priority = (uint8_t)sched_priority; + + /* Put it back into the prioritized list at the correct position. */ + + sched_addprioritized(tcb, tasklist); + } + + /* CASE 3b. The task resides in a non-prioritized list. */ + + else + { + /* Just change the task's priority */ + + tcb->sched_priority = (uint8_t)sched_priority; + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -81,7 +250,7 @@ * This function sets the priority of a specified task. * * NOTE: Setting a task's priority to the same value has a similar effect - * to sched_yield() -- The task will be moved to after all other tasks + * to sched_yield() -- The task will be moved to after all other tasks * with the same priority. * * Inputs: @@ -103,9 +272,7 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - tstate_t task_state; - irqstate_t saved_state; + irqstate_t flags; /* Verify that the requested priority is in the valid range */ @@ -120,114 +287,41 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority) * performing the following. */ - saved_state = irqsave(); + flags = enter_critical_section(); - /* There are four cases that must be considered: */ + /* There are three major cases (and two sub-cases) that must be considered: */ - task_state = tcb->task_state; - switch (task_state) + switch (tcb->task_state) { - /* CASE 1. The task is running or ready-to-run and a context switch - * may be caused by the re-prioritization + /* CASE 1. The task is running and a context switch may be caused by + * the re-prioritization */ case TSTATE_TASK_RUNNING: - - /* A context switch will occur if the new priority of the running - * task becomes less than OR EQUAL TO the next highest priority - * ready to run task. - */ - - if (sched_priority <= tcb->flink->sched_priority) - { - /* A context switch will occur. */ - - up_reprioritize_rtr(tcb, (uint8_t)sched_priority); - } - - /* Otherwise, we can just change priority since it has no effect */ - - else - { - /* Change the task priority */ - - tcb->sched_priority = (uint8_t)sched_priority; - } + sched_running_setpriority(tcb, sched_priority); break; - /* CASE 2. The task is running or ready-to-run and a context switch - * may be caused by the re-prioritization + /* CASE 2. The task is ready-to-run (but not running) and a context + * switch may be caused by the re-prioritization */ case TSTATE_TASK_READYTORUN: - - /* A context switch will occur if the new priority of the ready-to - * run task is (strictly) greater than the current running task - */ - - if (sched_priority > rtcb->sched_priority) - { - /* A context switch will occur. */ - - up_reprioritize_rtr(tcb, (uint8_t)sched_priority); - } - - /* Otherwise, we can just change priority and re-schedule (since it - * have no other effect). - */ - - else - { - /* Remove the TCB from the ready-to-run task list */ - - ASSERT(!sched_removereadytorun(tcb)); - - /* Change the task priority */ - - tcb->sched_priority = (uint8_t)sched_priority; - - /* Put it back into the ready-to-run task list */ - - ASSERT(!sched_addreadytorun(tcb)); - } +#ifdef CONFIG_SMP + case TSTATE_TASK_ASSIGNED: +#endif + sched_readytorun_setpriority(tcb, sched_priority); break; + /* CASE 3. The task is not in the ready to run list. Changing its * Priority cannot effect the currently executing task. */ default: - - /* CASE 3a. The task resides in a prioritized list. */ - - if (g_tasklisttable[task_state].prioritized) - { - /* Remove the TCB from the prioritized task list */ - - dq_rem((FAR dq_entry_t*)tcb, (FAR dq_queue_t*)g_tasklisttable[task_state].list); - - /* Change the task priority */ - - tcb->sched_priority = (uint8_t)sched_priority; - - /* Put it back into the prioritized list at the correct - * position - */ - - sched_addprioritized(tcb, (FAR dq_queue_t*)g_tasklisttable[task_state].list); - } - - /* CASE 3b. The task resides in a non-prioritized list. */ - - else - { - /* Just change the task's priority */ - - tcb->sched_priority = (uint8_t)sched_priority; - } + sched_blocked_setpriority(tcb, sched_priority); break; } - irqrestore(saved_state); + leave_critical_section(flags); return OK; } diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index 841d9eb1659026ed72a50685d1071e0fefbe2a2b..20026e7ec95d1a56c9f871243674349c0790a070 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_setscheduler.c * - * Copyright (C) 2007, 2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include #include +#include #include #include "sched/sched.h" @@ -86,7 +87,7 @@ int sched_setscheduler(pid_t pid, int policy, FAR const struct sched_param *param) { FAR struct tcb_s *tcb; - irqstate_t saved_state; + irqstate_t flags; #ifdef CONFIG_SCHED_SPORADIC int errcode; #endif @@ -109,7 +110,7 @@ int sched_setscheduler(pid_t pid, int policy, /* Check if the task to modify the calling task */ - if (pid == 0 ) + if (pid == 0) { pid = getpid(); } @@ -131,8 +132,8 @@ int sched_setscheduler(pid_t pid, int policy, /* Further, disable timer interrupts while we set up scheduling policy. */ - saved_state = irqsave(); - tcb->flags &= TCB_FLAG_POLICY_MASK; + flags = enter_critical_section(); + tcb->flags &= ~TCB_FLAG_POLICY_MASK; switch (policy) { default: @@ -273,7 +274,7 @@ int sched_setscheduler(pid_t pid, int policy, #endif } - irqrestore(saved_state); + leave_critical_section(flags); /* Set the new priority */ @@ -284,7 +285,7 @@ int sched_setscheduler(pid_t pid, int policy, #ifdef CONFIG_SCHED_SPORADIC errout_with_irq: set_errno(errcode); - irqrestore(saved_state); + leave_critical_section(flags); sched_unlock(); return ERROR; #endif diff --git a/sched/sched/sched_sporadic.c b/sched/sched/sched_sporadic.c old mode 100755 new mode 100644 index afd3325de5106272d72a14efc23ec82d9e35b015..d31837d3f1af7e8f8d9f6288e4a5ba9349b94bae --- a/sched/sched/sched_sporadic.c +++ b/sched/sched/sched_sporadic.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_sporadic.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -452,7 +452,7 @@ static void sporadic_budget_expire(int argc, wdparm_t arg1, ...) * this operation is needed. */ - if (tcb->lockcount > 0) + if (sched_islocked(tcb)) { DEBUGASSERT((mrepl->flags && SPORADIC_FLAG_ALLOCED) != 0 && sporadic->nrepls > 0); @@ -600,7 +600,7 @@ static void sporadic_replenish_expire(int argc, wdparm_t arg1, ...) * this operation is needed. */ - if (tcb->lockcount > 0) + if (sched_islocked(tcb)) { /* Set the timeslice to the magic value */ @@ -768,16 +768,16 @@ int sched_sporadic_initialize(FAR struct tcb_s *tcb) * sporadic scheduling parameters and state data. */ - sporadic = (FAR struct sporadic_s *)kmm_zalloc(sizeof(struct sporadic_s)); - if (sporadic == NULL) - { - slldbg("ERROR: Failed to allocate sporadic data structure\n"); - return -ENOMEM; - } + sporadic = (FAR struct sporadic_s *)kmm_zalloc(sizeof(struct sporadic_s)); + if (sporadic == NULL) + { + slldbg("ERROR: Failed to allocate sporadic data structure\n"); + return -ENOMEM; + } - /* The initialize required is to set the back pointer to the TCB in - * each of the replenishment structures. - */ + /* The initialize required is to set the back pointer to the TCB in + * each of the replenishment structures. + */ for (i = 0; i < CONFIG_SCHED_SPORADIC_MAXREPL; i++) { @@ -975,9 +975,9 @@ int sched_sporadic_resume(FAR struct tcb_s *tcb) { FAR struct sporadic_s *sporadic; FAR struct replenishment_s *repl; + systime_t now; uint32_t unrealized; uint32_t last; - uint32_t now; DEBUGASSERT(tcb && tcb->sporadic); sporadic = tcb->sporadic; @@ -1145,7 +1145,7 @@ int sched_sporadic_suspend(FAR struct tcb_s *tcb) * * Input Parameters: * tcb - The TCB of the thread that is beginning sporadic - scheduling. + * scheduling. * ticks - The number of elapsed ticks since the last time this * function was called. * noswitches - We are running in a context where context switching is @@ -1199,7 +1199,7 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks, /* Does the thread have the scheduler locked? */ sporadic = tcb->sporadic; - if (tcb->lockcount > 0) + if (sched_islocked(tcb)) { /* Yes... then we have no option but to give the thread more * time at the higher priority. Dropping the priority could diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 7546ec8046a4ae742465e12efbaf3ff3c863aa35..ee340996870ba42e1ba0c2b2250605ffc266be6f 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_timerexpiration.c * * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -55,9 +55,9 @@ #ifdef CONFIG_SCHED_TICKLESS -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ /* In the original design, it was planned that sched_timer_reasses() be * called whenever there was a change at the head of the ready-to-run * list. That call was intended to establish a new time-slice or to @@ -87,9 +87,9 @@ # define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif -/************************************************************************ +/**************************************************************************** * Public Data - ************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP /* By default, the RTOS tickless logic assumes that range of times that can @@ -108,10 +108,10 @@ uint32_t g_oneshot_maxticks = UINT32_MAX; #endif -/************************************************************************ - * Private Variables - ************************************************************************/ -/* This is the duration of the currently active timer or, when +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the duration of the currently active timer or, when * sched_timer_expiration() is called, the duration of interval timer * that just expired. The value zero means that no timer was active. */ @@ -133,11 +133,11 @@ static struct timespec g_sched_time; static struct timespec g_stop_time; #endif -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_process_scheduler * * Description: @@ -159,13 +159,13 @@ static struct timespec g_stop_time; * that a context switch is needed now, but cannot be performed because * noswitches == true. * - ************************************************************************/ + ****************************************************************************/ #if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) static inline uint32_t sched_process_scheduler(uint32_t ticks, bool noswitches) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - FAR struct tcb_s *ntcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); + FAR struct tcb_s *ntcb = this_task(); uint32_t ret = 0; #if CONFIG_RR_INTERVAL > 0 @@ -211,16 +211,16 @@ static inline uint32_t sched_process_scheduler(uint32_t ticks, bool noswitches) /* If a context switch occurred, then need to return delay remaining for * the new task at the head of the ready to run list. */ - - ntcb = (FAR struct tcb_s*)g_readytorun.head; + + ntcb = this_task(); /* Check if the new task at the head of the ready-to-run has changed. */ if (rtcb != ntcb) { - /* Recurse just to get the correct return value */ + /* Recurse just to get the correct return value */ - return sched_process_scheduler(0, true); + return sched_process_scheduler(0, true); } /* Returning zero means that there is no interesting event to be timed */ @@ -271,9 +271,9 @@ static unsigned int sched_timer_process(unsigned int ticks, bool noswitches) rettime = tmp; } - /* Check for operations specific to scheduling policy of the currently - * active task. - */ + /* Check for operations specific to scheduling policy of the currently + * active task. + */ tmp = sched_process_scheduler(ticks, noswitches); if (tmp > 0 && tmp < cmptime) @@ -317,7 +317,7 @@ static void sched_timer_start(unsigned int ticks) { struct timespec ts; -#if CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP if (ticks > g_oneshot_maxticks) { ticks = g_oneshot_maxticks; @@ -355,9 +355,9 @@ static void sched_timer_start(unsigned int ticks) ret = up_alarm_start(&ts); #else - /* [Re-]start the interval timer */ + /* [Re-]start the interval timer */ - ret = up_timer_start(&ts); + ret = up_timer_start(&ts); #endif if (ret < 0) @@ -368,9 +368,9 @@ static void sched_timer_start(unsigned int ticks) } } -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: sched_alarm_expiration diff --git a/sched/sched/sched_unlock.c b/sched/sched/sched_unlock.c index 6ac0ad49ab4367da831b3122506bf5acd87e9486..9a6ff5a924857fc7ad46c2b58de69cc92fe81c20 100644 --- a/sched/sched/sched_unlock.c +++ b/sched/sched/sched_unlock.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/sched/sched_unlock.c * - * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,24 +31,26 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include +#include #include #include +#include #include "sched/sched.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sched_unlock * * Description: @@ -59,11 +61,11 @@ * decremented to zero, any tasks that were eligible to preempt the * current task will execute. * - ************************************************************************/ + ****************************************************************************/ int sched_unlock(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); /* Check for some special cases: (1) rtcb may be NULL only during * early boot-up phases, and (2) sched_unlock() should have no @@ -72,13 +74,13 @@ int sched_unlock(void) if (rtcb && !up_interrupt_context()) { - /* Prevent context switches throughout the following */ + /* Prevent context switches throughout the following. */ - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); /* Decrement the preemption lock counter */ - if (rtcb->lockcount) + if (rtcb->lockcount > 0) { rtcb->lockcount--; } @@ -89,13 +91,40 @@ int sched_unlock(void) if (rtcb->lockcount <= 0) { +#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION + /* Note that we no longer have pre-emption */ + + sched_note_premption(rtcb, false); +#endif + /* Set the lock count to zero */ + rtcb->lockcount = 0; +#ifdef CONFIG_SMP + /* The lockcount has decremented to zero and we need to perform + * release our hold on the lock. + */ + + DEBUGASSERT(g_cpu_schedlock == SP_LOCKED && + (g_cpu_lockset & (1 << this_cpu())) != 0); + + spin_clrbit(&g_cpu_lockset, this_cpu(), &g_cpu_locksetlock, + &g_cpu_schedlock); +#endif + /* Release any ready-to-run tasks that have collected in - * g_pendingtasks. + * g_pendingtasks. In the SMP case, the scheduler remains + * locked if interrupts are disabled. + * + * NOTE: This operation has a very high likelihood of causing + * this task to be switched out! */ - if (g_pendingtasks.head) +#ifdef CONFIG_SMP + if (g_pendingtasks.head != NULL && rtcb->irqcount <= 0) +#else + if (g_pendingtasks.head != NULL) +#endif { up_release_pending(); } @@ -118,7 +147,7 @@ int sched_unlock(void) * maximum. */ - if (rtcb != (FAR struct tcb_s*)g_readytorun.head) + if (rtcb != this_task()) { rtcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); } @@ -156,7 +185,7 @@ int sched_unlock(void) * change the currently active task. */ - if (rtcb == (FAR struct tcb_s*)g_readytorun.head) + if (rtcb == this_task()) { sched_timer_reassess(); } @@ -165,7 +194,7 @@ int sched_unlock(void) #endif } - irqrestore(flags); + leave_critical_section(flags); } return OK; diff --git a/sched/sched/sched_verifytcb.c b/sched/sched/sched_verifytcb.c index 33ead33f66e21967abcfb26d8994d011d27bdeb9..5958b28e0c0986a5a06552cc77554d14e0969ac1 100644 --- a/sched/sched/sched_verifytcb.c +++ b/sched/sched/sched_verifytcb.c @@ -44,26 +44,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/sched/sched_wait.c b/sched/sched/sched_wait.c index d2efd8ee2a5172167c747a507437a3a44d46b982..d1547e07cfa75c0784e1ff29f4fe4667bdb197e2 100644 --- a/sched/sched/sched_wait.c +++ b/sched/sched/sched_wait.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * sched/sched/sched_wait.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -49,15 +49,11 @@ #if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT) -/***************************************************************************** - * Private Functions - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: wait * * Description: @@ -80,7 +76,7 @@ * Returned Value: * See waitpid(); * - *****************************************************************************/ + ****************************************************************************/ pid_t wait(FAR int *stat_loc) { diff --git a/sched/sched/sched_waitid.c b/sched/sched/sched_waitid.c index 31a393861d62baa7d0737361e86e885353bced1d..c6fd8d4501c384201692cd7b50bff2d644cd5c67 100644 --- a/sched/sched/sched_waitid.c +++ b/sched/sched/sched_waitid.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * sched/sched/sched_waitid.c * * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -50,29 +50,30 @@ #if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT) -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: exited_child * * Description: * Handle the case where a child exited properlay was we (apparently) lost * the detch of child signal. * - *****************************************************************************/ + ****************************************************************************/ #ifdef CONFIG_SCHED_CHILD_STATUS static void exited_child(FAR struct tcb_s *rtcb, FAR struct child_status_s *child, FAR siginfo_t *info) { /* The child has exited. Return the saved exit status (and some fudged - * information. + * information). */ info->si_signo = SIGCHLD; info->si_code = CLD_EXITED; + info->si_errno = OK; info->si_value.sival_ptr = NULL; info->si_pid = child->ch_pid; info->si_status = child->ch_status; @@ -84,11 +85,11 @@ static void exited_child(FAR struct tcb_s *rtcb, FAR struct child_status_s *chil } #endif -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: waitid * * Description: @@ -149,11 +150,11 @@ static void exited_child(FAR struct tcb_s *rtcb, FAR struct child_status_s *chil * EINVAL - An invalid value was specified for options, or idtype and id * specify an invalid set of processes. * - *****************************************************************************/ + ****************************************************************************/ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *ctcb; #ifdef CONFIG_SCHED_CHILD_STATUS FAR struct child_status_s *child; @@ -224,9 +225,9 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) /* Does this task retain child status? */ - if (retains) + if (retains) { - /* Check if this specific pid has allocated child status? */ + /* Check if this specific pid has allocated child status? */ if (group_findchild(rtcb->group, (pid_t)id) == NULL) { @@ -247,7 +248,7 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) } else if (idtype == P_PID) { - /* Get the TCB corresponding to this PID and make sure it is our child. */ + /* Get the TCB corresponding to this PID and make sure it is our child. */ ctcb = sched_gettcb((pid_t)id); #ifdef HAVE_GROUP_MEMBERS @@ -264,7 +265,7 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options) /* Loop until the child that we are waiting for dies */ - for (;;) + for (; ; ) { #ifdef CONFIG_SCHED_CHILD_STATUS /* Check if the task has already died. Signals are not queued in diff --git a/sched/sched/sched_waitpid.c b/sched/sched/sched_waitpid.c index c612f85edb3bcdc85255611593f8482b6113803b..4a669958c7ca2061e62aa54580bb4b390d88f645 100644 --- a/sched/sched/sched_waitpid.c +++ b/sched/sched/sched_waitpid.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * sched/sched/sched_waitpid.c * * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -51,15 +51,11 @@ #ifdef CONFIG_SCHED_WAITPID -/***************************************************************************** - * Private Functions - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: waitpid * * Description: @@ -176,7 +172,7 @@ * defined), then waitpid() is still available, but does not obey the * restriction that the pid be a child of the caller. * - *****************************************************************************/ + ****************************************************************************/ #ifndef CONFIG_SCHED_HAVE_PARENT pid_t waitpid(pid_t pid, int *stat_loc, int options) @@ -212,11 +208,15 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) goto errout_with_errno; } - /* The the task group corresponding to this PID */ + /* Then the task group corresponding to this PID */ group = ctcb->group; DEBUGASSERT(group); + /* Lock this group so that it cannot be deleted until the wait completes */ + + group_addwaiter(group); + /* "If more than one thread is suspended in waitpid() awaiting termination of * the same process, exactly one thread will return the process status at the * time of the target process termination." Hmmm.. what do we return to the @@ -236,6 +236,8 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* Don't wait if status is not available */ ret = sem_trywait(&group->tg_exitsem); + group_delwaiter(group); + if (ret < 0) { pid = 0; @@ -246,6 +248,8 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* Wait if necessary for status to become available */ ret = sem_wait(&group->tg_exitsem); + group_delwaiter(group); + if (ret < 0) { /* Unlock pre-emption and return the ERROR (sem_wait has already set @@ -274,7 +278,7 @@ errout: return ERROR; } -/*************************************************************************** +/**************************************************************************** * * If CONFIG_SCHED_HAVE_PARENT is defined, then waitpid will use the SIGHCLD * signal. It can also handle the pid == (pid_t)-1 arguement. This is @@ -285,12 +289,12 @@ errout: * lost (or to have the data in the struct siginfo to be overwritten by * the next signal). * - ***************************************************************************/ + ****************************************************************************/ #else pid_t waitpid(pid_t pid, int *stat_loc, int options) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *ctcb; #ifdef CONFIG_SCHED_CHILD_STATUS FAR struct child_status_s *child; @@ -353,11 +357,11 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* Does this task retain child status? */ - if (retains) + if (retains) { - /* Check if this specific pid has allocated child status? */ + /* Check if this specific pid has allocated child status? */ - if (group_findchild(rtcb->group, pid) == NULL) + if (group_findchild(rtcb->group, pid) == NULL) { err = ECHILD; goto errout_with_errno; @@ -376,7 +380,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) } else if (pid != (pid_t)-1) { - /* Get the TCB corresponding to this PID and make sure it is our child. */ + /* Get the TCB corresponding to this PID and make sure it is our child. */ ctcb = sched_gettcb(pid); #ifdef HAVE_GROUP_MEMBERS @@ -394,7 +398,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* Loop until the child that we are waiting for dies */ - for (;;) + for (; ; ) { #ifdef CONFIG_SCHED_CHILD_STATUS /* Check if the task has already died. Signals are not queued in diff --git a/sched/sched/sched_yield.c b/sched/sched/sched_yield.c index 933d03ede2e964a1fcd6c552bee6801e33c5930e..c55a925dac044a8b7899a140ab49a468a308cbfe 100644 --- a/sched/sched/sched_yield.c +++ b/sched/sched/sched_yield.c @@ -43,30 +43,6 @@ #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -90,7 +66,7 @@ int sched_yield(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); /* This equivalent to just resetting the task priority to its current value * since this will cause the task to be rescheduled behind any other tasks diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 53b6a540ef12bb98afec6e7cd8da8b7a96459ab0..39ba7cd2dc5345a5d41b98dbdc2031dd7c5fa2cb 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # sched/semaphore/Make.defs # -# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. +# Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -35,12 +35,16 @@ CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c -CSRCS += sem_waitirq.c +CSRCS += sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sem_initialize.c sem_holder.c endif +ifeq ($(CONFIG_SPINLOCK),y) +CSRCS += spinlock.c +endif + # Include semaphore build support DEPPATH += --dep-path semaphore diff --git a/sched/semaphore/sem_destroy.c b/sched/semaphore/sem_destroy.c index 1d1a955d1028f39055a1edc4bd96717415b7646b..7518382bb93328210bb159f4bb5d9c75c27fc4c0 100644 --- a/sched/semaphore/sem_destroy.c +++ b/sched/semaphore/sem_destroy.c @@ -44,26 +44,6 @@ #include "semaphore/semaphore.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c index 22082b613069425f4cec385005fa50b066556644..854747cb01205b61f16d70d6d15001bdba8da9bd 100644 --- a/sched/semaphore/sem_holder.c +++ b/sched/semaphore/sem_holder.c @@ -68,11 +68,7 @@ typedef int (*holderhandler_t)(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg); /**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /* Preallocated holder structures */ @@ -82,10 +78,6 @@ static struct semholder_s g_holderalloc[CONFIG_SEM_PREALLOCHOLDERS]; static FAR struct semholder_s *g_freeholders; #endif -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Name: sem_allocholder ****************************************************************************/ @@ -290,10 +282,10 @@ static int sem_boostholderprio(FAR struct semholder_s *pholder, */ if (!sched_verifytcb(htcb)) - { + { sdbg("TCB 0x%08x is a stale handle, counts lost\n", htcb); sem_freeholder(sem, pholder); - } + } #if CONFIG_SEM_NNESTPRIO > 0 @@ -441,10 +433,10 @@ static int sem_restoreholderprio(FAR struct semholder_s *pholder, */ if (!sched_verifytcb(htcb)) - { + { sdbg("TCB 0x%08x is a stale handle, counts lost\n", htcb); sem_freeholder(sem, pholder); - } + } /* Was the priority of the holder thread boosted? If so, then drop its * priority back to the correct level. What is the correct level? @@ -573,7 +565,7 @@ static int sem_restoreholderprio(FAR struct semholder_s *pholder, static int sem_restoreholderprioA(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); if (pholder->htcb != rtcb) { return sem_restoreholderprio(pholder, sem, arg); @@ -593,7 +585,7 @@ static int sem_restoreholderprioA(FAR struct semholder_s *pholder, static int sem_restoreholderprioB(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); if (pholder->htcb == rtcb) { (void)sem_restoreholderprio(pholder, sem, arg); @@ -699,7 +691,7 @@ static inline void sem_restorebaseprio_irq(FAR struct tcb_s *stcb, static inline void sem_restorebaseprio_task(FAR struct tcb_s *stcb, FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct semholder_s *pholder; /* Perform the following actions only if a new thread was given a count. @@ -780,7 +772,7 @@ static inline void sem_restorebaseprio_task(FAR struct tcb_s *stcb, void sem_initholders(void) { #if CONFIG_SEM_PREALLOCHOLDERS > 0 - int i; + int i; /* Put all of the pre-allocated holder structures into the free list */ @@ -858,7 +850,7 @@ void sem_destroyholder(FAR sem_t *sem) void sem_addholder(FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct semholder_s *pholder; /* Find or allocate a container for this new holder */ @@ -893,7 +885,7 @@ void sem_addholder(FAR sem_t *sem) void sem_boostpriority(FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); /* Boost the priority of every thread holding counts on this semaphore * that are lower in priority than the new thread that is waiting for a @@ -922,7 +914,7 @@ void sem_boostpriority(FAR sem_t *sem) void sem_releaseholder(FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); FAR struct semholder_s *pholder; /* Find the container for this holder */ diff --git a/sched/semaphore/sem_post.c b/sched/semaphore/sem_post.c index 974b6d20be8ddd70a508a1bfbdaf071d3d403133..97235de42818534b5eab7df1cd34617d4cfea57b 100644 --- a/sched/semaphore/sem_post.c +++ b/sched/semaphore/sem_post.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_post.c * - * Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,31 +42,13 @@ #include #include #include + +#include #include #include "sched/sched.h" #include "semaphore/semaphore.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -101,7 +83,7 @@ int sem_post(FAR sem_t *sem) { FAR struct tcb_s *stcb = NULL; - irqstate_t saved_state; + irqstate_t flags; int ret = ERROR; /* Make sure we were supplied with a valid semaphore. */ @@ -113,7 +95,7 @@ int sem_post(FAR sem_t *sem) * handler. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Perform the semaphore unlock operation. */ @@ -144,7 +126,7 @@ int sem_post(FAR sem_t *sem) * that we want. */ - for (stcb = (FAR struct tcb_s*)g_waitingforsemaphore.head; + for (stcb = (FAR struct tcb_s *)g_waitingforsemaphore.head; (stcb && stcb->waitsem != sem); stcb = stcb->flink); @@ -173,7 +155,7 @@ int sem_post(FAR sem_t *sem) /* Interrupts may now be enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } return ret; diff --git a/sched/semaphore/sem_recover.c b/sched/semaphore/sem_recover.c index fd40e6b7dca54663376c133985b7a034be8149d8..8b2d105b39c2241084fcf990ac07df361dd15f30 100644 --- a/sched/semaphore/sem_recover.c +++ b/sched/semaphore/sem_recover.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_recover.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,35 +39,12 @@ #include +#include #include #include #include "semaphore/semaphore.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -115,7 +92,7 @@ void sem_recover(FAR struct tcb_s *tcb) * enforce that here). */ - flags = irqsave(); + flags = enter_critical_section(); if (tcb->task_state == TSTATE_WAIT_SEM) { sem_t *sem = tcb->waitsem; @@ -144,5 +121,5 @@ void sem_recover(FAR struct tcb_s *tcb) tcb->waitsem = NULL; } - irqrestore(flags); + leave_critical_section(flags); } diff --git a/sched/semaphore/sem_reset.c b/sched/semaphore/sem_reset.c new file mode 100644 index 0000000000000000000000000000000000000000..4f98d4e8e39215b9facb9b23a44842a8c1622dd6 --- /dev/null +++ b/sched/semaphore/sem_reset.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * sched/semaphore/sem_reset.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "semaphore/semaphore.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sem_reset + * + * Description: + * Reset a semaphore count to a specific value. This is similar to part + * of the operation of sem_init(). But sem_reset() may need to wake up + * tasks waiting on a count. This kind of operation is sometimes required + * within the OS (only) for certain error handling conditions. + * + * Parameters: + * sem - Semaphore descriptor to be reset + * count - The requested semaphore count + * + * Return Value: + * 0 (OK) or a negated errno value if unsuccessful + * + ****************************************************************************/ + +int sem_reset(FAR sem_t *sem, int16_t count) +{ + irqstate_t flags; + + DEBUGASSERT(sem != NULL && count >= 0); + + /* Don't allow any context switches that may result from the following + * sem_post() operations. + */ + + sched_lock(); + + /* Prevent any access to the semaphore by interrupt handlers while we are + * performing this operation. + */ + + flags = enter_critical_section(); + + /* A negative count indicates that the negated number of threads are + * waiting to take a count from the semaphore. Loop here, handing + * out counts to any waiting threads. + */ + + while (sem->semcount < 0 && count > 0) + { + /* Give out one counting, waking up one of the waiting threads + * and, perhaps, kicking off a lot of priority inheritance + * logic (REVISIT). + */ + + DEBUGVERIFY(sem_post(sem)); + count--; + } + + /* We exit the above loop with either (1) no threads waiting for the + * (i.e., with sem->semcount >= 0). In this case, 'count' holds the + * the new value of the semaphore count. OR (2) with threads still + * waiting but all of the semaphore counts exhausted: The current + * value of sem->semcount is already correct in this case. + */ + + if (sem->semcount >= 0) + { + sem->semcount = count; + } + + /* Allow any pending context switches to occur now */ + + leave_critical_section(flags); + sched_unlock(); + return OK; +} diff --git a/sched/semaphore/sem_tickwait.c b/sched/semaphore/sem_tickwait.c index 57e36d1f0cbc26b82bbdd38f0d2ef50a2bbc68cd..a76308154a828c17a889f957b1e14ab562b206d2 100644 --- a/sched/semaphore/sem_tickwait.c +++ b/sched/semaphore/sem_tickwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_tickdwait.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #include #include @@ -80,11 +81,11 @@ * ****************************************************************************/ -int sem_tickwait(FAR sem_t *sem, uint32_t start, uint32_t delay) +int sem_tickwait(FAR sem_t *sem, systime_t start, uint32_t delay) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); irqstate_t flags; - uint32_t elapsed; + systime_t elapsed; int ret; DEBUGASSERT(sem != NULL && up_interrupt_context() == false && @@ -109,7 +110,7 @@ int sem_tickwait(FAR sem_t *sem, uint32_t start, uint32_t delay) * enabled while we are blocked waiting for the semaphore. */ - flags = irqsave(); + flags = enter_critical_section(); /* Try to take the semaphore without waiting. */ @@ -136,7 +137,7 @@ int sem_tickwait(FAR sem_t *sem, uint32_t start, uint32_t delay) /* Adjust the delay for any time since the delay was calculated */ elapsed = clock_systimer() - start; - if (/*elapsed >= (UINT32_MAX / 2) || */ elapsed >= delay) + if (/* elapsed >= (UINT32_MAX / 2) || */ elapsed >= delay) { ret = -ETIMEDOUT; goto errout_with_irqdisabled; @@ -172,7 +173,7 @@ success_with_irqdisabled: /* Error exits */ errout_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); wd_delete(rtcb->waitdog); rtcb->waitdog = NULL; return ret; diff --git a/sched/semaphore/sem_timedwait.c b/sched/semaphore/sem_timedwait.c index 503aed2322716c094ad4d918d5ef9ef01f6b0a26..f006268c5cffc48f092cd30cf96079ddc40f907d 100644 --- a/sched/semaphore/sem_timedwait.c +++ b/sched/semaphore/sem_timedwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_timedwait.c * - * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -94,7 +95,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); irqstate_t flags; int ticks; int errcode; @@ -134,7 +135,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) * enabled while we are blocked waiting for the semaphore. */ - flags = irqsave(); + flags = enter_critical_section(); /* Try to take the semaphore without waiting. */ @@ -179,7 +180,6 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) /* Start the watchdog */ - errcode = OK; (void)wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid()); /* Now perform the blocking wait */ @@ -196,12 +196,17 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) wd_cancel(rtcb->waitdog); + if (errcode != OK) + { + goto errout_with_irqdisabled; + } + /* We can now restore interrupts and delete the watchdog */ /* Success exits */ success_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); wd_delete(rtcb->waitdog); rtcb->waitdog = NULL; return OK; @@ -209,7 +214,7 @@ success_with_irqdisabled: /* Error exits */ errout_with_irqdisabled: - irqrestore(flags); + leave_critical_section(flags); wd_delete(rtcb->waitdog); rtcb->waitdog = NULL; diff --git a/sched/semaphore/sem_timeout.c b/sched/semaphore/sem_timeout.c index 0bacd41237752c7b5e5648e11c2728a0e0aea4c8..542724a94cb0bde197bf9f7ba978924732d9de4c 100644 --- a/sched/semaphore/sem_timeout.c +++ b/sched/semaphore/sem_timeout.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include "semaphore/semaphore.h" @@ -78,7 +78,7 @@ void sem_timeout(int argc, wdparm_t pid) /* Disable interrupts to avoid race conditions */ - flags = irqsave(); + flags = enter_critical_section(); /* Get the TCB associated with this PID. It is possible that * task may no longer be active when this watchdog goes off. @@ -99,5 +99,5 @@ void sem_timeout(int argc, wdparm_t pid) /* Interrupts may now be enabled. */ - irqrestore(flags); + leave_critical_section(flags); } diff --git a/sched/semaphore/sem_trywait.c b/sched/semaphore/sem_trywait.c index ed8ceab707eb080d02383cf0d8a4db38e05ed548..37ba0d66e20034c37d13d71b68785cb8118dda2e 100644 --- a/sched/semaphore/sem_trywait.c +++ b/sched/semaphore/sem_trywait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_trywait.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,31 +43,13 @@ #include #include #include + +#include #include #include "sched/sched.h" #include "semaphore/semaphore.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -96,8 +78,8 @@ int sem_trywait(FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - irqstate_t saved_state; + FAR struct tcb_s *rtcb = this_task(); + irqstate_t flags; int ret = ERROR; /* This API should not be called from interrupt handlers */ @@ -114,7 +96,7 @@ int sem_trywait(FAR sem_t *sem) * because sem_post() may be called from an interrupt handler. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Any further errors could only occurr because the semaphore is not * available. @@ -135,7 +117,7 @@ int sem_trywait(FAR sem_t *sem) /* Interrupts may now be enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } return ret; diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c index f4e267f6aa192024ef258255e757ed32cceacbc7..86fb013696073248073bc176b0546782cbfd490f 100644 --- a/sched/semaphore/sem_wait.c +++ b/sched/semaphore/sem_wait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_wait.c * - * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,31 +43,13 @@ #include #include #include + +#include #include #include "sched/sched.h" #include "semaphore/semaphore.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -96,8 +78,8 @@ int sem_wait(FAR sem_t *sem) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - irqstate_t saved_state; + FAR struct tcb_s *rtcb = this_task(); + irqstate_t flags; int ret = ERROR; /* This API should not be called from interrupt handlers */ @@ -115,7 +97,7 @@ int sem_wait(FAR sem_t *sem) * handler. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Check if the lock is available */ @@ -206,7 +188,7 @@ int sem_wait(FAR sem_t *sem) /* Interrupts may now be enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } return ret; diff --git a/sched/semaphore/sem_waitirq.c b/sched/semaphore/sem_waitirq.c index e80ef66cd7b5fe82f5b3b9bf4268dbfd5bec7cf9..5ddafa62e02dbb4db8b8a995dcd307c2a856cd73 100644 --- a/sched/semaphore/sem_waitirq.c +++ b/sched/semaphore/sem_waitirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/semaphore/sem_waitirq.c * - * Copyright (C) 2007-2010, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,8 @@ #include #include + +#include #include #include "semaphore/semaphore.h" @@ -77,14 +79,14 @@ void sem_waitirq(FAR struct tcb_s *wtcb, int errcode) { - irqstate_t saved_state; + irqstate_t flags; /* Disable interrupts. This is necessary (unfortunately) because an * interrupt handler may attempt to post the semaphore while we are * doing this. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* It is possible that an interrupt/context switch beat us to the punch * and already changed the task's state. @@ -124,5 +126,5 @@ void sem_waitirq(FAR struct tcb_s *wtcb, int errcode) /* Interrupts may now be enabled. */ - irqrestore(saved_state); + leave_critical_section(flags); } diff --git a/sched/semaphore/semaphore.h b/sched/semaphore/semaphore.h index e40141c9cb2648be6ca716ecbd278a23d28c6ef6..85f4e6c876bad6aecd0bf1d8eceb0bc3a7a96cad 100644 --- a/sched/semaphore/semaphore.h +++ b/sched/semaphore/semaphore.h @@ -49,18 +49,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/sched/semaphore/spinlock.c b/sched/semaphore/spinlock.c new file mode 100644 index 0000000000000000000000000000000000000000..79d904e7efcb5a62bbf1eccee82c4e1322fc1e97 --- /dev/null +++ b/sched/semaphore/spinlock.c @@ -0,0 +1,371 @@ +/**************************************************************************** + * sched/semaphore/spinlock.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sched/sched.h" + +#ifdef CONFIG_SPINLOCK + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMPOSSIBLE_CPU 0xff + +/* REVISIT: What happens if a thread taks a spinlock while running on one + * CPU, but is suspended, then reassigned to another CPU where it runs and + * eventually calls spin_unlock(). One solution might be to lock a thread to + * a CPU if it holds a spinlock. That would assure that it never runs on + * any other CPU and avoids such complexities. + */ + +#undef CONFIG_SPINLOCK_LOCKDOWN /* Feature not yet available */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spin_initializer + * + * Description: + * Initialize a re-entrant spinlock object to its initial, unlocked state. + * + * Input Parameters: + * lock - A reference to the spinlock object to be initialized. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void spin_initializer(FAR struct spinlock_s *lock) +{ + DEBUGASSERT(lock != NULL); + + lock->sp_lock = SP_UNLOCKED; +#ifdef CONFIG_SMP + lock->sp_cpu = IMPOSSIBLE_CPU; + lock->sp_count = 0; +#endif +} + +/**************************************************************************** + * Name: spin_lock + * + * Description: + * If this CPU does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and is prone to deadlocks in + * the case that any logic on the same CPU attempts to take the lock + * more than one + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_lock(FAR volatile spinlock_t *lock) +{ + while (up_testset(lock) == SP_LOCKED) + { +#if 0 /* Would recurse */ + sched_yield(); +#endif + } +} + +/**************************************************************************** + * Name: spin_lockr + * + * Description: + * If this CPU does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is re-entrant in the sense that it can called + * numerous times from the same CPU without blocking. Of course, + * spin_unlock() must be called the same number of times. NOTE: the + * thread that originallly took the look may be executing on a different + * CPU when it unlocks the spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_lockr(FAR struct spinlock_s *lock) +{ +#ifdef CONFIG_SMP + irqstate_t flags; + uint8_t cpu = this_cpu(); + + /* Disable interrupts (all CPUs) */ + + flags = up_irq_save(); + + /* Do we already hold the lock on this CPU? */ + + if (lock->sp_cpu == cpu) + { + /* Yes... just increment the number of references we have on the lock */ + + lock->sp_count++; + DEBUGASSERT(lock->sp_lock = SP_LOCKED && lock->sp_count > 0); + } + else + { +#ifdef CONFIG_SPINLOCK_LOCKDOWN + /* REVISIT: What happens if this thread is suspended, then reassigned + * to another CPU where it runs and eventually calls spin_unlock(). + * One solution might be to lock a thread to a CPU if it holds a + * spinlock. That would assure that it never runs on any other CPU + * and avoids such complexities. + */ + +# warning Missing logic +#endif + /* Take the lock. REVISIT: We should set an indication in the TCB + * that the thread is spinning. This might be useful in determining + * some scheduling actions? + */ + + while (up_testset(&lock->sp_lock) == SP_LOCKED) + { + up_irq_restore(flags); + sched_yield(); + flags = up_irq_save(); + } + + /* Take one count on the lock */ + + lock->sp_cpu = cpu; + lock->sp_count = 1; + } + + up_irq_restore(flags); + +#else /* CONFIG_SMP */ + + /* Take the lock. REVISIT: We should set an indication in the TCB that + * the thread is spinning. This might be useful in determining some + * scheduling actions? + */ + + while (up_testset(&lock->sp_lock) == SP_LOCKED) + { + sched_yield(); + } + +#endif /* CONFIG_SMP */ +} + +/**************************************************************************** + * Name: spin_unlockr + * + * Description: + * Release one count on a spinlock. + * + * Input Parameters: + * lock - A reference to the spinlock object to unlock. + * + * Returned Value: + * None. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void spin_unlockr(FAR struct spinlock_s *lock) +{ +#ifdef CONFIG_SMP + irqstate_t flags; +#ifdef CONFIG_SPINLOCK_LOCKDOWN + uint8_t cpu = this_cpu(); +#endif + + /* Disable interrupts (all CPUs) */ + + flags = up_irq_save(); + +#ifdef CONFIG_SPINLOCK_LOCKDOWN + /* REVISIT: What happens if this thread took the lock on a different CPU, + * was suspended, then reassigned to this CPU where it runs and eventually + * calls spin_unlock(). One solution might be to lock a thread to a CPU if + * it holds a spinlock. That would assure that it never runs on any other + * CPU and avoids such complexities. + */ + + DEBUGASSERT(lock != NULL && lock->sp_lock == SP_LOCKED && + lock->sp_cpu == this_cpu() && lock->sp_count > 0); + + /* Do we already hold the lock? */ + + if (lock->sp_cpu == cpu) +#else + /* The alternative is to allow the lock to be released from any CPU */ + + DEBUGASSERT(lock != NULL && lock->sp_lock == SP_LOCKED && + lock->sp_count > 0); +#endif + + { + /* Yes... just decrement the number of references we have on the lock */ + + if (lock->sp_count <= 1) + { + /* The count must decremented to zero */ + + lock->sp_count = 0; + lock->sp_cpu = IMPOSSIBLE_CPU; + lock->sp_lock = SP_UNLOCKED; + } + else + { + lock->sp_count--; + } + } + + up_irq_restore(flags); + +#else /* CONFIG_SMP */ + /* Just mark the spinlock unlocked */ + + DEBUGASSERT(lock != NULL && lock->sp_lock == SP_LOCKED); + lock->sp_lock = SP_UNLOCKED; + +#endif /* CONFIG_SMP */ +} + +/**************************************************************************** + * Name: spin_setbit + * + * Description: + * Makes setting a CPU bit in a bitset an atomic action + * + * Input Parameters: + * set - A reference to the bitset to set the CPU bit in + * cpu - The bit number to be set + * setlock - A reference to the lock lock protecting the set + * orlock - Will be set to SP_LOCKED while holding setlock + * + * Returned Value: + * None + * + ****************************************************************************/ + +void spin_setbit(FAR volatile cpu_set_t *set, unsigned int cpu, + FAR volatile spinlock_t *setlock, + FAR volatile spinlock_t *orlock) +{ + /* First, get the 'setlock' spinlock */ + + spin_lock(setlock); + + /* Then set the bit and mark the 'orlock' as locked */ + + *set |= (1 << cpu); + *orlock = SP_LOCKED; + + /* Release the 'setlock' */ + + spin_unlock(setlock); +} + +/**************************************************************************** + * Name: spin_clrbit + * + * Description: + * Makes clearing a CPU bit in a bitset an atomic action + * + * Input Parameters: + * set - A reference to the bitset to set the CPU bit in + * cpu - The bit number to be set + * setlock - A reference to the lock lock protecting the set + * orlock - Will be set to SP_UNLOCKED if all bits become cleared in set + * + * Returned Value: + * None + * + ****************************************************************************/ + +void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, + FAR volatile spinlock_t *setlock, + FAR volatile spinlock_t *orlock) +{ + /* First, get the 'setlock' spinlock */ + + spin_lock(setlock); + + /* Then clear the bit in the CPU set. Set/clear the 'orlock' depending + * upon the resulting state of the CPU set. + */ + + *set &= ~(1 << cpu); + *orlock = (*set != 0) ? SP_LOCKED : SP_UNLOCKED; + + /* Release the 'setlock' */ + + spin_unlock(setlock); +} + +#endif /* CONFIG_SPINLOCK */ diff --git a/sched/signal/Make.defs b/sched/signal/Make.defs index 8521b644aa69b80835cbd71b4b43c7eb41877d0b..9d6ddda3a67d6ecd325ff4a5caf4828b479823c2 100644 --- a/sched/signal/Make.defs +++ b/sched/signal/Make.defs @@ -44,6 +44,10 @@ CSRCS += sig_removependingsignal.c sig_releasependingsignal.c sig_lowest.c CSRCS += sig_mqnotempty.c sig_cleanup.c sig_dispatch.c sig_deliver.c CSRCS += sig_pause.c sig_nanosleep.c +ifeq ($(CONFIG_SIG_EVTHREAD),y) +CSRCS += sig_notification.c +endif + # Include signal build support DEPPATH += --dep-path signal diff --git a/sched/signal/sig_action.c b/sched/signal/sig_action.c index 4d0f845875c9e6ddebae209cb62538aff2c07497..4b61dc1d49b1881e12e474a367fde550ce955d88 100644 --- a/sched/signal/sig_action.c +++ b/sched/signal/sig_action.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_action.c * - * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ #include #include +#include + #include "sched/sched.h" #include "group/group.h" #include "signal/signal.h" @@ -58,18 +60,6 @@ (t)->sa_mask = (f)->sa_mask; \ (t)->sa_flags = (f)->sa_flags; } -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -88,7 +78,7 @@ static FAR sigactq_t *sig_allocateaction(void) /* Try to get the signal action structure from the free list */ - sigact = (FAR sigactq_t*)sq_remfirst(&g_sigfreeaction); + sigact = (FAR sigactq_t *)sq_remfirst(&g_sigfreeaction); /* Check if we got one. */ @@ -100,7 +90,7 @@ static FAR sigactq_t *sig_allocateaction(void) /* And try again */ - sigact = (FAR sigactq_t*)sq_remfirst(&g_sigfreeaction); + sigact = (FAR sigactq_t *)sq_remfirst(&g_sigfreeaction); ASSERT(sigact); } @@ -165,13 +155,17 @@ static FAR sigactq_t *sig_allocateaction(void) int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction *oact) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); + FAR struct task_group_s *group; FAR sigactq_t *sigact; /* Since sigactions can only be installed from the running thread of * execution, no special precautions should be necessary. */ + DEBUGASSERT(rtcb != NULL && rtcb->group != NULL); + group = rtcb->group; + /* Verify the signal number */ if (!GOOD_SIGNO(signo)) @@ -180,9 +174,9 @@ int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction * return ERROR; } - /* Find the signal in the sigactionq */ + /* Find the signal in the signal action queue */ - sigact = sig_findaction(rtcb, signo); + sigact = sig_findaction(group, signo); /* Return the old sigaction value if so requested */ @@ -231,7 +225,7 @@ int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction * * can be modified by the child thread. */ - flags = irqsave(); + flags = enter_critical_section(); /* Mark that status should be not be retained */ @@ -240,7 +234,7 @@ int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction * /* Free all pending exit status */ group_removechildren(rtcb->group); - irqrestore(flags); + leave_critical_section(flags); } #endif @@ -252,9 +246,9 @@ int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction * if (sigact) { - /* Yes.. Remove it from sigactionq */ + /* Yes.. Remove it from signal action queue */ - sq_rem((FAR sq_entry_t*)sigact, &rtcb->sigactionq); + sq_rem((FAR sq_entry_t *)sigact, &group->tg_sigactionq); /* And deallocate it */ @@ -279,18 +273,18 @@ int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction * /* An error has occurred if we could not allocate the sigaction */ if (!sigact) - { + { set_errno(ENOMEM); return ERROR; - } + } /* Put the signal number in the queue entry */ sigact->signo = (uint8_t)signo; - /* Add the new sigaction to sigactionq */ + /* Add the new sigaction to signal action queue */ - sq_addlast((FAR sq_entry_t*)sigact, &rtcb->sigactionq); + sq_addlast((FAR sq_entry_t *)sigact, &group->tg_sigactionq); } /* Set the new sigaction */ @@ -313,5 +307,5 @@ void sig_releaseaction(FAR sigactq_t *sigact) { /* Just put it back on the free list */ - sq_addlast((FAR sq_entry_t*)sigact, &g_sigfreeaction); + sq_addlast((FAR sq_entry_t *)sigact, &g_sigfreeaction); } diff --git a/sched/signal/sig_allocatependingsigaction.c b/sched/signal/sig_allocatependingsigaction.c index 3ea627a298f3e54a5086ad0d2e8a5d7e8c2fbd22..361b9460a3b47b1031fd8904df7c4936c1d66825 100644 --- a/sched/signal/sig_allocatependingsigaction.c +++ b/sched/signal/sig_allocatependingsigaction.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_allocatependingsigaction.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,56 +31,38 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include + +#include #include #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_allocatependingsigaction * * Description: * Allocate a new element for the pending signal action queue * - ************************************************************************/ + ****************************************************************************/ FAR sigq_t *sig_allocatependingsigaction(void) { FAR sigq_t *sigq; - irqstate_t saved_state; + irqstate_t flags; /* Check if we were called from an interrupt handler. */ @@ -88,7 +70,7 @@ FAR sigq_t *sig_allocatependingsigaction(void) { /* Try to get the pending signal action structure from the free list */ - sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingaction); + sigq = (FAR sigq_t *)sq_remfirst(&g_sigpendingaction); /* If so, then try the special list of structures reserved for * interrupt handlers @@ -96,7 +78,7 @@ FAR sigq_t *sig_allocatependingsigaction(void) if (!sigq) { - sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingirqaction); + sigq = (FAR sigq_t *)sq_remfirst(&g_sigpendingirqaction); } } @@ -107,9 +89,9 @@ FAR sigq_t *sig_allocatependingsigaction(void) { /* Try to get the pending signal action structure from the free list */ - saved_state = irqsave(); - sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingaction); - irqrestore(saved_state); + flags = enter_critical_section(); + sigq = (FAR sigq_t *)sq_remfirst(&g_sigpendingaction); + leave_critical_section(flags); /* Check if we got one. */ diff --git a/sched/signal/sig_cleanup.c b/sched/signal/sig_cleanup.c index 58fc1093c76d5d150a8d6e1db186d408e7117473..4a37e67b5fc3fd4f14f511667c8fb3f03cfe5a7a 100644 --- a/sched/signal/sig_cleanup.c +++ b/sched/signal/sig_cleanup.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_cleanup.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,42 +31,22 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_cleanup * * Description: @@ -74,41 +54,33 @@ * called only at task deletion time. The caller is expected to have * assured the critical section necessary to perform this action. * - ************************************************************************/ + ****************************************************************************/ void sig_cleanup(FAR struct tcb_s *stcb) { - FAR sigactq_t *sigact; FAR sigq_t *sigq; - /* Deallocate all entries in the list of signal actions */ - - while ((sigact = (FAR sigactq_t*)sq_remfirst(&stcb->sigactionq)) != NULL) - { - sig_releaseaction(sigact); - } - /* Deallocate all entries in the list of pending signal actions */ - while ((sigq = (FAR sigq_t*)sq_remfirst(&stcb->sigpendactionq)) != NULL) + while ((sigq = (FAR sigq_t *)sq_remfirst(&stcb->sigpendactionq)) != NULL) { sig_releasependingsigaction(sigq); } /* Deallocate all entries in the list of posted signal actions */ - while ((sigq = (FAR sigq_t*)sq_remfirst(&stcb->sigpostedq)) != NULL) + while ((sigq = (FAR sigq_t *)sq_remfirst(&stcb->sigpostedq)) != NULL) { sig_releasependingsigaction(sigq); } - /* Misc. signal-related clean-up */ + /* Misc. signal-related clean-up */ - stcb->sigprocmask = ALL_SIGNAL_SET; - stcb->sigwaitmask = NULL_SIGNAL_SET; + stcb->sigprocmask = ALL_SIGNAL_SET; + stcb->sigwaitmask = NULL_SIGNAL_SET; } -/************************************************************************ +/**************************************************************************** * Name: sig_release * * Description: @@ -117,15 +89,23 @@ void sig_cleanup(FAR struct tcb_s *stcb) * expected to have assured the critical section necessary to perform * this action. * - ************************************************************************/ + ****************************************************************************/ void sig_release(FAR struct task_group_s *group) { + FAR sigactq_t *sigact; FAR sigpendq_t *sigpend; + /* Deallocate all entries in the list of signal actions */ + + while ((sigact = (FAR sigactq_t *)sq_remfirst(&group->tg_sigactionq)) != NULL) + { + sig_releaseaction(sigact); + } + /* Deallocate all entries in the list of pending signals */ - while ((sigpend = (FAR sigpendq_t*)sq_remfirst(&group->sigpendingq)) != NULL) + while ((sigpend = (FAR sigpendq_t *)sq_remfirst(&group->tg_sigpendingq)) != NULL) { sig_releasependingsignal(sigpend); } diff --git a/sched/signal/sig_deliver.c b/sched/signal/sig_deliver.c index c91a10e403480ab7522b75338baf216cb90756fa..1f9c378b8a640dec0056b22e3a60b68c6b9d59e5 100644 --- a/sched/signal/sig_deliver.c +++ b/sched/signal/sig_deliver.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_deliver.c * - * Copyright (C) 2007, 2008, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2012-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,31 +45,13 @@ #include #include #include + +#include #include #include "semaphore/semaphore.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -88,7 +70,7 @@ void sig_deliver(FAR struct tcb_s *stcb) FAR sigq_t *sigq; FAR sigq_t *next; sigset_t savesigprocmask; - irqstate_t saved_state; + irqstate_t flags; int saved_errno; sched_lock(); @@ -101,7 +83,7 @@ void sig_deliver(FAR struct tcb_s *stcb) */ saved_errno = stcb->pterrno; - for (sigq = (FAR sigq_t*)stcb->sigpendactionq.head; (sigq); sigq = next) + for (sigq = (FAR sigq_t *)stcb->sigpendactionq.head; (sigq); sigq = next) { next = sigq->flink; sdbg("Sending signal sigq=0x%x\n", sigq); @@ -111,10 +93,10 @@ void sig_deliver(FAR struct tcb_s *stcb) * time, there should never be more than one signal in the sigpostedq */ - saved_state = irqsave(); - sq_rem((FAR sq_entry_t*)sigq, &(stcb->sigpendactionq)); - sq_addlast((FAR sq_entry_t*)sigq, &(stcb->sigpostedq)); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_rem((FAR sq_entry_t *)sigq, &(stcb->sigpendactionq)); + sq_addlast((FAR sq_entry_t *)sigq, &(stcb->sigpostedq)); + leave_critical_section(flags); /* Call the signal handler (unless the signal was cancelled) * @@ -172,14 +154,14 @@ void sig_deliver(FAR struct tcb_s *stcb) /* Remove the signal from the sigpostedq */ - saved_state = irqsave(); - sq_rem((FAR sq_entry_t*)sigq, &(stcb->sigpostedq)); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_rem((FAR sq_entry_t *)sigq, &(stcb->sigpostedq)); + leave_critical_section(flags); /* Then deallocate it */ sig_releasependingsigaction(sigq); - } + } stcb->pterrno = saved_errno; sched_unlock(); diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index 2113487e550ef4a1a86605d123195c1acdc7b796..107982c59baef03c1570a02c31dab37ccf34429a 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_dispatch.c * - * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #include "sched/sched.h" @@ -54,22 +55,6 @@ #include "signal/signal.h" #include "mqueue/mqueue.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -89,14 +74,15 @@ static int sig_queueaction(FAR struct tcb_s *stcb, siginfo_t *info) { FAR sigactq_t *sigact; FAR sigq_t *sigq; - irqstate_t saved_state; + irqstate_t flags; int ret = OK; sched_lock(); + DEBUGASSERT(stcb != NULL && stcb->group != NULL); - /* Find the sigaction associated with this signal */ + /* Find the group sigaction associated with this signal */ - sigact = sig_findaction(stcb, info->si_signo); + sigact = sig_findaction(stcb->group, info->si_signo); /* Check if a valid signal handler is available and if the signal is * unblocked. NOTE: There is no default action. @@ -117,15 +103,15 @@ static int sig_queueaction(FAR struct tcb_s *stcb, siginfo_t *info) { /* Populate the new signal queue element */ - sigq->action.sighandler = sigact->act.sa_u._sa_sigaction; - sigq->mask = sigact->act.sa_mask; - memcpy(&sigq->info, info, sizeof(siginfo_t)); + sigq->action.sighandler = sigact->act.sa_u._sa_sigaction; + sigq->mask = sigact->act.sa_mask; + memcpy(&sigq->info, info, sizeof(siginfo_t)); - /* Put it at the end of the pending signals list */ + /* Put it at the end of the pending signals list */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigq, &(stcb->sigpendactionq)); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigq, &(stcb->sigpendactionq)); + leave_critical_section(flags); } } @@ -144,7 +130,7 @@ static int sig_queueaction(FAR struct tcb_s *stcb, siginfo_t *info) static FAR sigpendq_t *sig_allocatependingsignal(void) { FAR sigpendq_t *sigpend; - irqstate_t saved_state; + irqstate_t flags; /* Check if we were called from an interrupt handler. */ @@ -152,7 +138,7 @@ static FAR sigpendq_t *sig_allocatependingsignal(void) { /* Try to get the pending signal structure from the free list */ - sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingsignal); + sigpend = (FAR sigpendq_t *)sq_remfirst(&g_sigpendingsignal); if (!sigpend) { /* If no pending signal structure is available in the free list, @@ -160,20 +146,21 @@ static FAR sigpendq_t *sig_allocatependingsignal(void) * interrupt handlers */ - sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingirqsignal); + sigpend = (FAR sigpendq_t *)sq_remfirst(&g_sigpendingirqsignal); } } /* If we were not called from an interrupt handler, then we are - * free to allocate pending action structures if necessary. */ + * free to allocate pending action structures if necessary. + */ else { /* Try to get the pending signal structure from the free list */ - saved_state = irqsave(); - sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingsignal); - irqrestore(saved_state); + flags = enter_critical_section(); + sigpend = (FAR sigpendq_t *)sq_remfirst(&g_sigpendingsignal); + leave_critical_section(flags); /* Check if we got one. */ @@ -210,21 +197,21 @@ static FAR sigpendq_t *sig_findpendingsignal(FAR struct task_group_s *group, int signo) { FAR sigpendq_t *sigpend = NULL; - irqstate_t saved_state; + irqstate_t flags; - DEBUGASSERT(group); + DEBUGASSERT(group != NULL); /* Pending sigals can be added from interrupt level. */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Seach the list for a sigpendion on this signal */ - for (sigpend = (FAR sigpendq_t*)group->sigpendingq.head; + for (sigpend = (FAR sigpendq_t *)group->tg_sigpendingq.head; (sigpend && sigpend->info.si_signo != signo); sigpend = sigpend->flink); - irqrestore(saved_state); + leave_critical_section(flags); return sigpend; } @@ -242,13 +229,14 @@ static FAR sigpendq_t *sig_findpendingsignal(FAR struct task_group_s *group, static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb, FAR siginfo_t *info) { - FAR struct task_group_s *group = stcb->group; + FAR struct task_group_s *group; FAR sigpendq_t *sigpend; - irqstate_t saved_state; + irqstate_t flags; - DEBUGASSERT(group); + DEBUGASSERT(stcb != NULL && stcb->group != NULL); + group = stcb->group; - /* Check if the signal is already pending */ + /* Check if the signal is already pending for the group */ sigpend = sig_findpendingsignal(group, info->si_signo); if (sigpend) @@ -258,7 +246,7 @@ static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb, memcpy(&sigpend->info, info, sizeof(siginfo_t)); } - /* No... There is nothing pending for this signo */ + /* No... There is nothing pending in the group for this signo */ else { @@ -271,11 +259,11 @@ static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb, memcpy(&sigpend->info, info, sizeof(siginfo_t)); - /* Add the structure to the pending signal list */ + /* Add the structure to the group pending signal list */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigpend, &group->sigpendingq); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigpend, &group->tg_sigpendingq); + leave_critical_section(flags); } } @@ -310,14 +298,14 @@ static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb, int sig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) { - irqstate_t saved_state; + irqstate_t flags; int ret = OK; sdbg("TCB=0x%08x signo=%d code=%d value=%d mask=%08x\n", stcb, info->si_signo, info->si_code, info->si_value.sival_int, stcb->sigprocmask); - DEBUGASSERT(stcb && info); + DEBUGASSERT(stcb != NULL && info != NULL); /************************* MASKED SIGNAL HANDLING ************************/ @@ -332,14 +320,14 @@ int sig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) * from the interrupt level. */ - saved_state = irqsave(); + flags = enter_critical_section(); if (stcb->task_state == TSTATE_WAIT_SIG && sigismember(&stcb->sigwaitmask, info->si_signo)) { memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t)); stcb->sigwaitmask = NULL_SIGNAL_SET; up_unblock_task(stcb); - irqrestore(saved_state); + leave_critical_section(flags); } /* Its not one we are waiting for... Add it to the list of pending @@ -348,7 +336,7 @@ int sig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) else { - irqrestore(saved_state); + leave_critical_section(flags); ASSERT(sig_addpendingsignal(stcb, info)); } } @@ -372,7 +360,7 @@ int sig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) * signals can be queued from the interrupt level. */ - saved_state = irqsave(); + flags = enter_critical_section(); if (stcb->task_state == TSTATE_WAIT_SIG) { memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t)); @@ -380,7 +368,7 @@ int sig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) up_unblock_task(stcb); } - irqrestore(saved_state); + leave_critical_section(flags); /* If the task neither was waiting for the signal nor had a signal * handler attached to the signal, then the default action is @@ -451,7 +439,7 @@ int sig_dispatch(pid_t pid, FAR siginfo_t *info) /* Get the TCB associated with the pid */ stcb = sched_gettcb(pid); - if (stcb) + if (stcb != NULL) { /* The task/thread associated with this PID is still active. Get its * task group. @@ -471,7 +459,7 @@ int sig_dispatch(pid_t pid, FAR siginfo_t *info) /* Did we locate the group? */ - if (group) + if (group != NULL) { /* Yes.. call group_signal() to send the signal to the correct group * member. @@ -490,7 +478,7 @@ int sig_dispatch(pid_t pid, FAR siginfo_t *info) /* Get the TCB associated with the pid */ stcb = sched_gettcb(pid); - if (!stcb) + if (stcb == NULL) { return -ESRCH; } diff --git a/sched/signal/sig_findaction.c b/sched/signal/sig_findaction.c index 62a7807c1aac1f99d9715b45f40520e0b6d399d7..769a678d3c51f41dc5ff57eec39c943e18af3361 100644 --- a/sched/signal/sig_findaction.c +++ b/sched/signal/sig_findaction.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_findaction.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,54 +31,34 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_findaction * * Description: * Allocate a new element for a signal queue * - ************************************************************************/ + ****************************************************************************/ -FAR sigactq_t *sig_findaction(FAR struct tcb_s *stcb, int signo) +FAR sigactq_t *sig_findaction(FAR struct task_group_s *group, int signo) { FAR sigactq_t *sigact = NULL; /* Verify the caller's sanity */ - if (stcb) + if (group) { /* Sigactions can only be assigned to the currently executing * thread. So, a simple lock ought to give us sufficient @@ -89,7 +69,7 @@ FAR sigactq_t *sig_findaction(FAR struct tcb_s *stcb, int signo) /* Seach the list for a sigaction on this signal */ - for (sigact = (FAR sigactq_t*)stcb->sigactionq.head; + for (sigact = (FAR sigactq_t *)group->tg_sigactionq.head; ((sigact) && (sigact->signo != signo)); sigact = sigact->flink); diff --git a/sched/signal/sig_initialize.c b/sched/signal/sig_initialize.c index 66d24b97532800f95c42853e5b39553ec3c49d74..12dc4a18bece6cf8a2b4d8418ade71a78cf48ce2 100644 --- a/sched/signal/sig_initialize.c +++ b/sched/signal/sig_initialize.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_initialize.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -45,17 +45,9 @@ #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ /* The g_sigfreeaction data structure is a list of available signal * action structures. @@ -88,9 +80,9 @@ sq_queue_t g_sigpendingsignal; sq_queue_t g_sigpendingirqsignal; -/************************************************************************ - * Private Variables - ************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ /* g_sigactionalloc is a pointer to the start of the allocated blocks of * signal actions. @@ -122,91 +114,91 @@ static sigpendq_t *g_sigpendingsignalalloc; static sigpendq_t *g_sigpendingirqsignalalloc; -/************************************************************************ +/**************************************************************************** * Private Function Prototypes - ************************************************************************/ + ****************************************************************************/ static sigq_t *sig_allocateblock(sq_queue_t *siglist, uint16_t nsigs, uint8_t sigtype); static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *siglist, uint16_t nsigs, uint8_t sigtype); -/************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_allocateblock * * Description: * Allocate a block of pending signal actions and place them * on the free list. * - ************************************************************************/ + ****************************************************************************/ static sigq_t *sig_allocateblock(sq_queue_t *siglist, uint16_t nsigs, uint8_t sigtype) { - sigq_t *sigqalloc; - sigq_t *sigq; - int i; + FAR sigq_t *sigqalloc; + FAR sigq_t *sigq; + int i; /* Allocate a block of pending signal actions */ - sigqalloc = (sigq_t*)kmm_malloc((sizeof(sigq_t)) * nsigs); + sigqalloc = (FAR sigq_t *)kmm_malloc((sizeof(sigq_t)) * nsigs); sigq = sigqalloc; for (i = 0; i < nsigs; i++) { sigq->type = sigtype; - sq_addlast((FAR sq_entry_t*)sigq++, siglist); + sq_addlast((FAR sq_entry_t *)sigq++, siglist); } return sigqalloc; } -/************************************************************************ +/**************************************************************************** * Name: sig_allocatependingsignalblock * * Description: * Allocate a block of pending signal structures and place them on * the free list. * - ************************************************************************/ + ****************************************************************************/ static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *siglist, uint16_t nsigs, uint8_t sigtype) { - sigpendq_t *sigpendalloc; - sigpendq_t *sigpend; + FAR sigpendq_t *sigpendalloc; + FAR sigpendq_t *sigpend; int i; /* Allocate a block of pending signal structures */ sigpendalloc = - (sigpendq_t*)kmm_malloc((sizeof(sigpendq_t)) * nsigs); + (FAR sigpendq_t *)kmm_malloc((sizeof(sigpendq_t)) * nsigs); sigpend = sigpendalloc; for (i = 0; i < nsigs; i++) { sigpend->type = sigtype; - sq_addlast((FAR sq_entry_t*)sigpend++, siglist); + sq_addlast((FAR sq_entry_t *)sigpend++, siglist); } return sigpendalloc; } -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_initialize * * Description: * Perform one-time power-up initialization * - ************************************************************************/ + ****************************************************************************/ void sig_initialize(void) { @@ -243,28 +235,28 @@ void sig_initialize(void) SIG_ALLOC_IRQ); } -/************************************************************************ +/**************************************************************************** * Name: sig_allocateactionblock * * Description: * Allocate a block of signal actions and place them * on the free list. * - ************************************************************************/ + ****************************************************************************/ void sig_allocateactionblock(void) { - sigactq_t *sigact; + FAR sigactq_t *sigact; int i; /* Allocate a block of signal actions */ g_sigactionalloc = - (sigactq_t*)kmm_malloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS); + (FAR sigactq_t *)kmm_malloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS); sigact = g_sigactionalloc; for (i = 0; i < NUM_SIGNAL_ACTIONS; i++) { - sq_addlast((FAR sq_entry_t*)sigact++, &g_sigfreeaction); + sq_addlast((FAR sq_entry_t *)sigact++, &g_sigfreeaction); } } diff --git a/sched/signal/sig_kill.c b/sched/signal/sig_kill.c index 956029a693f7c4c0e2f39349fd09034c66fda6a5..0fa9930e8a47e04c256e7ecc8b97c459c3e92033 100644 --- a/sched/signal/sig_kill.c +++ b/sched/signal/sig_kill.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_kill.c * - * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -47,11 +47,11 @@ #include "sched/sched.h" #include "signal/signal.h" -/************************************************************************ - * Global Functions - ************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: kill * * Description: @@ -80,12 +80,12 @@ * * Assumptions: * - ************************************************************************/ + ****************************************************************************/ int kill(pid_t pid, int signo) { #ifdef CONFIG_SCHED_HAVE_PARENT - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #endif siginfo_t info; int ret; @@ -114,6 +114,7 @@ int kill(pid_t pid, int signo) info.si_signo = signo; info.si_code = SI_USER; + info.si_errno = EINTR; info.si_value.sival_ptr = NULL; #ifdef CONFIG_SCHED_HAVE_PARENT info.si_pid = rtcb->pid; diff --git a/sched/signal/sig_lowest.c b/sched/signal/sig_lowest.c index 46f0de0c9bf39dfea8dd10ea8f94616dd9ae2248..5474e25e7d7660c442204d8339a527d59a349751 100644 --- a/sched/signal/sig_lowest.c +++ b/sched/signal/sig_lowest.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_lowest.c * * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,37 +43,17 @@ #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_lowest * * Description: * Return the lowest signal number that is a member of a set of signals. * - ************************************************************************/ + ****************************************************************************/ int sig_lowest(sigset_t *set) { diff --git a/sched/signal/sig_mqnotempty.c b/sched/signal/sig_mqnotempty.c index ee936f02fcfd73f8427cdfcfaf529271a3f04d8b..44b05b7aff70c8b413d7d0665c7f3ce13827d100 100644 --- a/sched/signal/sig_mqnotempty.c +++ b/sched/signal/sig_mqnotempty.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_mqnotempty.c * - * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,26 +48,6 @@ #include "sched/sched.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functionss - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -90,7 +70,7 @@ int sig_mqnotempty(int pid, int signo, void *sival_ptr) #endif { #ifdef CONFIG_SCHED_HAVE_PARENT - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #endif siginfo_t info; int ret; @@ -112,6 +92,7 @@ int sig_mqnotempty(int pid, int signo, void *sival_ptr) info.si_signo = signo; info.si_code = SI_MESGQ; + info.si_errno = OK; #ifdef CONFIG_CAN_PASS_STRUCTS info.si_value = value; #else diff --git a/sched/signal/sig_nanosleep.c b/sched/signal/sig_nanosleep.c index c540d3451408f57534724dd83ea13f0b2c14d7aa..9ffbcb52c764161dc6c378b8b17144949b90d75b 100644 --- a/sched/signal/sig_nanosleep.c +++ b/sched/signal/sig_nanosleep.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig/nanosleep.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,30 +45,10 @@ #include #include -#include +#include #include "clock/clock.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -124,7 +104,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) { irqstate_t flags; - uint32_t starttick; + systime_t starttick; sigset_t set; struct siginfo value; int errval; @@ -143,7 +123,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) * after the wait. */ - flags = irqsave(); + flags = enter_critical_section(); starttick = clock_systimer(); /* Set up for the sleep. Using the empty set means that we are not @@ -173,7 +153,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) { /* The timeout "error" is the normal, successful result */ - irqrestore(flags); + leave_critical_section(flags); return OK; } @@ -183,8 +163,8 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) if (rmtp) { - uint32_t elapsed; - uint32_t remaining; + systime_t elapsed; + systime_t remaining; int ticks; /* First get the number of clock ticks that we were requested to @@ -214,7 +194,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) (void)clock_ticks2time((int)remaining, rmtp); } - irqrestore(flags); + leave_critical_section(flags); errout: set_errno(errval); diff --git a/sched/signal/sig_notification.c b/sched/signal/sig_notification.c new file mode 100644 index 0000000000000000000000000000000000000000..f9a0710fbeaa3394034dabfaae0b1b365a560577 --- /dev/null +++ b/sched/signal/sig_notification.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * sched/signal/sig_notification.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_SIG_EVTHREAD + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Use the low-prioriry work queue is it is available */ + +#if defined(CONFIG_SCHED_LPWORK) +# define NTWORK LPWORK +#elif defined(CONFIG_SCHED_HPWORK) +# define NTWORK HPWORK +#else +# error Work queue is not enabled +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* This structure retains all that is necessary to perform the notification */ + +struct sig_notify_s +{ + struct work_s nt_work; /* Work queue structure */ + union sigval nt_value; /* Data passed with notification */ + sigev_notify_function_t nt_func; /* Notification function */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sig_ntworker + * + * Description: + * Perform the callback from the context of the worker thread. + * + * Input Parameters: + * arg - Work argument. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void sig_ntworker(FAR void *arg) +{ + FAR struct sig_notify_s *notify = (FAR struct sig_notify_s *)arg; + + DEBUGASSERT(notify != NULL); + + /* Perform the callback */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + notify->nt_func(notify->nt_value); +#else + notify->nt_func(notify->nt_value.sival_ptr); +#endif + + /* Free the alloated notification parameters */ + + kmm_free(notify); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sig_notification + * + * Description: + * Notify a client a signal event via a function call. This function is + * an internal OS interface that implements the common logic for signal + * event notification for the case of SIGEV_THREAD. + * + * Input Parameters: + * pid - The task/thread ID a the client thread to be signaled. + * event - The instance of struct sigevent that describes how to signal + * the client. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int sig_notification(pid_t pid, FAR struct sigevent *event) +{ + FAR struct sig_notify_s *notify; + DEBUGASSERT(event != NULL && event->sigev_notify_function != NULL); + int ret; + + /* Allocate a structure to hold the notification information */ + + notify = kmm_zalloc(sizeof(struct sig_notify_s)); + if (notify == NULL) + { + return -ENOMEM; + } + + /* Initialize the notification information */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + notify->nt_value = event->sigev_value; +#else + notify->nt_value.sival_ptr = event->sigev_value.sival_ptr; +#endif + notify->nt_func = event->sigev_notify_function; + + /* Then queue the work */ + + ret = work_queue(NTWORK, ¬ify->nt_work, sig_ntworker, notify, 0); + if (ret < 0) + { + kmm_free(notify); + } + + return ret; +} + +#endif /* CONFIG_SIG_EVTHREAD */ diff --git a/sched/signal/sig_pause.c b/sched/signal/sig_pause.c index 9344c2bec37e8d66d164c73d99f839b77a17bbd9..80fc712cb7bbe56869e79d27af1ff3f4a7a3b4f1 100644 --- a/sched/signal/sig_pause.c +++ b/sched/signal/sig_pause.c @@ -42,26 +42,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/signal/sig_pending.c b/sched/signal/sig_pending.c index f60c56e90773aa5fcc5b93370d1763ee22a035ed..aadef0b86bea0e742a9fd11397d15d857f987a73 100644 --- a/sched/signal/sig_pending.c +++ b/sched/signal/sig_pending.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_pending.c * - * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,29 +42,11 @@ #include #include +#include + #include "sched/sched.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -89,7 +71,7 @@ int sigpending(FAR sigset_t *set) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); int ret = ERROR; if (set) @@ -114,20 +96,20 @@ sigset_t sig_pendingset(FAR struct tcb_s *stcb) FAR struct task_group_s *group = stcb->group; sigset_t sigpendset; FAR sigpendq_t *sigpend; - irqstate_t saved_state; + irqstate_t flags; DEBUGASSERT(group); sigpendset = NULL_SIGNAL_SET; - saved_state = irqsave(); - for (sigpend = (FAR sigpendq_t*)group->sigpendingq.head; + flags = enter_critical_section(); + for (sigpend = (FAR sigpendq_t *)group->tg_sigpendingq.head; (sigpend); sigpend = sigpend->flink) { sigaddset(&sigpendset, sigpend->info.si_signo); } - irqrestore(saved_state); + leave_critical_section(flags); return sigpendset; } diff --git a/sched/signal/sig_procmask.c b/sched/signal/sig_procmask.c index 0ef425a2dcfa1386f1388f379622ab5a5ed8eff8..e7a7ad9d8aecbb5bf4c688a1cf0ee2f6aec10f34 100644 --- a/sched/signal/sig_procmask.c +++ b/sched/signal/sig_procmask.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_procmask.c * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include #include +#include #include #include #include @@ -53,26 +54,6 @@ #include "sched/sched.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -113,9 +94,9 @@ int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); sigset_t oldsigprocmask; - irqstate_t saved_state; + irqstate_t flags; int ret = OK; sched_lock(); @@ -136,7 +117,7 @@ int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) * ourselves from attempts to process signals from interrupts */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Okay, determine what we are supposed to do */ @@ -169,7 +150,7 @@ int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) break; } - irqrestore(saved_state); + leave_critical_section(flags); /* Now, process any pending signals that were just unmasked */ diff --git a/sched/signal/sig_queue.c b/sched/signal/sig_queue.c index 6e9b1b2ce9f8329952105bc260fd445d1359a985..3daa59c155e3f2b67820a6ece9a9e0afa04d24f8 100644 --- a/sched/signal/sig_queue.c +++ b/sched/signal/sig_queue.c @@ -48,26 +48,6 @@ #include "sched/sched.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -112,7 +92,7 @@ int sigqueue(int pid, int signo, void *sival_ptr) #endif { #ifdef CONFIG_SCHED_HAVE_PARENT - FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #endif siginfo_t info; int ret; @@ -135,6 +115,7 @@ int sigqueue(int pid, int signo, void *sival_ptr) info.si_signo = signo; info.si_code = SI_QUEUE; + info.si_errno = OK; #ifdef CONFIG_CAN_PASS_STRUCTS info.si_value = value; #else diff --git a/sched/signal/sig_releasependingsigaction.c b/sched/signal/sig_releasependingsigaction.c index 424d73368453ba023f027a5091419821cba23516..11e8d72f984787b58ffb8a9be267a145786ef9fb 100644 --- a/sched/signal/sig_releasependingsigaction.c +++ b/sched/signal/sig_releasependingsigaction.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_releasependingsigaction.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,53 +31,35 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include -#include "signal/signal.h" - -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ +#include -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ +#include "signal/signal.h" -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_releasependingsigaction * * Description: * Deallocate a pending signal action Q entry * - ************************************************************************/ + ****************************************************************************/ void sig_releasependingsigaction(FAR sigq_t *sigq) { - irqstate_t saved_state; + irqstate_t flags; /* If this is a generally available pre-allocated structyre, * then just put it back in the free list. @@ -88,10 +70,10 @@ void sig_releasependingsigaction(FAR sigq_t *sigq) /* Make sure we avoid concurrent access to the free * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigq, &g_sigpendingaction); - irqrestore(saved_state); - } + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigq, &g_sigpendingaction); + leave_critical_section(flags); + } /* If this is a message pre-allocated for interrupts, * then put it back in the correct free list. @@ -102,9 +84,9 @@ void sig_releasependingsigaction(FAR sigq_t *sigq) /* Make sure we avoid concurrent access to the free * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigq, &g_sigpendingirqaction); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigq, &g_sigpendingirqaction); + leave_critical_section(flags); } /* Otherwise, deallocate it. Note: interrupt handlers diff --git a/sched/signal/sig_releasependingsignal.c b/sched/signal/sig_releasependingsignal.c index 0b58a35cba3f39de4a27e3fe30991e47d8a0ea74..3f671a867867a7a6cb76960c5b3291e1c55be7cd 100644 --- a/sched/signal/sig_releasependingsignal.c +++ b/sched/signal/sig_releasependingsignal.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_releasependingsignal.c * - * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,47 +46,28 @@ #include #include +#include #include #include #include #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_releasependingsignal * * Description: * Deallocate a pending signal list entry * - ************************************************************************/ + ****************************************************************************/ void sig_releasependingsignal(FAR sigpendq_t *sigpend) { - irqstate_t saved_state; + irqstate_t flags; /* If this is a generally available pre-allocated structyre, * then just put it back in the free list. @@ -98,9 +79,9 @@ void sig_releasependingsignal(FAR sigpendq_t *sigpend) * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingsignal); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigpend, &g_sigpendingsignal); + leave_critical_section(flags); } /* If this is a message pre-allocated for interrupts, @@ -113,9 +94,9 @@ void sig_releasependingsignal(FAR sigpendq_t *sigpend) * list from interrupt handlers. */ - saved_state = irqsave(); - sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingirqsignal); - irqrestore(saved_state); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)sigpend, &g_sigpendingirqsignal); + leave_critical_section(flags); } /* Otherwise, deallocate it. Note: interrupt handlers diff --git a/sched/signal/sig_removependingsignal.c b/sched/signal/sig_removependingsignal.c index 1eeef02d3ab21d1873e0fc4539800ea4e3e98b19..90485c2dc50593afce9f6551b71628bb20b5f1af 100644 --- a/sched/signal/sig_removependingsignal.c +++ b/sched/signal/sig_removependingsignal.c @@ -1,7 +1,7 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_removependingsignal.c * - * Copyright (C) 2007, 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -46,56 +46,37 @@ #include #include +#include #include #include #include #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_removependingsignal * * Description: * Remove the specified signal from the signal pending list * - ************************************************************************/ + ****************************************************************************/ FAR sigpendq_t *sig_removependingsignal(FAR struct tcb_s *stcb, int signo) { FAR struct task_group_s *group = stcb->group; FAR sigpendq_t *currsig; FAR sigpendq_t *prevsig; - irqstate_t saved_state; + irqstate_t flags; DEBUGASSERT(group); - saved_state = irqsave(); + flags = enter_critical_section(); - for (prevsig = NULL, currsig = (FAR sigpendq_t*)group->sigpendingq.head; + for (prevsig = NULL, currsig = (FAR sigpendq_t *)group->tg_sigpendingq.head; (currsig && currsig->info.si_signo != signo); prevsig = currsig, currsig = currsig->flink); @@ -103,15 +84,15 @@ FAR sigpendq_t *sig_removependingsignal(FAR struct tcb_s *stcb, int signo) { if (prevsig) { - sq_remafter((FAR sq_entry_t*)prevsig, &group->sigpendingq); + sq_remafter((FAR sq_entry_t *)prevsig, &group->tg_sigpendingq); } else { - sq_remfirst(&group->sigpendingq); + sq_remfirst(&group->tg_sigpendingq); } } - irqrestore(saved_state); + leave_critical_section(flags); return currsig; } diff --git a/sched/signal/sig_suspend.c b/sched/signal/sig_suspend.c index 807eb25176f9d224763065eaccad721d84b44e37..d3a4a9ba7190207afd25ec0f2de3ebe8636ae170 100644 --- a/sched/signal/sig_suspend.c +++ b/sched/signal/sig_suspend.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_suspend.c * - * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,31 +44,12 @@ #include #include +#include #include #include "sched/sched.h" #include "signal/signal.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -110,11 +91,11 @@ int sigsuspend(FAR const sigset_t *set) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); sigset_t intersection; sigset_t saved_sigprocmask; FAR sigpendq_t *sigpend; - irqstate_t saved_state; + irqstate_t flags; int unblocksigno; /* Several operations must be performed below: We must determine if any @@ -124,7 +105,7 @@ int sigsuspend(FAR const sigset_t *set) */ sched_lock(); /* Not necessary */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Check if there is a pending signal corresponding to one of the * signals that will be unblocked by the new sigprocmask. @@ -143,7 +124,7 @@ int sigsuspend(FAR const sigset_t *set) ASSERT(sigpend); sig_releasependingsignal(sigpend); - irqrestore(saved_state); + leave_critical_section(flags); } else { @@ -162,7 +143,7 @@ int sigsuspend(FAR const sigset_t *set) /* We are running again, restore the original sigprocmask */ rtcb->sigprocmask = saved_sigprocmask; - irqrestore(saved_state); + leave_critical_section(flags); /* Now, handle the (rare?) case where (a) a blocked signal was received * while the task was suspended but (b) restoring the original diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c index a0abc47d933365b0974cf805a3609d7c35fd0a67..687884dcf9c48f3947bd420a3c04366916ebd864 100644 --- a/sched/signal/sig_timedwait.c +++ b/sched/signal/sig_timedwait.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/signal/sig_timedwait.c * - * Copyright (C) 2007-2009, 2012-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -66,18 +67,6 @@ #define SIG_WAIT_TIMEOUT 0xff -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -93,7 +82,7 @@ static void sig_timeout(int argc, wdparm_t itcb) { /* On many small machines, pointers are encoded and cannot be simply cast - * from uint32_t to struct tcb_s*. The following union works around this + * from uint32_t to struct tcb_s *. The following union works around this * (see wdogparm_t). This odd logic could be conditioned on * CONFIG_CAN_CAST_POINTERS, but it is not too bad in any case. */ @@ -115,6 +104,7 @@ static void sig_timeout(int argc, wdparm_t itcb) { u.wtcb->sigunbinfo.si_signo = SIG_WAIT_TIMEOUT; u.wtcb->sigunbinfo.si_code = SI_TIMER; + u.wtcb->sigunbinfo.si_errno = ETIMEDOUT; u.wtcb->sigunbinfo.si_value.sival_int = 0; #ifdef CONFIG_SCHED_HAVE_PARENT u.wtcb->sigunbinfo.si_pid = 0; /* Not applicable */ @@ -174,10 +164,10 @@ static void sig_timeout(int argc, wdparm_t itcb) int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info, FAR const struct timespec *timeout) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); sigset_t intersection; FAR sigpendq_t *sigpend; - irqstate_t saved_state; + irqstate_t flags; int32_t waitticks; int ret = ERROR; @@ -191,7 +181,7 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info, * can only be eliminated by disabling interrupts! */ - saved_state = irqsave(); + flags = enter_critical_section(); /* Check if there is a pending signal corresponding to one of the * signals in the pending signal set argument. @@ -218,7 +208,7 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info, /* Then dispose of the pending signal structure properly */ sig_releasependingsignal(sigpend); - irqrestore(saved_state); + leave_critical_section(flags); /* The return value is the number of the signal that awakened us */ @@ -349,9 +339,9 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info, memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo)); } - irqrestore(saved_state); - } + leave_critical_section(flags); + } - sched_unlock(); - return ret; + sched_unlock(); + return ret; } diff --git a/sched/signal/sig_unmaskpendingsignal.c b/sched/signal/sig_unmaskpendingsignal.c index 9c4c9ba2ea8b32daf366b3c3d97206c4a23e4429..7781515e00fe58c376c85b97fda157ff547c5cf0 100644 --- a/sched/signal/sig_unmaskpendingsignal.c +++ b/sched/signal/sig_unmaskpendingsignal.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/signal/sig_unmaskpendingsignal.c * * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -44,31 +44,11 @@ #include "sched/sched.h" #include "signal/signal.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: sig_unmaskpendingsignal * * Description: @@ -76,33 +56,33 @@ * unmasks and processes any pending signals. This function should * be called whenever the sigprocmask is changed. * - ************************************************************************/ + ****************************************************************************/ void sig_unmaskpendingsignal(void) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - sigset_t unmaskedset; - FAR sigpendq_t *pendingsig; - int signo; + FAR struct tcb_s *rtcb = this_task(); + sigset_t unmaskedset; + FAR sigpendq_t *pendingsig; + int signo; - /* Prohibit any context switches until we are done with this. - * We may still be performing signal operations from interrupt - * handlers, however, none of the pending signals that we - * are concerned with here should be effected. - */ + /* Prohibit any context switches until we are done with this. + * We may still be performing signal operations from interrupt + * handlers, however, none of the pending signals that we + * are concerned with here should be effected. + */ - sched_lock(); + sched_lock(); - /* Get the set of pending signals that were just unmasked. The - * following operation should be safe because the sigprocmask - * can only be changed on this thread of execution. - */ + /* Get the set of pending signals that were just unmasked. The + * following operation should be safe because the sigprocmask + * can only be changed on this thread of execution. + */ - unmaskedset = ~(rtcb->sigprocmask) & sig_pendingset(rtcb); + unmaskedset = ~(rtcb->sigprocmask) & sig_pendingset(rtcb); - /* Loop while there are unmasked pending signals to be processed. */ + /* Loop while there are unmasked pending signals to be processed. */ - while (unmaskedset != NULL_SIGNAL_SET) + while (unmaskedset != NULL_SIGNAL_SET) { /* Pending signals will be processed from lowest numbered signal * to highest diff --git a/sched/signal/sig_waitinfo.c b/sched/signal/sig_waitinfo.c index 6e7fc1b17068d54ae7b5f3db542c16a2654faef4..d271dc9884cdbcf7163d2471805a7c3b4397fc40 100644 --- a/sched/signal/sig_waitinfo.c +++ b/sched/signal/sig_waitinfo.c @@ -40,26 +40,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/sched/signal/signal.h b/sched/signal/signal.h index fce53f916c3d52dce6854439ccca9221729d3048..e8cfda81b649d8bb51032d230fff93ca1d7a4ee9 100644 --- a/sched/signal/signal.h +++ b/sched/signal/signal.h @@ -117,7 +117,7 @@ struct sigq_s typedef struct sigq_s sigq_t; /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /* The g_sigfreeaction data structure is a list of available signal action @@ -186,7 +186,7 @@ void sig_release(FAR struct task_group_s *group); FAR sigq_t *sig_allocatependingsigaction(void); void sig_deliver(FAR struct tcb_s *stcb); -FAR sigactq_t *sig_findaction(FAR struct tcb_s *stcb, int signo); +FAR sigactq_t *sig_findaction(FAR struct task_group_s *group, int signo); int sig_lowest(FAR sigset_t *set); #ifdef CONFIG_CAN_PASS_STRUCTS int sig_mqnotempty(int tid, int signo, union sigval value); diff --git a/sched/task/exit.c b/sched/task/exit.c index 85cc99cba3f575922612ad56130c08e2d06fde02..582fe5a05c57fcc969845c03aacb58e551f7ce2d 100644 --- a/sched/task/exit.c +++ b/sched/task/exit.c @@ -49,30 +49,6 @@ #include "task/task.h" #include "sched/sched.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -93,7 +69,7 @@ void exit(int status) { - struct tcb_s *tcb = (struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); /* Only the lower 8-bits of status are used */ diff --git a/sched/task/task.h b/sched/task/task.h index 17f4931516abdba7b68094302ff9012979e97c68..b4967c799a620dc5a10bc9d0ec2e15dedcc8e274 100644 --- a/sched/task/task.h +++ b/sched/task/task.h @@ -57,7 +57,7 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** * Public Function Prototypes diff --git a/sched/task/task_activate.c b/sched/task/task_activate.c index 43cc553aa08d7a6167f840d050a6e589fc7c9575..47791c7a259504439d6ef9554a674c2ccef133b8 100644 --- a/sched/task/task_activate.c +++ b/sched/task/task_activate.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_activate.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,31 +42,9 @@ #include #include +#include #include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ +#include /**************************************************************************** * Public Functions @@ -89,7 +67,7 @@ int task_activate(FAR struct tcb_s *tcb) { - irqstate_t flags = irqsave(); + irqstate_t flags = enter_critical_section(); #ifdef CONFIG_SCHED_INSTRUMENTATION @@ -112,6 +90,6 @@ int task_activate(FAR struct tcb_s *tcb) #endif up_unblock_task(tcb); - irqrestore(flags); + leave_critical_section(flags); return OK; } diff --git a/sched/task/task_atexit.c b/sched/task/task_atexit.c index d8d99eb9e62d2962bfbc08a7f5fdf413b5d8eba2..ba26f3ab8cc8d7927d368828159a8197c687f2e6 100644 --- a/sched/task/task_atexit.c +++ b/sched/task/task_atexit.c @@ -52,30 +52,6 @@ #ifdef CONFIG_SCHED_ATEXIT -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -121,7 +97,7 @@ int atexit(void (*func)(void)) return on_exit((onexitfunc_t)func, NULL); #elif defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1 - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; int index; int ret = ERROR; @@ -155,7 +131,7 @@ int atexit(void (*func)(void)) return ret; #else - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; int ret = ERROR; diff --git a/sched/task/task_create.c b/sched/task/task_create.c index 0da676fb420285ccb00b2e00d35442df9366a87f..1ced3b95157f04fdc3989d29875a76bb0e2b8d0b 100644 --- a/sched/task/task_create.c +++ b/sched/task/task_create.c @@ -52,22 +52,6 @@ #include "group/group.h" #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -188,7 +172,7 @@ static int thread_create(FAR const char *name, uint8_t ttype, int priority, /* The TCB was added to the active task list by task_schedsetup() */ - dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); + dq_rem((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks); goto errout_with_tcb; } diff --git a/sched/task/task_delete.c b/sched/task/task_delete.c index ae5ab231f654f649bfbddd211d9cd193370e7809..5b4c0f747dcc0d5e555cf0f57a98fbc26f199f15 100644 --- a/sched/task/task_delete.c +++ b/sched/task/task_delete.c @@ -46,30 +46,6 @@ #include "sched/sched.h" #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -117,7 +93,7 @@ int task_delete(pid_t pid) /* Check if the task to delete is the calling task */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); if (pid == 0 || pid == rtcb->pid) { /* If it is, then what we really wanted to do was exit. Note that we diff --git a/sched/task/task_execv.c b/sched/task/task_execv.c index 01d89f1393456a92e519ef0a1feee825e383a2df..c4457df537f26ff314c95e74d543fc535fb1d8f8 100644 --- a/sched/task/task_execv.c +++ b/sched/task/task_execv.c @@ -54,7 +54,7 @@ ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/sched/task/task_exit.c b/sched/task/task_exit.c index 89e2c0603c5b387181d2b8dbea2deaf8bafc3b80..964b1be8d0e04588fbc0deb5d297da07da6624a6 100644 --- a/sched/task/task_exit.c +++ b/sched/task/task_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_exit.c * - * Copyright (C) 2008-2009, 2012-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2012-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,30 +48,6 @@ #endif #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -106,7 +82,7 @@ int task_exit(void) { - FAR struct tcb_s *dtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *dtcb = this_task(); FAR struct tcb_s *rtcb; int ret; @@ -119,7 +95,7 @@ int task_exit(void) */ (void)sched_removereadytorun(dtcb); - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = this_task(); /* We are now in a bad state -- the head of the ready to run task list * does not correspond to the thread that is running. Disabling pre- @@ -131,6 +107,14 @@ int task_exit(void) */ rtcb->lockcount++; + +#ifdef CONFIG_SMP + /* Make sure that the system knows about the locked state */ + + spin_setbit(&g_cpu_lockset, this_cpu(), &g_cpu_locksetlock, + &g_cpu_schedlock); +#endif + rtcb->task_state = TSTATE_TASK_READYTORUN; /* Move the TCB to the specified blocked task list and delete it. Calling @@ -147,7 +131,7 @@ int task_exit(void) * task list now */ - if (g_pendingtasks.head) + if (g_pendingtasks.head != NULL) { (void)sched_mergepending(); } @@ -161,5 +145,16 @@ int task_exit(void) */ rtcb->lockcount--; + +#ifdef CONFIG_SMP + if (rtcb->lockcount == 0) + { + /* Make sure that the system knows about the unlocked state */ + + spin_clrbit(&g_cpu_lockset, this_cpu(), &g_cpu_locksetlock, + &g_cpu_schedlock); + } +#endif + return ret; } diff --git a/sched/task/task_exithook.c b/sched/task/task_exithook.c index 585b897d496786343a00284f46cffb445b9a4e40..b1210778d6cda8ce90e22adc67329fd57e4f5ead 100644 --- a/sched/task/task_exithook.c +++ b/sched/task/task_exithook.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_exithook.c * - * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -62,11 +62,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -343,6 +343,7 @@ static inline void task_sigchild(gid_t pgid, FAR struct tcb_s *ctcb, int status) info.si_signo = SIGCHLD; info.si_code = CLD_EXITED; + info.si_errno = OK; info.si_value.sival_ptr = NULL; #ifndef CONFIG_DISABLE_PTHREAD info.si_pid = chgrp->tg_task; @@ -394,6 +395,7 @@ static inline void task_sigchild(FAR struct tcb_s *ptcb, info.si_signo = SIGCHLD; info.si_code = CLD_EXITED; + info.si_errno = OK; info.si_value.sival_ptr = NULL; #ifndef CONFIG_DISABLE_PTHREAD info.si_pid = ctcb->group->tg_task; @@ -527,8 +529,8 @@ static inline void task_exitwakeup(FAR struct tcb_s *tcb, int status) { /* Yes.. Wakeup any tasks waiting for this task to exit */ - group->tg_statloc = NULL; - while (group->tg_exitsem.semcount < 0) + group->tg_statloc = NULL; + while (group->tg_exitsem.semcount < 0) { /* Wake up the thread */ diff --git a/sched/task/task_getgroup.c b/sched/task/task_getgroup.c index 0145709c57c207476228c84c53d36b725c8b21c8..6b18aaac14aa0a9f4f3215edbe401a5f8213c5b2 100644 --- a/sched/task/task_getgroup.c +++ b/sched/task/task_getgroup.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/**************************************************************************** * sched/task/task_getgroup.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include @@ -47,31 +47,31 @@ #ifdef HAVE_TASK_GROUP -/***************************************************************************** +/**************************************************************************** * Pre-processor Definitions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Private Types - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Private Data - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Data - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Private Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: task_getgroup * * Description: @@ -90,7 +90,7 @@ * precautions should be required here. However, extra care is taken when * accessing the global g_grouphead list. * - *****************************************************************************/ + ****************************************************************************/ FAR struct task_group_s *task_getgroup(pid_t pid) { diff --git a/sched/task/task_getpid.c b/sched/task/task_getpid.c index 7f538bd1b5b866529716a6416f556b79d57deb40..29ae703e8758245a56a210eb97276a0c6753b7e2 100644 --- a/sched/task/task_getpid.c +++ b/sched/task/task_getpid.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/task/task_getpid.c * * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include #include @@ -44,37 +44,17 @@ #include "sched/sched.h" #include "task/task.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Global Variables - ************************************************************************/ - -/************************************************************************ - * Private Variables - ************************************************************************/ - -/************************************************************************ - * Private Function Prototypes - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: getpid * * Description: * Get the task ID of the currently executing task. * - ************************************************************************/ + ****************************************************************************/ pid_t getpid(void) { @@ -82,12 +62,12 @@ pid_t getpid(void) /* Get the the TCB at the head of the ready-to-run task list. That * will be the currently executing task. There is an exception to - * this: Verify early in the start-up sequence, the g_readytorun - * list may be empty! This case, of course, the start-up/IDLE thread - * with pid == 0 must be running. + * this: Early in the start-up sequence, the ready-to-run list may be + * empty! This case, of course, the start-up/IDLE thread with pid == 0 + * must be running. */ - rtcb = (FAR struct tcb_s *)g_readytorun.head; + rtcb = this_task(); if (rtcb) { /* Return the task ID from the TCB at the head of the ready-to-run @@ -98,7 +78,7 @@ pid_t getpid(void) } /* We must have been called earlier in the start up sequence from the - * start-up/IDLE thread before the g_readytorun list has been initialized. + * start-up/IDLE thread before the ready-to-run list has been initialized. */ return 0; diff --git a/sched/task/task_init.c b/sched/task/task_init.c index 8a05cf60352ba9321e4966a6df9f1c5c5c296b60..8583c1ecc3d0f6e3e77198824439237d22efaffa 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -59,11 +59,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -138,7 +138,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority, } #endif - /* Associate file descriptors with the new task */ + /* Associate file descriptors with the new task */ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 ret = group_setuptaskfiles(ttcb); diff --git a/sched/task/task_onexit.c b/sched/task/task_onexit.c index 71d67102646ab2e94454350becc0f5c9ac1bebcc..6d3d47fce6b4df8fe667d36e3c22c3df1da7405c 100644 --- a/sched/task/task_onexit.c +++ b/sched/task/task_onexit.c @@ -52,30 +52,6 @@ #ifdef CONFIG_SCHED_ONEXIT -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -116,7 +92,7 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg) { #if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1 - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; int index; int ret = ENOSPC; @@ -151,7 +127,7 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg) return ret; #else - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; int ret = ENOSPC; diff --git a/sched/task/task_posixspawn.c b/sched/task/task_posixspawn.c index 65ee785ab34fc397cab76dd195f8172275e2de67..17172086fc19c512ecee64cfc64fa57121ac0bd6 100644 --- a/sched/task/task_posixspawn.c +++ b/sched/task/task_posixspawn.c @@ -438,22 +438,22 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path, goto errout_with_lock; } - /* Wait for the proxy to complete its job */ + /* Wait for the proxy to complete its job */ #ifdef CONFIG_SCHED_WAITPID - ret = waitpid(proxy, &status, 0); - if (ret < 0) - { - sdbg("ERROR: waitpid() failed: %d\n", errno); - goto errout_with_lock; - } + ret = waitpid(proxy, &status, 0); + if (ret < 0) + { + sdbg("ERROR: waitpid() failed: %d\n", errno); + goto errout_with_lock; + } #else - spawn_semtake(&g_spawn_execsem); + spawn_semtake(&g_spawn_execsem); #endif - /* Get the result and relinquish our access to the parameter structure */ + /* Get the result and relinquish our access to the parameter structure */ - ret = g_spawn_parms.result; + ret = g_spawn_parms.result; errout_with_lock: #ifdef CONFIG_SCHED_WAITPID diff --git a/sched/task/task_prctl.c b/sched/task/task_prctl.c index 5bbac6b9f95cf8c7cdb32265cc97afea60e5dfcd..1908872536dbcfca5cc7ea5252f8b2ea8038a181 100644 --- a/sched/task/task_prctl.c +++ b/sched/task/task_prctl.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/task/task_prctl.c * * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -50,13 +50,9 @@ #include "sched/sched.h" #include "task/task.h" -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ /**************************************************************************** * Name: prctl @@ -102,7 +98,7 @@ int prctl(int option, ...) if (!pid) { - tcb = (FAR struct tcb_s *)g_readytorun.head; + tcb = this_task(); } else { diff --git a/sched/task/task_reparent.c b/sched/task/task_reparent.c index 424356457a9a3e3379dde1f0693712bc51de5b26..690294ec024d7f4f99a80a7ad77e62f8ce84e24c 100644 --- a/sched/task/task_reparent.c +++ b/sched/task/task_reparent.c @@ -1,7 +1,7 @@ -/***************************************************************************** +/**************************************************************************** * sched/task/task_reparent.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,31 +31,29 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Included Files - *****************************************************************************/ + ****************************************************************************/ #include #include +#include + #include "sched/sched.h" #include "group/group.h" #include "task/task.h" #ifdef CONFIG_SCHED_HAVE_PARENT -/***************************************************************************** - * Private Functions - *****************************************************************************/ - -/***************************************************************************** +/**************************************************************************** * Public Functions - *****************************************************************************/ + ****************************************************************************/ -/***************************************************************************** +/**************************************************************************** * Name: task_reparent * * Description: @@ -69,7 +67,7 @@ * Return Value: * 0 (OK) on success; A negated errno value on failure. * - *****************************************************************************/ + ****************************************************************************/ #ifdef HAVE_GROUP_MEMBERS int task_reparent(pid_t ppid, pid_t chpid) @@ -90,7 +88,7 @@ int task_reparent(pid_t ppid, pid_t chpid) * the three task: Child, current parent, and new parent. */ - flags = irqsave(); + flags = enter_critical_section(); /* Get the child tasks task group */ @@ -202,7 +200,7 @@ int task_reparent(pid_t ppid, pid_t chpid) #endif /* CONFIG_SCHED_CHILD_STATUS */ errout_with_ints: - irqrestore(flags); + leave_critical_section(flags); return ret; } #else @@ -222,7 +220,7 @@ int task_reparent(pid_t ppid, pid_t chpid) * the three task: Child, current parent, and new parent. */ - flags = irqsave(); + flags = enter_critical_section(); /* Get the child tasks TCB (chtcb) */ @@ -314,7 +312,7 @@ int task_reparent(pid_t ppid, pid_t chpid) #endif /* CONFIG_SCHED_CHILD_STATUS */ errout_with_ints: - irqrestore(flags); + leave_critical_section(flags); return ret; } #endif diff --git a/sched/task/task_restart.c b/sched/task/task_restart.c index 0d86326968be5b6c69d24788b8507fd19aa4cb41..0656494696f31e20a8556694ca68ef9d6ec34ac2 100644 --- a/sched/task/task_restart.c +++ b/sched/task/task_restart.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_restart.c * - * Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,6 +43,7 @@ #include #include +#include #include #include "sched/sched.h" @@ -50,30 +51,6 @@ #include "signal/signal.h" #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -104,7 +81,8 @@ int task_restart(pid_t pid) { FAR struct tcb_s *rtcb; FAR struct task_tcb_s *tcb; - irqstate_t state; + FAR dq_queue_t *tasklist; + irqstate_t flags; int status; /* Make sure this task does not become ready-to-run while @@ -115,7 +93,7 @@ int task_restart(pid_t pid) /* Check if the task to restart is the calling task */ - rtcb = (FAR struct tcb_s *)g_readytorun.head; + rtcb = this_task(); if ((pid == 0) || (pid == rtcb->pid)) { /* Not implemented */ @@ -124,84 +102,102 @@ int task_restart(pid_t pid) return ERROR; } - /* We are restarting some other task than ourselves */ +#ifdef CONFIG_SMP + /* There is currently no capability to restart a task that is actively + * running on another CPU either. This is not the calling cast so if it + * is running, then it could only be running a a different CPU. + * + * Also, will need some interlocks to assure that no tasks are rescheduled + * on any other CPU while we do this. + */ - else +#warning Missing SMP logic + if (rtcb->task_state == TSTATE_TASK_RUNNING) { - /* Find for the TCB associated with matching pid */ + /* Not implemented */ + + set_errno(ENOSYS); + return ERROR; + } +#endif - tcb = (FAR struct task_tcb_s *)sched_gettcb(pid); + /* We are restarting some other task than ourselves */ + /* Find for the TCB associated with matching pid */ + + tcb = (FAR struct task_tcb_s *)sched_gettcb(pid); #ifndef CONFIG_DISABLE_PTHREAD - if (!tcb || (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) + if (!tcb || (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) #else - if (!tcb) + if (!tcb) #endif - { - /* There is no TCB with this pid or, if there is, it is not a - * task. - */ + { + /* There is no TCB with this pid or, if there is, it is not a task. */ - set_errno(ESRCH); - return ERROR; - } + set_errno(ESRCH); + return ERROR; + } - /* Try to recover from any bad states */ + /* Try to recover from any bad states */ - task_recover((FAR struct tcb_s *)tcb); + task_recover((FAR struct tcb_s *)tcb); - /* Kill any children of this thread */ + /* Kill any children of this thread */ -#if HAVE_GROUP_MEMBERS - (void)group_killchildren(tcb); +#ifdef HAVE_GROUP_MEMBERS + (void)group_killchildren(tcb); #endif - /* Remove the TCB from whatever list it is in. At this point, the - * TCB should no longer be accessible to the system - */ + /* Remove the TCB from whatever list it is in. After this point, the TCB + * should no longer be accessible to the system + */ - state = irqsave(); - dq_rem((FAR dq_entry_t*)tcb, - (dq_queue_t*)g_tasklisttable[tcb->cmn.task_state].list); - tcb->cmn.task_state = TSTATE_TASK_INVALID; - irqrestore(state); +#ifdef CONFIG_SMP + tasklist = TLIST_HEAD(tcb->cmn.task_state, tcb->cmn.cpu); +#else + tasklist = TLIST_HEAD(tcb->cmn.task_state); +#endif - /* Deallocate anything left in the TCB's queues */ + flags = enter_critical_section(); + dq_rem((FAR dq_entry_t *)tcb, tasklist); + tcb->cmn.task_state = TSTATE_TASK_INVALID; + leave_critical_section(flags); - sig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */ + /* Deallocate anything left in the TCB's queues */ - /* Reset the current task priority */ + sig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */ - tcb->cmn.sched_priority = tcb->init_priority; + /* Reset the current task priority */ - /* Reset the base task priority and the number of pending reprioritizations */ + tcb->cmn.sched_priority = tcb->init_priority; + + /* Reset the base task priority and the number of pending reprioritizations */ #ifdef CONFIG_PRIORITY_INHERITANCE - tcb->cmn.base_priority = tcb->init_priority; + tcb->cmn.base_priority = tcb->init_priority; # if CONFIG_SEM_NNESTPRIO > 0 - tcb->cmn.npend_reprio = 0; + tcb->cmn.npend_reprio = 0; # endif #endif - /* Re-initialize the processor-specific portion of the TCB - * This will reset the entry point and the start-up parameters - */ + /* Re-initialize the processor-specific portion of the TCB. This will + * reset the entry point and the start-up parameters + */ - up_initial_state((FAR struct tcb_s *)tcb); + up_initial_state((FAR struct tcb_s *)tcb); - /* Add the task to the inactive task list */ + /* Add the task to the inactive task list */ - dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); - tcb->cmn.task_state = TSTATE_TASK_INACTIVE; + dq_addfirst((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks); + tcb->cmn.task_state = TSTATE_TASK_INACTIVE; - /* Activate the task */ + /* Activate the task */ - status = task_activate((FAR struct tcb_s *)tcb); - if (status != OK) - { - (void)task_delete(pid); - set_errno(-status); - return ERROR; - } + status = task_activate((FAR struct tcb_s *)tcb); + if (status != OK) + { + (void)task_delete(pid); + set_errno(-status); + return ERROR; } sched_unlock(); diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index 5474c91265091117e6ad71003494f42795bddd6a..6d0ea9c2b2103511d505b4475cef055d850ff001 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_setup.c * - * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -63,27 +63,13 @@ #define MAX_STACK_ARGS 256 /**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /* This is the name for un-named tasks */ static const char g_noname[] = ""; -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int task_assignpid(FAR struct tcb_s* tcb); - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -160,6 +146,38 @@ static int task_assignpid(FAR struct tcb_s *tcb) return ERROR; } +/**************************************************************************** + * Name: task_inherit_affinity + * + * Description: + * exec(), task_create(), and vfork() all inherit the affinity mask from + * the parent thread. This is the default for pthread_create() as well + * but the affinity mask can be specified in the pthread attributes as + * well. pthread_setup() will have to fix up the affinity mask in this + * case. + * + * Parameters: + * tcb - The TCB of the new task. + * + * Returned Value: + * None + * + * Assumptions: + * The parent of the new task is the task at the head of the assigned task + * list for the current CPU. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +static inline void task_inherit_affinity(FAR struct tcb_s *tcb) +{ + FAR struct tcb_s *rtcb = this_task(); + tcb->affinity = rtcb->affinity; +} +#else +# define task_inherit_affinity(tcb) +#endif + /**************************************************************************** * Name: task_saveparent * @@ -183,7 +201,7 @@ static int task_assignpid(FAR struct tcb_s *tcb) #ifdef CONFIG_SCHED_HAVE_PARENT static inline void task_saveparent(FAR struct tcb_s *tcb, uint8_t ttype) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); #if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_SCHED_CHILD_STATUS) DEBUGASSERT(tcb && tcb->group && rtcb->group); @@ -288,7 +306,7 @@ static inline void task_saveparent(FAR struct tcb_s *tcb, uint8_t ttype) #ifdef CONFIG_PIC static inline void task_dupdspace(FAR struct tcb_s *tcb) { - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct tcb_s *rtcb = this_task(); if (rtcb->dspace != NULL) { /* Copy the D-Space structure reference and increment the reference @@ -362,11 +380,22 @@ static int thread_schedsetup(FAR struct tcb_s *tcb, int priority, task_saveparent(tcb, ttype); +#ifdef CONFIG_SMP + /* exec(), task_create(), and vfork() all inherit the affinity mask + * from the parent thread. This is the default for pthread_create() + * as well but the affinity mask can be specified in the pthread + * attributes as well. pthread_create() will have to fix up the + * affinity mask in this case. + */ + + task_inherit_affinity(tcb); +#endif + +#ifndef CONFIG_DISABLE_SIGNALS /* exec(), pthread_create(), task_create(), and vfork() all * inherit the signal mask of the parent thread. */ -#ifndef CONFIG_DISABLE_SIGNALS (void)sigprocmask(SIG_SETMASK, NULL, &tcb->sigprocmask); #endif @@ -390,7 +419,7 @@ static int thread_schedsetup(FAR struct tcb_s *tcb, int priority, /* Add the task to the inactive task list */ sched_lock(); - dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); + dq_addfirst((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks); tcb->task_state = TSTATE_TASK_INACTIVE; sched_unlock(); } @@ -499,7 +528,7 @@ static inline int task_stackargsetup(FAR struct task_tcb_s *tcb, strtablen += (strlen(argv[argc]) + 1); if (strtablen >= tcb->cmn.adj_stack_size) { - return -ENAMETOOLONG; + return -ENAMETOOLONG; } /* Increment the number of args. Here is a sanity check to @@ -520,7 +549,7 @@ static inline int task_stackargsetup(FAR struct task_tcb_s *tcb, * task name plus a NULL argv[] entry to terminate the list. */ - argvlen = (argc + 2)*sizeof(FAR char*); + argvlen = (argc + 2) * sizeof(FAR char *); stackargv = (FAR char **)up_stack_frame(&tcb->cmn, argvlen + strtablen); DEBUGASSERT(stackargv != NULL); @@ -642,8 +671,8 @@ int task_schedsetup(FAR struct task_tcb_s *tcb, int priority, start_t start, ****************************************************************************/ #ifndef CONFIG_DISABLE_PTHREAD -int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, start_t start, - pthread_startroutine_t entry) +int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, + start_t start, pthread_startroutine_t entry) { /* Perform common thread setup */ diff --git a/sched/task/task_spawn.c b/sched/task/task_spawn.c index 985350782929187c3c4a143ca88432727ee02b33..ef686e03ade36d1a4a1cd10e4d38095fa341f955 100644 --- a/sched/task/task_spawn.c +++ b/sched/task/task_spawn.c @@ -216,7 +216,7 @@ errout: static int task_spawn_proxy(int argc, FAR char *argv[]) { - int ret; + int ret; /* Perform file actions and/or set a custom signal mask. We get here only * if the file_actions parameter to task_spawn[p] was non-NULL and/or the @@ -421,7 +421,7 @@ int task_spawn(FAR pid_t *pid, FAR const char *name, main_t entry, proxy = task_create("task_spawn_proxy", param.sched_priority, CONFIG_POSIX_SPAWN_PROXY_STACKSIZE, (main_t)task_spawn_proxy, - (FAR char * const*)NULL); + (FAR char * const *)NULL); if (proxy < 0) { ret = get_errno(); @@ -430,22 +430,22 @@ int task_spawn(FAR pid_t *pid, FAR const char *name, main_t entry, goto errout_with_lock; } - /* Wait for the proxy to complete its job */ + /* Wait for the proxy to complete its job */ #ifdef CONFIG_SCHED_WAITPID - ret = waitpid(proxy, &status, 0); - if (ret < 0) - { - sdbg("ERROR: waitpid() failed: %d\n", errno); - goto errout_with_lock; - } + ret = waitpid(proxy, &status, 0); + if (ret < 0) + { + sdbg("ERROR: waitpid() failed: %d\n", errno); + goto errout_with_lock; + } #else - spawn_semtake(&g_spawn_execsem); + spawn_semtake(&g_spawn_execsem); #endif - /* Get the result and relinquish our access to the parameter structure */ + /* Get the result and relinquish our access to the parameter structure */ - ret = g_spawn_parms.result; + ret = g_spawn_parms.result; errout_with_lock: #ifdef CONFIG_SCHED_WAITPID diff --git a/sched/task/task_spawnparms.c b/sched/task/task_spawnparms.c index 8e1b0318fbf7c5e55b6f103281ad79480ff48787..df0946c2fb69a8ab6183770357d09f881c7ebe48 100644 --- a/sched/task/task_spawnparms.c +++ b/sched/task/task_spawnparms.c @@ -127,7 +127,7 @@ static inline int spawn_open(FAR struct spawn_open_file_action_s *action) } /* Does the return file descriptor happen to match the required file - * desciptor number? + * descriptor number? */ else if (fd != action->fd) diff --git a/sched/task/task_start.c b/sched/task/task_start.c index 9432c537e5808c64713aa99e2222221f9abeabd3..acff33e66cd2ca7bf18f97c95ae982a138c80d07 100644 --- a/sched/task/task_start.c +++ b/sched/task/task_start.c @@ -63,11 +63,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** @@ -100,7 +100,7 @@ void task_start(void) { - FAR struct task_tcb_s *tcb = (FAR struct task_tcb_s*)g_readytorun.head; + FAR struct task_tcb_s *tcb = (FAR struct task_tcb_s *)this_task(); int exitcode; int argc; diff --git a/sched/task/task_starthook.c b/sched/task/task_starthook.c index 7c43b7b26707784797c7b6f6a5bc75e276fcbf5a..f102afc0a7cab30ca6f6b7d15f468f7254891d2e 100644 --- a/sched/task/task_starthook.c +++ b/sched/task/task_starthook.c @@ -54,11 +54,11 @@ ****************************************************************************/ /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ /**************************************************************************** - * Private Variables + * Private Data ****************************************************************************/ /**************************************************************************** diff --git a/sched/task/task_terminate.c b/sched/task/task_terminate.c index c8192f50bcb8f19abe576451ff7e2507489f2f51..f9b115f8e40bf4ac996d0cc4041aa3f5949c0ad5 100644 --- a/sched/task/task_terminate.c +++ b/sched/task/task_terminate.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_terminate.c * - * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,7 +45,8 @@ #include #include -#include +#include +#include #include "sched/sched.h" #ifndef CONFIG_DISABLE_SIGNALS @@ -53,30 +54,6 @@ #endif #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -124,7 +101,8 @@ int task_terminate(pid_t pid, bool nonblocking) { FAR struct tcb_s *dtcb; - irqstate_t saved_state; + FAR dq_queue_t *tasklist; + irqstate_t flags; /* Make sure the task does not become ready-to-run while we are futzing with * its TCB by locking ourselves as the executing task. @@ -143,6 +121,14 @@ int task_terminate(pid_t pid, bool nonblocking) return -ESRCH; } +#ifdef CONFIG_SMP + /* We will need some interlocks to assure that no tasks are rescheduled + * on any other CPU while we do this. + */ + +# warning Missing SMP logic +#endif + /* Verify our internal sanity */ if (dtcb->task_state == TSTATE_TASK_RUNNING || @@ -165,12 +151,18 @@ int task_terminate(pid_t pid, bool nonblocking) task_exithook(dtcb, EXIT_SUCCESS, nonblocking); - /* Remove the task from the OS's tasks lists. */ + /* Remove the task from the OS's task lists. */ + +#ifdef CONFIG_SMP + tasklist = TLIST_HEAD(dtcb->task_state, dtcb->cpu); +#else + tasklist = TLIST_HEAD(dtcb->task_state); +#endif - saved_state = irqsave(); - dq_rem((FAR dq_entry_t*)dtcb, (dq_queue_t*)g_tasklisttable[dtcb->task_state].list); + flags = enter_critical_section(); + dq_rem((FAR dq_entry_t *)dtcb, tasklist); dtcb->task_state = TSTATE_TASK_INVALID; - irqrestore(saved_state); + leave_critical_section(flags); /* At this point, the TCB should no longer be accessible to the system */ diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c index 20e74179b1faeab4e012239be38ad5102abc3276..b2fef61d3675febe46a480382d9fdf79e0b9432c 100644 --- a/sched/task/task_vfork.c +++ b/sched/task/task_vfork.c @@ -240,7 +240,7 @@ static inline int vfork_argsetup(FAR struct tcb_s *parent, FAR struct task_tcb_s *task_vforksetup(start_t retaddr) { - struct tcb_s *parent = (FAR struct tcb_s *)g_readytorun.head; + struct tcb_s *parent = this_task(); struct task_tcb_s *child; uint8_t ttype; int priority; @@ -364,12 +364,12 @@ errout_with_tcb: pid_t task_vforkstart(FAR struct task_tcb_s *child) { - struct tcb_s *parent = (FAR struct tcb_s *)g_readytorun.head; + struct tcb_s *parent = this_task(); pid_t pid; int rc; int ret; - svdbg("Starting Child TCB=%p, parent=%p\n", child, g_readytorun.head); + svdbg("Starting Child TCB=%p, parent=%p\n", child, this_task()); DEBUGASSERT(child); /* Duplicate the original argument list in the forked child TCB */ @@ -458,7 +458,7 @@ void task_vforkabort(FAR struct task_tcb_s *child, int errcode) { /* The TCB was added to the active task list by task_schedsetup() */ - dq_rem((FAR dq_entry_t*)child, (dq_queue_t*)&g_inactivetasks); + dq_rem((FAR dq_entry_t *)child, (FAR dq_queue_t *)&g_inactivetasks); /* Release the TCB */ diff --git a/sched/timer/timer.h b/sched/timer/timer.h index 1f139a1f426d0018df4967b14f6d7136fce15931..6165d9e847b3d69aedc8c89535455141836c034a 100644 --- a/sched/timer/timer.h +++ b/sched/timer/timer.h @@ -1,7 +1,7 @@ /******************************************************************************** * sched/timer/timer.h * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -67,12 +67,11 @@ struct posix_timer_s uint8_t pt_flags; /* See PT_FLAGS_* definitions */ uint8_t pt_crefs; /* Reference count */ - uint8_t pt_signo; /* Notification signal */ pid_t pt_owner; /* Creator of timer */ int pt_delay; /* If non-zero, used to reset repetitive timers */ int pt_last; /* Last value used to set watchdog */ WDOG_ID pt_wdog; /* The watchdog that provides the timing */ - union sigval pt_value; /* Data passed with notification */ + struct sigevent pt_event; /* Notification information */ }; /******************************************************************************** diff --git a/sched/timer/timer_create.c b/sched/timer/timer_create.c index fc8f9acd4ab1da321fc10dd857310589e2ffee38..a573ff38ba2a07732ea61b63acb87562ed961e76 100644 --- a/sched/timer/timer_create.c +++ b/sched/timer/timer_create.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/timer/timer_create.c * - * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -52,18 +53,6 @@ #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - /******************************************************************************** * Private Functions ********************************************************************************/ @@ -76,18 +65,18 @@ * ********************************************************************************/ -static struct posix_timer_s *timer_allocate(void) +static FAR struct posix_timer_s *timer_allocate(void) { - struct posix_timer_s *ret; - irqstate_t flags; - uint8_t pt_flags; + FAR struct posix_timer_s *ret; + irqstate_t flags; + uint8_t pt_flags; /* Try to get a preallocated timer from the free list */ #if CONFIG_PREALLOC_TIMERS > 0 - flags = irqsave(); - ret = (struct posix_timer_s*)sq_remfirst((sq_queue_t*)&g_freetimers); - irqrestore(flags); + flags = enter_critical_section(); + ret = (FAR struct posix_timer_s *)sq_remfirst((FAR sq_queue_t *)&g_freetimers); + leave_critical_section(flags); /* Did we get one? */ @@ -100,7 +89,7 @@ static struct posix_timer_s *timer_allocate(void) { /* Allocate a new timer from the heap */ - ret = (struct posix_timer_s*)kmm_malloc(sizeof(struct posix_timer_s)); + ret = (FAR struct posix_timer_s *)kmm_malloc(sizeof(struct posix_timer_s)); pt_flags = 0; } @@ -115,9 +104,9 @@ static struct posix_timer_s *timer_allocate(void) /* And add it to the end of the list of allocated timers */ - flags = irqsave(); - sq_addlast((sq_entry_t*)ret, (sq_queue_t*)&g_alloctimers); - irqrestore(flags); + flags = enter_critical_section(); + sq_addlast((FAR sq_entry_t *)ret, (FAR sq_queue_t *)&g_alloctimers); + leave_critical_section(flags); } return ret; @@ -177,8 +166,8 @@ static struct posix_timer_s *timer_allocate(void) int timer_create(clockid_t clockid, FAR struct sigevent *evp, FAR timer_t *timerid) { - struct posix_timer_s *ret; - WDOG_ID wdog; + FAR struct posix_timer_s *ret; + WDOG_ID wdog; /* Sanity checks. Also, we support only CLOCK_REALTIME */ @@ -213,19 +202,31 @@ int timer_create(clockid_t clockid, FAR struct sigevent *evp, FAR timer_t *timer ret->pt_delay = 0; ret->pt_wdog = wdog; + /* Was a struct sigevent provided? */ + if (evp) { - ret->pt_signo = evp->sigev_signo; -#ifdef CONFIG_CAN_PASS_STRUCTS - ret->pt_value = evp->sigev_value; -#else - ret->pt_value.sival_ptr = evp->sigev_value.sival_ptr; -#endif + /* Yes, copy the entire struct sigevent content */ + + memcpy(&ret->pt_event, evp, sizeof(struct sigevent)); } else { - ret->pt_signo = SIGALRM; - ret->pt_value.sival_ptr = ret; + /* "If the evp argument is NULL, the effect is as if the evp argument + * pointed to a sigevent structure with the sigev_notify member + * having the value SIGEV_SIGNAL, the sigev_signo having a default + * signal number, and the sigev_value member having the value of the + * timer ID." + */ + + ret->pt_event.sigev_notify = SIGEV_SIGNAL; + ret->pt_event.sigev_signo = SIGALRM; + ret->pt_event.sigev_value.sival_ptr = ret; + +#ifdef CONFIG_SIG_EVTHREAD + ret->pt_event.sigev_notify_function = NULL; + ret->pt_event.sigev_notify_attributes = NULL; +#endif } /* Return the timer */ diff --git a/sched/timer/timer_delete.c b/sched/timer/timer_delete.c index 45933db2103fff72d12f7f095c22ced9aeed7388..495db81dc1da285246edb59e4094f02fd98e0d72 100644 --- a/sched/timer/timer_delete.c +++ b/sched/timer/timer_delete.c @@ -46,22 +46,6 @@ #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/timer/timer_getoverrun.c b/sched/timer/timer_getoverrun.c index ce2d44ba17fd2bb922b4acb4dba3c5e5f74b3087..e92a81bef9b928925855a120eaa3928144c7f2e8 100644 --- a/sched/timer/timer_getoverrun.c +++ b/sched/timer/timer_getoverrun.c @@ -46,22 +46,6 @@ #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/timer/timer_gettime.c b/sched/timer/timer_gettime.c index 0653432302e497f882ea08c50ba52cf6aa4093c2..44bf877c9f3c1557a89e382747371691349f252f 100644 --- a/sched/timer/timer_gettime.c +++ b/sched/timer/timer_gettime.c @@ -47,22 +47,6 @@ #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ diff --git a/sched/timer/timer_initialize.c b/sched/timer/timer_initialize.c index e28445d5e728b42658e2eb3cc3124e3254f3a347..2a215c605cfac5584048d5756f5ad99de05ad0e7 100644 --- a/sched/timer/timer_initialize.c +++ b/sched/timer/timer_initialize.c @@ -45,16 +45,12 @@ #include #include -#include +#include #include "timer/timer.h" #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - /******************************************************************************** * Private Data ********************************************************************************/ @@ -82,10 +78,6 @@ volatile sq_queue_t g_freetimers; volatile sq_queue_t g_alloctimers; -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ @@ -113,18 +105,19 @@ void weak_function timer_initialize(void) /* Place all of the pre-allocated timers into the free timer list */ - sq_init((sq_queue_t*)&g_freetimers); + sq_init((FAR sq_queue_t *)&g_freetimers); for (i = 0; i < CONFIG_PREALLOC_TIMERS; i++) { g_prealloctimers[i].pt_flags = PT_FLAGS_PREALLOCATED; - sq_addlast((FAR sq_entry_t*)&g_prealloctimers[i], (FAR sq_queue_t*)&g_freetimers); + sq_addlast((FAR sq_entry_t *)&g_prealloctimers[i], + (FAR sq_queue_t *)&g_freetimers); } #endif /* Initialize the list of allocated timers */ - sq_init((sq_queue_t*)&g_alloctimers); + sq_init((FAR sq_queue_t *)&g_alloctimers); } /******************************************************************************** @@ -154,8 +147,8 @@ void weak_function timer_deleteall(pid_t pid) FAR struct posix_timer_s *next; irqstate_t flags; - flags = irqsave(); - for (timer = (FAR struct posix_timer_s*)g_alloctimers.head; timer; timer = next) + flags = enter_critical_section(); + for (timer = (FAR struct posix_timer_s *)g_alloctimers.head; timer; timer = next) { next = timer->flink; if (timer->pt_owner == pid) @@ -164,7 +157,7 @@ void weak_function timer_deleteall(pid_t pid) } } - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_DISABLE_POSIX_TIMERS */ diff --git a/sched/timer/timer_release.c b/sched/timer/timer_release.c index 2eb2a004bdca9a9c2ae9d4a47f99985a89de5003..3ad62febbc11ab827d9df72892892262cb1688d1 100644 --- a/sched/timer/timer_release.c +++ b/sched/timer/timer_release.c @@ -10,7 +10,7 @@ * * 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 + * 2. Redistributions i, 2016n 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. @@ -42,24 +42,13 @@ #include #include +#include #include #include "timer/timer.h" #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - /******************************************************************************** * Private Functions ********************************************************************************/ @@ -80,23 +69,23 @@ static inline void timer_free(struct posix_timer_s *timer) /* Remove the timer from the allocated list */ - flags = irqsave(); - sq_rem((FAR sq_entry_t*)timer, (sq_queue_t*)&g_alloctimers); + flags = enter_critical_section(); + sq_rem((FAR sq_entry_t *)timer, (FAR sq_queue_t *)&g_alloctimers); /* Return it to the free list if it is one of the preallocated timers */ #if CONFIG_PREALLOC_TIMERS > 0 if ((timer->pt_flags & PT_FLAGS_PREALLOCATED) != 0) { - sq_addlast((FAR sq_entry_t*)timer, (FAR sq_queue_t*)&g_freetimers); - irqrestore(flags); + sq_addlast((FAR sq_entry_t *)timer, (FAR sq_queue_t *)&g_freetimers); + leave_critical_section(flags); } else #endif { /* Otherwise, return it to the heap */ - irqrestore(flags); + leave_critical_section(flags); sched_kfree(timer); } } diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c index 432b6d206801c244b48fa927152ef8b53b8b88ed..d134441e3e8ed2d811b2a93dd989fe2efc236c0d 100644 --- a/sched/timer/timer_settime.c +++ b/sched/timer/timer_settime.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/timer/timer_settime.c * - * Copyright (C) 2007-2010, 2013-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,29 +44,20 @@ #include #include +#include +#include + #include "clock/clock.h" #include "signal/signal.h" #include "timer/timer.h" #ifndef CONFIG_DISABLE_POSIX_TIMERS -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Data - ********************************************************************************/ - -/******************************************************************************** - * Public Data - ********************************************************************************/ - /******************************************************************************** * Private Function Prototypes ********************************************************************************/ -static inline void timer_sigqueue(FAR struct posix_timer_s *timer); +static inline void timer_signotify(FAR struct posix_timer_s *timer); static inline void timer_restart(FAR struct posix_timer_s *timer, wdparm_t itimer); static void timer_timeout(int argc, wdparm_t itimer); @@ -75,7 +66,7 @@ static void timer_timeout(int argc, wdparm_t itimer); ********************************************************************************/ /******************************************************************************** - * Name: timer_sigqueue + * Name: timer_signotify * * Description: * This function basically reimplements sigqueue() so that the si_code can @@ -92,27 +83,42 @@ static void timer_timeout(int argc, wdparm_t itimer); * ********************************************************************************/ -static inline void timer_sigqueue(FAR struct posix_timer_s *timer) +static inline void timer_signotify(FAR struct posix_timer_s *timer) { siginfo_t info; - /* Create the siginfo structure */ + /* Notify client via a signal? */ - info.si_signo = timer->pt_signo; - info.si_code = SI_TIMER; + if (timer->pt_event.sigev_notify == SIGEV_SIGNAL) + { + /* Yes.. Create the siginfo structure */ + + info.si_signo = timer->pt_event.sigev_signo; + info.si_code = SI_TIMER; + info.si_errno = OK; #ifdef CONFIG_CAN_PASS_STRUCTS - info.si_value = timer->pt_value; + info.si_value = timer->pt_event.sigev_value; #else - info.si_value.sival_ptr = timer->pt_value.sival_ptr; + info.si_value.sival_ptr = timer->pt_event.sigev_value.sival_ptr; #endif #ifdef CONFIG_SCHED_HAVE_PARENT - info.si_pid = 0; /* Not applicable */ - info.si_status = OK; + info.si_pid = 0; /* Not applicable */ + info.si_status = OK; #endif - /* Send the signal */ + /* Send the signal */ + + DEBUGVERIFY(sig_dispatch(timer->pt_owner, &info)); + } + +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ - (void)sig_dispatch(timer->pt_owner, &info); + else if (timer->pt_event.sigev_notify == SIGEV_THREAD) + { + DEBUGVERIFY(sig_notification(timer->pt_owner, &timer->pt_event)); + } +#endif } /******************************************************************************** @@ -169,7 +175,7 @@ static void timer_timeout(int argc, wdparm_t itimer) { #ifndef CONFIG_CAN_PASS_STRUCTS /* On many small machines, pointers are encoded and cannot be simply cast from - * wdparm_t to struct tcb_s*. The following union works around this (see wdogparm_t). + * wdparm_t to struct tcb_s *. The following union works around this (see wdogparm_t). */ union @@ -186,7 +192,7 @@ static void timer_timeout(int argc, wdparm_t itimer) */ u.timer->pt_crefs++; - timer_sigqueue(u.timer); + timer_signotify(u.timer); /* Release the reference. timer_release will return nonzero if the timer * was not deleted. @@ -194,7 +200,7 @@ static void timer_timeout(int argc, wdparm_t itimer) if (timer_release(u.timer)) { - /* If this is a repetitive timer, the restart the watchdog */ + /* If this is a repetitive timer, then restart the watchdog */ timer_restart(u.timer, itimer); } @@ -207,7 +213,7 @@ static void timer_timeout(int argc, wdparm_t itimer) */ timer->pt_crefs++; - timer_sigqueue(timer); + timer_signotify(timer); /* Release the reference. timer_release will return nonzero if the timer * was not deleted. @@ -293,7 +299,7 @@ int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value FAR struct itimerspec *ovalue) { FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid; - irqstate_t state; + irqstate_t intflags; int delay; int ret = OK; @@ -333,7 +339,7 @@ int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value * that the system timer is stable. */ - state = irqsave(); + intflags = enter_critical_section(); /* Check if abstime is selected */ @@ -375,7 +381,7 @@ int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value 1, (uint32_t)((wdparm_t)timer)); } - irqrestore(state); + leave_critical_section(intflags); return ret; } diff --git a/sched/wdog/wd_cancel.c b/sched/wdog/wd_cancel.c index 1a53801d465734903f6e184e5f3284b52294333e..ac8db7ed3375e4f6a08fa868327877be83e7fc0b 100644 --- a/sched/wdog/wd_cancel.c +++ b/sched/wdog/wd_cancel.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wdog/wd_cancel.c * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,32 +42,13 @@ #include #include +#include #include #include #include "sched/sched.h" #include "wdog/wdog.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -93,14 +74,14 @@ int wd_cancel(WDOG_ID wdog) { FAR struct wdog_s *curr; FAR struct wdog_s *prev; - irqstate_t state; + irqstate_t flags; int ret = ERROR; /* Prohibit timer interactions with the timer queue until the * cancellation is complete */ - state = irqsave(); + flags = enter_critical_section(); /* Make sure that the watchdog is initialized (non-NULL) and is still * active. @@ -143,7 +124,7 @@ int wd_cancel(WDOG_ID wdog) { /* Remove the watchdog from mid- or end-of-queue */ - (void)sq_remafter((FAR sq_entry_t*)prev, &g_wdactivelist); + (void)sq_remafter((FAR sq_entry_t *)prev, &g_wdactivelist); } else { @@ -168,6 +149,6 @@ int wd_cancel(WDOG_ID wdog) ret = OK; } - irqrestore(state); + leave_critical_section(flags); return ret; } diff --git a/sched/wdog/wd_create.c b/sched/wdog/wd_create.c index 2c04724a404f8010839318a2795ceb955ba643a1..416da9c351f3a1234cecadf57acf859de8490c80 100644 --- a/sched/wdog/wd_create.c +++ b/sched/wdog/wd_create.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wdog/wd_create.c * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,32 +42,13 @@ #include #include -#include +#include +#include #include #include #include "wdog/wdog.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -93,14 +74,14 @@ WDOG_ID wd_create (void) { FAR struct wdog_s *wdog; - irqstate_t state; + irqstate_t flags; /* These actions must be atomic with respect to other tasks and also with * respect to interrupt handlers that may be allocating or freeing watchdog * timers. */ - state = irqsave(); + flags = enter_critical_section(); /* If we are in an interrupt handler -OR- if the number of pre-allocated * timer structures exceeds the reserve, then take the the next timer from @@ -109,24 +90,34 @@ WDOG_ID wd_create (void) if (g_wdnfree > CONFIG_WDOG_INTRESERVE || up_interrupt_context()) { - /* Remove the watchdog timer from the free list and decrement the - * count of free timers all with interrupts disabled. - */ + /* Remove the watchdog timer from the free list */ wdog = (FAR struct wdog_s *)sq_remfirst(&g_wdfreelist); - DEBUGASSERT(g_wdnfree > 0); - g_wdnfree--; - irqrestore(state); /* Did we get one? */ - if (wdog) + if (wdog != NULL) { - /* Yes.. Clear the forward link and all flags */ + /* Yes.. decrement the count of free, pre-allocated timers (all + * with interrupts disabled). + */ + + DEBUGASSERT(g_wdnfree > 0); + g_wdnfree--; - wdog->next = NULL; + /* Clear the forward link and all flags */ + + wdog->next = NULL; wdog->flags = 0; } + else + { + /* We didn't get one... The count should then be exactly zero */ + + DEBUGASSERT(g_wdnfree == 0); + } + + leave_critical_section(flags); } /* We are in a normal tasking context AND there are not enough unreserved, @@ -138,7 +129,7 @@ WDOG_ID wd_create (void) { /* We do not require that interrupts be disabled to do this. */ - irqrestore(state); + leave_critical_section(flags); wdog = (FAR struct wdog_s *)kmm_malloc(sizeof(struct wdog_s)); /* Did we get one? */ diff --git a/sched/wdog/wd_delete.c b/sched/wdog/wd_delete.c index 11345ae055fe4916f68430313b0cd9b3982eb5a7..d28252fce47e80277c9794a73b36d9b59fbd4b76 100644 --- a/sched/wdog/wd_delete.c +++ b/sched/wdog/wd_delete.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wdog/wd_delete.c * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,32 +43,13 @@ #include #include +#include #include #include #include #include "wdog/wdog.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -95,7 +76,7 @@ int wd_delete(WDOG_ID wdog) { - irqstate_t state; + irqstate_t flags; DEBUGASSERT(wdog); @@ -103,7 +84,7 @@ int wd_delete(WDOG_ID wdog) * it is being deallocated. */ - state = irqsave(); + flags = enter_critical_section(); /* Check if the watchdog has been started. */ @@ -128,7 +109,7 @@ int wd_delete(WDOG_ID wdog) * We don't need interrupts disabled to do this. */ - irqrestore(state); + leave_critical_section(flags); sched_kfree(wdog); } @@ -142,10 +123,10 @@ int wd_delete(WDOG_ID wdog) * timers, all with interrupts disabled. */ - sq_addlast((FAR sq_entry_t*)wdog, &g_wdfreelist); + sq_addlast((FAR sq_entry_t *)wdog, &g_wdfreelist); g_wdnfree++; DEBUGASSERT(g_wdnfree <= CONFIG_PREALLOC_WDOGS); - irqrestore(state); + leave_critical_section(flags); } /* Return success */ diff --git a/sched/wdog/wd_gettime.c b/sched/wdog/wd_gettime.c index 3c553fde8ee90c2b64b164f7ea60784fa72df499..f533f42f1ec2868c9122887700ea01f83e89fdd4 100644 --- a/sched/wdog/wd_gettime.c +++ b/sched/wdog/wd_gettime.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/wdog/wd_gettime.c * - * Copyright (C) 2007, 2009, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -40,30 +40,10 @@ #include #include -#include +#include #include "wdog/wdog.h" -/******************************************************************************** - * Pre-processor Definitions - ********************************************************************************/ - -/******************************************************************************** - * Private Types - ********************************************************************************/ - -/******************************************************************************** - * Global Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Variables - ********************************************************************************/ - -/******************************************************************************** - * Private Functions - ********************************************************************************/ - /******************************************************************************** * Public Functions ********************************************************************************/ @@ -92,7 +72,7 @@ int wd_gettime(WDOG_ID wdog) /* Verify the wdog */ - flags = irqsave(); + flags = enter_critical_section(); if (wdog && WDOG_ISACTIVE(wdog)) { /* Traverse the watchdog list accumulating lag times until we find the wdog @@ -107,12 +87,12 @@ int wd_gettime(WDOG_ID wdog) delay += curr->lag; if (curr == wdog) { - irqrestore(flags); + leave_critical_section(flags); return delay; } } } - irqrestore(flags); + leave_critical_section(flags); return 0; } diff --git a/sched/wdog/wd_initialize.c b/sched/wdog/wd_initialize.c index 23242b6bf519f99e4b6f734e54faadac3617fd65..54b98e4838431a9c24ebc511b9a3453a50763ce5 100644 --- a/sched/wdog/wd_initialize.c +++ b/sched/wdog/wd_initialize.c @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/wdog/wd_initialize.c * * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. @@ -31,11 +31,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -43,17 +43,9 @@ #include "wdog/wdog.h" -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Private Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ /* The g_wdfreelist data structure is a singly linked list of watchdogs * available to the system for delayed function use. @@ -75,25 +67,21 @@ sq_queue_t g_wdactivelist; uint16_t g_wdnfree; -/************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************/ + ****************************************************************************/ /* g_wdpool is a list of pre-allocated watchdogs. The number of watchdogs -* in the pool is a configuration item. + * in the pool is a configuration item. */ static struct wdog_s g_wdpool[CONFIG_PREALLOC_WDOGS]; -/************************************************************************ - * Private Functions - ************************************************************************/ - -/************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: wd_initialize * * Description: @@ -110,7 +98,7 @@ static struct wdog_s g_wdpool[CONFIG_PREALLOC_WDOGS]; * before the timer interrupt is attached and before any watchdog * services are used. * - ************************************************************************/ + ****************************************************************************/ void wd_initialize(void) { @@ -128,7 +116,7 @@ void wd_initialize(void) for (i = 0; i < CONFIG_PREALLOC_WDOGS; i++) { - sq_addlast((FAR sq_entry_t*)wdog++, &g_wdfreelist); + sq_addlast((FAR sq_entry_t *)wdog++, &g_wdfreelist); } /* All watchdogs are free */ diff --git a/sched/wdog/wd_recover.c b/sched/wdog/wd_recover.c index bc1b3a839e9390a990a8bfee47ede9a1edc3e16b..2a4847471b3e61c023ba520d329723bcd70aa0be 100644 --- a/sched/wdog/wd_recover.c +++ b/sched/wdog/wd_recover.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wdog/wdog_recover.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -39,36 +39,13 @@ #include +#include #include #include #include #include "wdog/wdog.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -103,7 +80,7 @@ void wd_recover(FAR struct tcb_s *tcb) * the future. */ - flags = irqsave(); + flags = enter_critical_section(); if (tcb->waitdog) { (void)wd_cancel(tcb->waitdog); @@ -111,5 +88,5 @@ void wd_recover(FAR struct tcb_s *tcb) tcb->waitdog = NULL; } - irqrestore(flags); + leave_critical_section(flags); } diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index ba7cc06aa282be07ed12f8215cd37d18587d187b..9e99d01277fb462f3258650f57d1b1663ae08575 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wdog/wd_start.c * - * Copyright (C) 2007-2009, 2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -85,17 +86,10 @@ typedef void (*wdentry4_t)(int argc, wdparm_t arg1, wdparm_t arg2, wdparm_t arg3, wdparm_t arg4); #endif -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ + /**************************************************************************** * Name: wd_expiration * @@ -180,7 +174,7 @@ static inline void wd_expiration(void) case 4: (*((wdentry4_t)(wdog->func)))(4, wdog->parm[0], wdog->parm[1], - wdog->parm[2] ,wdog->parm[3]); + wdog->parm[2], wdog->parm[3]); break; #endif } @@ -225,14 +219,14 @@ static inline void wd_expiration(void) * ****************************************************************************/ -int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) +int wd_start(WDOG_ID wdog, int32_t delay, wdentry_t wdentry, int argc, ...) { va_list ap; FAR struct wdog_s *curr; FAR struct wdog_s *prev; FAR struct wdog_s *next; int32_t now; - irqstate_t state; + irqstate_t flags; int i; /* Verify the wdog */ @@ -249,7 +243,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) * the critical section is established. */ - state = irqsave(); + flags = enter_critical_section(); if (WDOG_ISACTIVE(wdog)) { wd_cancel(wdog); @@ -301,7 +295,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) { /* Add the watchdog to the head == tail of the queue. */ - sq_addlast((FAR sq_entry_t*)wdog, &g_wdactivelist); + sq_addlast((FAR sq_entry_t *)wdog, &g_wdactivelist); } /* There are other active watchdogs in the timer queue */ @@ -322,11 +316,11 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) /* Advance past shorter delays */ while (now <= delay && curr->next) - { - prev = curr; - curr = curr->next; - now += curr->lag; - } + { + prev = curr; + curr = curr->next; + now += curr->lag; + } /* Check if the new wdog must be inserted before the curr. */ @@ -368,13 +362,13 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) delay -= now; if (!curr->next) { - sq_addlast((FAR sq_entry_t*)wdog, &g_wdactivelist); + sq_addlast((FAR sq_entry_t *)wdog, &g_wdactivelist); } else { next = curr->next; next->lag -= delay; - sq_addafter((FAR sq_entry_t*)curr, (FAR sq_entry_t*)wdog, + sq_addafter((FAR sq_entry_t *)curr, (FAR sq_entry_t *)wdog, &g_wdactivelist); } } @@ -394,7 +388,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...) sched_timer_resume(); #endif - irqrestore(state); + leave_critical_section(flags); return OK; } diff --git a/sched/wdog/wdog.h b/sched/wdog/wdog.h index f26b90f910cc17dfb8b3ef3b0b3824bccaf2b962..73e4d4b9698769591ec0ddf64910a247c8da1d4f 100644 --- a/sched/wdog/wdog.h +++ b/sched/wdog/wdog.h @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * sched/wdog/wdog.h * * Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved. @@ -31,14 +31,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ #ifndef __SCHED_WDOG_WDOG_H #define __SCHED_WDOG_WDOG_H -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include @@ -48,17 +48,9 @@ #include #include -/************************************************************************ - * Pre-processor Definitions - ************************************************************************/ - -/************************************************************************ - * Public Type Declarations - ************************************************************************/ - -/************************************************************************ - * Public Variables - ************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ #ifdef __cplusplus #define EXTERN extern "C" @@ -88,11 +80,11 @@ extern sq_queue_t g_wdactivelist; extern uint16_t g_wdnfree; -/************************************************************************ +/**************************************************************************** * Public Function Prototypes - ************************************************************************/ + ****************************************************************************/ -/************************************************************************ +/**************************************************************************** * Name: wd_initialize * * Description: @@ -109,7 +101,7 @@ extern uint16_t g_wdnfree; * before the timer interrupt is attached and before any watchdog * services are used. * - ************************************************************************/ + ****************************************************************************/ void weak_function wd_initialize(void); diff --git a/sched/wqueue/kwork_cancel.c b/sched/wqueue/kwork_cancel.c index 8aa133aaabd3d7d925d7cd079f59dccc01dc9061..659d9688b7010e662b32c24a5614ceda8f6d1727 100644 --- a/sched/wqueue/kwork_cancel.c +++ b/sched/wqueue/kwork_cancel.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wqueue/kwork_cancel.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -50,22 +51,6 @@ #ifdef CONFIG_SCHED_WORKQUEUE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -104,16 +89,18 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, * new work is typically added to the work queue from interrupt handlers. */ - flags = irqsave(); + flags = enter_critical_section(); if (work->worker != NULL) { /* A little test of the integrity of the work queue */ - DEBUGASSERT(work->dq.flink || (FAR dq_entry_t *)work == wqueue->q.tail); - DEBUGASSERT(work->dq.blink || (FAR dq_entry_t *)work == wqueue->q.head); + DEBUGASSERT(work->dq.flink != NULL || + (FAR dq_entry_t *)work == wqueue->q.tail); + DEBUGASSERT(work->dq.blink != NULL || + (FAR dq_entry_t *)work == wqueue->q.head); /* Remove the entry from the work queue and make sure that it is - * mark as available (i.e., the worker field is nullified). + * marked as available (i.e., the worker field is nullified). */ dq_rem((FAR dq_entry_t *)work, &wqueue->q); @@ -121,7 +108,7 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, ret = OK; } - irqrestore(flags); + leave_critical_section(flags); return ret; } diff --git a/sched/wqueue/kwork_hpthread.c b/sched/wqueue/kwork_hpthread.c index 81ac4c24ffe962629519d91d692056bdbb1186e2..ae3f518be56673ec37869221535b1bf857497a06 100644 --- a/sched/wqueue/kwork_hpthread.c +++ b/sched/wqueue/kwork_hpthread.c @@ -52,14 +52,6 @@ #ifdef CONFIG_SCHED_HPWORK -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -68,10 +60,6 @@ struct hp_wqueue_s g_hpwork; -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -106,7 +94,7 @@ static int work_hpthread(int argc, char *argv[]) { /* Loop forever */ - for (;;) + for (; ; ) { #ifndef CONFIG_SCHED_LPWORK /* First, perform garbage collection. This cleans-up memory @@ -120,7 +108,7 @@ static int work_hpthread(int argc, char *argv[]) * thread instead. */ - sched_garbagecollection(); + sched_garbage_collection(); #endif /* Then process queued work. work_process will not return until: (1) diff --git a/sched/wqueue/kwork_inherit.c b/sched/wqueue/kwork_inherit.c index c169d877caa982d20d0c49dfa71cf8e4ed56b383..b6d98c7b4063944c267ebec6e708f52af1f92519 100644 --- a/sched/wqueue/kwork_inherit.c +++ b/sched/wqueue/kwork_inherit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/work/work_inherit.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include +#include #include #include "sched/sched.h" @@ -49,10 +50,6 @@ #if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_LPWORK) && \ defined(CONFIG_PRIORITY_INHERITANCE) -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -333,7 +330,7 @@ void lpwork_boostpriority(uint8_t reqprio) /* Prevent context switches until we get the priorities right */ - flags = irqsave(); + flags = enter_critical_section(); sched_lock(); /* Adjust the priority of every worker thread */ @@ -344,7 +341,7 @@ void lpwork_boostpriority(uint8_t reqprio) } sched_unlock(); - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -379,7 +376,7 @@ void lpwork_restorepriority(uint8_t reqprio) /* Prevent context switches until we get the priorities right */ - flags = irqsave(); + flags = enter_critical_section(); sched_lock(); /* Adjust the priority of every worker thread */ @@ -390,7 +387,7 @@ void lpwork_restorepriority(uint8_t reqprio) } sched_unlock(); - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_LPWORK && CONFIG_PRIORITY_INHERITANCE */ diff --git a/sched/wqueue/kwork_lpthread.c b/sched/wqueue/kwork_lpthread.c index c355596c09248b7e62950c0cb13a4432959dc646..2a47fbca481cc40f7566a6131c3149bf1a53959c 100644 --- a/sched/wqueue/kwork_lpthread.c +++ b/sched/wqueue/kwork_lpthread.c @@ -55,14 +55,6 @@ #ifdef CONFIG_SCHED_LPWORK -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ @@ -71,10 +63,6 @@ struct lp_wqueue_s g_lpwork; -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -127,7 +115,7 @@ static int work_lpthread(int argc, char *argv[]) /* Loop forever */ - for (;;) + for (; ; ) { #if CONFIG_SCHED_LPNTHREADS > 0 /* Thread 0 is special. Only thread 0 performs period garbage collection */ @@ -147,16 +135,16 @@ static int work_lpthread(int argc, char *argv[]) #endif { /* Perform garbage collection. This cleans-up memory de-allocations - * that were queued because they could not be freed in that execution - * context (for example, if the memory was freed from an interrupt handler). - * NOTE: If the work thread is disabled, this clean-up is performed by - * the IDLE thread (at a very, very low priority). - * - * In the event of multiple low priority threads, on index == 0 will do - * the garbage collection. - */ - - sched_garbagecollection(); + * that were queued because they could not be freed in that execution + * context (for example, if the memory was freed from an interrupt handler). + * NOTE: If the work thread is disabled, this clean-up is performed by + * the IDLE thread (at a very, very low priority). + * + * In the event of multiple low priority threads, on index == 0 will do + * the garbage collection. + */ + + sched_garbage_collection(); /* Then process queued work. work_process will not return until: * (1) there is no further work in the work queue, and (2) the polling diff --git a/sched/wqueue/kwork_process.c b/sched/wqueue/kwork_process.c index 6333a6c2197992782470b53ec0ef56cf81d91001..f09735fd66529693a213d338a0eb8aead682dc33 100644 --- a/sched/wqueue/kwork_process.c +++ b/sched/wqueue/kwork_process.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/wqueue/work_process.c * - * Copyright (C) 2009-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,11 +45,10 @@ #include #include +#include #include #include -#include - #include "wqueue/wqueue.h" #ifdef CONFIG_SCHED_WORKQUEUE @@ -72,22 +71,6 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -109,24 +92,24 @@ * ****************************************************************************/ -void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx) +void work_process(FAR struct kwork_wqueue_s *wqueue, systime_t period, int wndx) { volatile FAR struct work_s *work; worker_t worker; irqstate_t flags; FAR void *arg; - uint32_t elapsed; - uint32_t remaining; - uint32_t stick; - uint32_t ctick; - uint32_t next; + systime_t elapsed; + systime_t remaining; + systime_t stick; + systime_t ctick; + systime_t next; /* Then process queued work. We need to keep interrupts disabled while * we process items in the work list. */ next = period; - flags = irqsave(); + flags = enter_critical_section(); /* Get the time that we started this polling cycle in clock ticks. */ @@ -178,7 +161,7 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx) * performed... we don't have any idea how long this will take! */ - irqrestore(flags); + leave_critical_section(flags); worker(arg); /* Now, unfortunately, since we re-enabled interrupts we don't @@ -186,7 +169,7 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx) * back at the head of the list. */ - flags = irqsave(); + flags = enter_critical_section(); work = (FAR struct work_s *)wqueue->q.head; } else @@ -239,20 +222,20 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx) * period will be non-zero and equal to wqueue->delay. */ - if (period == 0) - { - sigset_t set; + if (period == 0) + { + sigset_t set; - /* Wait indefinitely until signalled with SIGWORK */ + /* Wait indefinitely until signalled with SIGWORK */ - sigemptyset(&set); - sigaddset(&set, SIGWORK); + sigemptyset(&set); + sigaddset(&set, SIGWORK); - wqueue->worker[wndx].busy = false; - DEBUGVERIFY(sigwaitinfo(&set, NULL)); + wqueue->worker[wndx].busy = false; + DEBUGVERIFY(sigwaitinfo(&set, NULL)); wqueue->worker[wndx].busy = true; - } - else + } + else #endif { /* Get the delay (in clock ticks) since we started the sampling */ @@ -280,7 +263,7 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx) } } - irqrestore(flags); + leave_critical_section(flags); } #endif /* CONFIG_SCHED_WORKQUEUE */ diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 842fe656ff16b39336c4a63850ebad545f591c61..3c4acb2d00a0892e91036fcffd0d93e650c63653 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wqueue/kwork_queue.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -52,22 +53,6 @@ #ifdef CONFIG_SCHED_WORKQUEUE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -103,29 +88,29 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue, FAR struct work_s *work, worker_t worker, - FAR void *arg, uint32_t delay) + FAR void *arg, systime_t delay) { irqstate_t flags; - DEBUGASSERT(work != NULL); + DEBUGASSERT(work != NULL && worker != NULL); - /* First, initialize the work structure */ + /* First, initialize the work structure. This must be done with interrupts + * disabled. This permits this function to be called from with task logic + * or interrupt handlers. + */ - work->worker = worker; /* Work callback */ + flags = enter_critical_section(); + work->worker = worker; /* Work callback. non-NULL means queued */ work->arg = arg; /* Callback argument */ work->delay = delay; /* Delay until work performed */ - /* Now, time-tag that entry and put it in the work queue. This must be - * done with interrupts disabled. This permits this function to be called - * from with task logic or interrupt handlers. - */ + /* Now, time-tag that entry and put it in the work queue */ - flags = irqsave(); work->qtime = clock_systimer(); /* Time work queued */ dq_addlast((FAR dq_entry_t *)work, &wqueue->q); - irqrestore(flags); + leave_critical_section(flags); } /**************************************************************************** @@ -162,7 +147,7 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue, ****************************************************************************/ int work_queue(int qid, FAR struct work_s *work, worker_t worker, - FAR void *arg, uint32_t delay) + FAR void *arg, systime_t delay) { #ifdef CONFIG_SCHED_HPWORK if (qid == HPWORK) diff --git a/sched/wqueue/kwork_signal.c b/sched/wqueue/kwork_signal.c index d08263b5e996cda2a6d93dbc2cb672eff4517ab4..a4d94dbef9336c4a1ba63e5d484570ae58df6d51 100644 --- a/sched/wqueue/kwork_signal.c +++ b/sched/wqueue/kwork_signal.c @@ -48,29 +48,10 @@ #ifdef CONFIG_SCHED_WORKQUEUE -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ + /**************************************************************************** * Name: work_signal * diff --git a/sched/wqueue/wqueue.h b/sched/wqueue/wqueue.h index 14bf74b44c84d6ab7584b08f7ceac76a5798c33e..701af9b300d43bbce6e6f606fcbceb3b5fc18bcd 100644 --- a/sched/wqueue/wqueue.h +++ b/sched/wqueue/wqueue.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/wqueue/wqueue.h * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ #include #include +#include + #ifdef CONFIG_SCHED_WORKQUEUE /**************************************************************************** @@ -72,7 +74,7 @@ struct kworker_s struct kwork_wqueue_s { - uint32_t delay; /* Delay between polling cycles (ticks) */ + systime_t delay; /* Delay between polling cycles (ticks) */ struct dq_queue_s q; /* The queue of pending work */ struct kworker_s worker[1]; /* Describes a worker thread */ }; @@ -84,7 +86,7 @@ struct kwork_wqueue_s #ifdef CONFIG_SCHED_HPWORK struct hp_wqueue_s { - uint32_t delay; /* Delay between polling cycles (ticks) */ + systime_t delay; /* Delay between polling cycles (ticks) */ struct dq_queue_s q; /* The queue of pending work */ struct kworker_s worker[1]; /* Describes the single high priority worker */ }; @@ -97,7 +99,7 @@ struct hp_wqueue_s #ifdef CONFIG_SCHED_LPWORK struct lp_wqueue_s { - uint32_t delay; /* Delay between polling cycles (ticks) */ + systime_t delay; /* Delay between polling cycles (ticks) */ struct dq_queue_s q; /* The queue of pending work */ /* Describes each thread in the low priority queue's thread pool */ @@ -183,7 +185,7 @@ int work_lpstart(void); * ****************************************************************************/ -void work_process(FAR struct kwork_wqueue_s *wqueue, uint32_t period, int wndx); +void work_process(FAR struct kwork_wqueue_s *wqueue, systime_t period, int wndx); #endif /* CONFIG_SCHED_WORKQUEUE */ #endif /* __SCHED_WQUEUE_WQUEUE_H */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index c97d16ccf463e676b3c26a3f9cfee8bcaff6f6f6..a7d81215358f217cd8dbbbbd7219b6994bd78515 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -11,7 +11,7 @@ "clock_getres","time.h","","int","clockid_t","struct timespec*" "clock_gettime","time.h","","int","clockid_t","struct timespec*" "clock_settime","time.h","","int","clockid_t","const struct timespec*" -"clock_systimer","nuttx/clock.h","","uint32_t" +"clock_systimer","nuttx/clock.h","!defined(__HAVE_KERNEL_GLOBALS)","systime_t" "close","unistd.h","CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0","int","int" "closedir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","int","FAR DIR*" "connect","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","FAR const struct sockaddr*","socklen_t" @@ -23,10 +23,12 @@ "fs_fdopen","nuttx/fs/fs.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","FAR struct file_struct*","int","int","FAR struct tcb_s*" "fs_ioctl","nuttx/fs/fs.h","defined(CONFIG_LIBC_IOCTL_VARIADIC) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","int","int","unsigned long" "fsync","unistd.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","int" -"get_errno","errno.h","","int" +"get_errno","errno.h","!defined(__DIRECT_ERRNO_ACCESS)","int" +"get_errno_ptr","errno.h","defined(__DIRECT_ERRNO_ACCESS)","FAR int*" "getenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char*","FAR const char*" "getpid","unistd.h","","pid_t" "getsockopt","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int","FAR void*","FAR socklen_t*" +"insmod","nuttx/module.h","defined(CONFIG_MODULE)","int","FAR const char *","FAR const char *" "ioctl","sys/ioctl.h","!defined(CONFIG_LIBC_IOCTL_VARIADIC) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","int","int","unsigned long" "kill","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","pid_t","int" "listen","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int" @@ -70,6 +72,7 @@ "pthread_create","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_t*","FAR const pthread_attr_t*","pthread_startroutine_t","pthread_addr_t" "pthread_detach","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t" "pthread_exit","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","void","pthread_addr_t" +"pthread_getaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR cpu_set_t*" "pthread_getschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR int*","FAR struct sched_param*" "pthread_getspecific","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","FAR void*","pthread_key_t" "pthread_join","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR pthread_addr_t*" @@ -82,6 +85,7 @@ "pthread_mutex_trylock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t*" "pthread_mutex_unlock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t*" "pthread_once","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_once_t*","CODE void (*)(void)" +"pthread_setaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR const cpu_set_t*" "pthread_setcancelstate","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","int","FAR int*" "pthread_setschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","int","FAR const struct sched_param*" "pthread_setschedprio","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","int" @@ -96,6 +100,7 @@ "rename","stdio.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*","FAR const char*" "rewinddir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","void","FAR DIR*" "rmdir","unistd.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*" +"rmmod","nuttx/module.h","defined(CONFIG_MODULE)","int","FAR const char *" "sched_getparam","sched.h","","int","pid_t","struct sched_param*" "sched_getscheduler","sched.h","","int","pid_t" "sched_getstreams","nuttx/sched.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","FAR struct streamlist*" @@ -119,7 +124,7 @@ "send","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","ssize_t","int","FAR const void*","size_t","int" "sendfile","sys/sendfile.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_NET_SENDFILE)","ssize_t","int","int","FAR off_t*","size_t" "sendto","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","ssize_t","int","FAR const void*","size_t","int","FAR const struct sockaddr*","socklen_t" -"set_errno","errno.h","","void","int" +"set_errno","errno.h","!defined(__DIRECT_ERRNO_ACCESS)","void","int" "setenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","FAR const char*","FAR const char*","int" "sethostname","unistd.h","defined(CONFIG_LIBC_NETDB)","int","FAR const char*","size_t" "setsockopt","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int","FAR const void*","socklen_t" diff --git a/syscall/syscall_clock_systimer.c b/syscall/syscall_clock_systimer.c index 18801debbd34844655c01d4be1d624917771f532..3473cc673dd7307e24915756f4db3a997ec9842e 100644 --- a/syscall/syscall_clock_systimer.c +++ b/syscall/syscall_clock_systimer.c @@ -1,7 +1,7 @@ /**************************************************************************** * syscall/syscall_clock_systimer.c * - * Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ * ****************************************************************************/ -uint32_t syscall_clock_systimer(void) +systime_t syscall_clock_systimer(void) { return clock_systimer(); } diff --git a/syscall/syscall_funclookup.c b/syscall/syscall_funclookup.c index 8aa14a6926bb297071f682634a6069fdcc937896..8e624701038777508ce31ffe418a2f2a13da0205 100644 --- a/syscall/syscall_funclookup.c +++ b/syscall/syscall_funclookup.c @@ -99,7 +99,7 @@ * have an address that can be included in the g_funclookup[] table. */ -uint32_t syscall_clock_systimer(void); +systime_t syscall_clock_systimer(void); /**************************************************************************** * Pre-processor Definitions diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index db52304592d4d6310371c3d5d9720fd150dfb218..8fb2f507b04fffef6bd9d031039f2de83e81a9ab 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -1,7 +1,7 @@ /**************************************************************************** * syscall/syscall_lookup.h * - * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -106,6 +106,15 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) # endif #endif +/* The following can only be defined if we are configured to load + * OS modules from a file system. + */ + +#ifdef CONFIG_MODULE + SYSCALL_LOOKUP(insmod, 2, STUB_insmod) + SYSCALL_LOOKUP(rmmod, 1, STUB_rmmod) +#endif + /* The following can only be defined if we are configured to execute * programs from a file system. */ @@ -269,6 +278,10 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) SYSCALL_LOOKUP(pthread_setschedprio, 2, STUB_pthread_setschedprio) SYSCALL_LOOKUP(pthread_setspecific, 2, STUB_pthread_setspecific) SYSCALL_LOOKUP(pthread_yield, 0, STUB_pthread_yield) +# ifdef CONFIG_SMP + SYSCALL_LOOKUP(pthread_setaffinity, 3, STUB_pthread_setaffinity) + SYSCALL_LOOKUP(pthread_getaffinity, 3, STUB_pthread_getaffinity) +# endif # ifndef CONFIG_DISABLE_SIGNALS SYSCALL_LOOKUP(pthread_cond_timedwait, 3, STUB_pthread_cond_timedwait) SYSCALL_LOOKUP(pthread_kill, 2, STUB_pthread_kill) diff --git a/syscall/syscall_nparms.c b/syscall/syscall_nparms.c index 292421643b563484bb5f2c03bc092794bc8954d4..164ab3e3fdb96812d437235e061a7aca5c61b424 100644 --- a/syscall/syscall_nparms.c +++ b/syscall/syscall_nparms.c @@ -72,4 +72,4 @@ const uint8_t g_funcnparms[SYS_nsyscalls] = * Public Functions ****************************************************************************/ - #endif /* CONFIG_LIB_SYSCALL */ +#endif /* CONFIG_LIB_SYSCALL */ diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 9991192feb2034f4692b161bf200ba8d921260a4..63af75eb4095a89bf2a4750b5320dd9ca9bc2813 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -1,7 +1,7 @@ /**************************************************************************** * syscall/syscall_stublookup.c * - * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -107,6 +107,15 @@ uintptr_t STUB_wait(int nbr, uintptr_t parm1); uintptr_t STUB_waitid(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4); +/* The following can only be defined if we are configured to load + * OS modules from a file system. + */ + +#ifdef CONFIG_MODULE +uintptr_t STUB_insmod(int nbr, uintptr_t parm1, uintptr_t parm2); +uintptr_t STUB_rmmod(int nbr, uintptr_t parm1); +#endif + /* The following can only be defined if we are configured to execute * programs from a file system. */ @@ -281,6 +290,11 @@ uintptr_t STUB_pthread_setspecific(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_pthread_yield(int nbr); +uintptr_t STUB_pthread_setaffinity(int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3); +uintptr_t STUB_pthread_getaffinity(int nbr, uintptr_t parm1, + uintptr_t parm2, uintptr_t parm3); + uintptr_t STUB_pthread_cond_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3); uintptr_t STUB_pthread_kill(int nbr, uintptr_t parm1, uintptr_t parm2); diff --git a/tools/.gitignore b/tools/.gitignore index 6a55708068244fdcfb7f8cb37dbb80feb7311528..d10c12aa3c265a20d14078b00015b3491aa16ce4 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -4,9 +4,11 @@ /configure /mkconfig /mkdeps +/cnvwindeps /mksymtab /mksyscall /mkversion +/nxstyle /*.exe /*.dSYM /.k2h-body.dat diff --git a/tools/Makefile.host b/tools/Makefile.host index 1580ec8ed56d1cf4b08d7c4c8b0f4aa41f0edada..c408a0a4e74bf5346762f18da16822a3279e345e 100644 --- a/tools/Makefile.host +++ b/tools/Makefile.host @@ -1,7 +1,7 @@ ############################################################################ # Makefile.host # -# Copyright (C) 2007, 2008, 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2007, 2008, 2011-2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -40,6 +40,8 @@ include ${TOPDIR}/tools/Config.mk # Define HOSTCC on the make command line if it differs from these defaults # Define HOSTCFLAGS with -g on the make command line to build debug versions +HOSTOS = ${shell uname -o 2>/dev/null || echo "Other"} + ifeq ($(CONFIG_WINDOWS_NATIVE),y) # In the Windows native environment, the MinGW GCC compiler is assumed @@ -49,24 +51,32 @@ HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DCONFIG_WINDOWS_NATIVE else -# GCC is assumed in the POSIX environment. +# GCC is assumed in the POSIX environment (Linux or Cygwin). # strtok_r is used in some tools, but does not seem to be available in # the MinGW environment. HOSTCC ?= gcc -HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DHAVE_STRTOK_C +HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. +HOSTCFLAGS += -DHAVE_STRTOK_C=1 +ifeq ($(HOSTOS),Cygwin) +HOSTCFLAGS += -DHOST_CYGWIN=1 +HOSTEXEEXT ?= .exe +endif endif # Targets all: b16$(HOSTEXEEXT) bdf-converter$(HOSTEXEEXT) cmpconfig$(HOSTEXEEXT) \ - configure$(HOSTEXEEXT) mkconfig$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) mksymtab$(HOSTEXEEXT) \ - mksyscall$(HOSTEXEEXT) mkversion$(HOSTEXEEXT) -default: mkconfig$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) + configure$(HOSTEXEEXT) mkconfig$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) \ + mksymtab$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkversion$(HOSTEXEEXT) \ + cnvwindeps$(HOSTEXEEXT) nxstyle$(HOSTEXEEXT) +default: mkconfig$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) \ + cnvwindeps$(HOSTEXEEXT) ifdef HOSTEXEEXT -.PHONY: b16 bdf-converter cmpconfig clean configure mkconfig mkdeps mksymtab mksyscall mkversion +.PHONY: b16 bdf-converter cmpconfig clean configure mkconfig mkdeps \ + cnvwindeps mksymtab mksyscall mkversion else .PHONY: clean endif @@ -152,6 +162,25 @@ ifdef HOSTEXEEXT bdf-converter: bdf-converter$(HOSTEXEEXT) endif +# nxstyle - Check a file for compliance to NuttX coding style + +nxstyle$(HOSTEXEEXT): nxstyle.c + $(Q) $(HOSTCC) $(HOSTCFLAGS) -o nxstyle$(HOSTEXEEXT) nxstyle.c + +ifdef HOSTEXEEXT +nxstyle: nxstyle$(HOSTEXEEXT) +endif + +# cnvwindeps - Convert dependences generated by a Windows native toolchain +# for use in a Cygwin/POSIX build environment + +cnvwindeps$(HOSTEXEEXT): cnvwindeps.c + $(Q) $(HOSTCC) $(HOSTCFLAGS) -o cnvwindeps$(HOSTEXEEXT) cnvwindeps.c + +ifdef HOSTEXEEXT +cnvwindeps: cnvwindeps$(HOSTEXEEXT) +endif + # Create dependencies for a list of files mkdeps$(HOSTEXEEXT): mkdeps.c csvparser.c @@ -164,6 +193,8 @@ endif clean: $(call DELFILE, mkdeps) $(call DELFILE, mkdeps.exe) + $(call DELFILE, cnvwindeps) + $(call DELFILE, cnvwindeps.exe) $(call DELFILE, mkconfig) $(call DELFILE, mkconfig.exe) $(call DELFILE, Make.dep) diff --git a/tools/README.txt b/tools/README.txt index 604a4c7055d0a6d22f11f9087f54082a0cd67d29..4f57ca0b34d38f40c2af92c2dc45d9e1356c8858 100644 --- a/tools/README.txt +++ b/tools/README.txt @@ -210,6 +210,30 @@ mkctags.sh A script for creating ctags from Ken Pettit. See http://en.wikipedia.org/wiki/Ctags and http://ctags.sourceforge.net/ +nxstyle.c +--------- + + I am embarassed that this is here. This program is a complete hack + but, unfortunately, it has become so useful to me that I need to keep + it here. + + A little background: I have tinkered with pretty printers for some + time and have not been happy with the results. An alternative that + occurred to me would be just a standard checker that examines a C + file that gives warnings for violations of the coding standard. + + This turns out to be more difficult that you might think. A pretty + printer understands C syntax: They break the file up into its C + components then reassembles the output in the format. But parsing the + C loses the original file layout and so it not useful in this case. + + This program instead, uses a collection of heuristics (i.e., hacks and + bandaids) to examine the C file for obvious violations of the coding + standard. This program is completely ignorant of C syntax; it simply + performs crude pattern matching to check the file. + + Usage: nxstyle + pic32mx ------- @@ -369,18 +393,20 @@ mkromfsimg.sh image. It accepts an rcS script "template" and generates and image that may be mounted under /etc in the NuttX pseudo file system. -mkdeps.sh -mkdeps.bat + TIP: Edit the resulting header file and mark the generated data values + as 'const' so that they will be stored in FLASH. + mkdeps.c +cnvwindeps.c +mkwindeps.sh mknulldeps.sh ------------- NuttX uses the GCC compilers capabilities to create Makefile dependencies. - The bash script mkdeps.sh is used to run GCC in order to create the - dependencies. If a NuttX configuration uses the GCC toolchain, its Make.defs - file (see configs/README.txt) will include a line like: + The program mkdeps is used to run GCC in order to create the dependencies. + If a NuttX configuration uses the GCC toolchain, its Make.defs file (see + configs/README.txt) will include a line like: - MKDEP = $(TOPDIR)/tools/mkdeps.sh, or MKDEP = $(TOPDIR)/tools/mkdeps[.exe] (See NOTE below) If the NuttX configuration does not use a GCC compatible toolchain, then @@ -390,22 +416,12 @@ mknulldeps.sh The mknulldeps.sh is a stub script that does essentially nothing. - NOTE: The mk*deps.* files are undergoing change. mkdeps.sh is a bash - script that produces dependencies well for POSIX style hosts (e..g., - Linux and Cygwin). It does not work well for mixed environments with - a Windows toolchain running in a POSIX style environment (hence, the - mknulldeps.sh script). And, of course, cannot be used in a Windows - nativ environment. - - [mkdeps.sh does have an option, --winpath, that purports to convert - the dependencies generated by a Windows toolchain to POSIX format. - However, that is not being used and mostly likely does not cover - all of the conversion cases.] - - mkdeps.bat is a simple port of the bash script to run in a Windows - command shell. However, it does not work well either because some - of the common CFLAGS use characters like '=' which are transformed - by the CMD.exe shell. + mkwindeps.sh is a version that creates dependencies using the Windows + native toolchain. That generates Windows native paths in the dependency + file. But the mkwindeps.sh uses cnvwindeps.c to convert the Windows + paths to POSIX paths. This adds some time to the Windows dependency + generation but is generally th best option available for that mixed + environment of Cygwin with a native Windows GCC toolchain. mkdeps.c generates mkdeps (on Linux) or mkdeps.exe (on Windows). However, this verison is still under-development. It works well in @@ -413,7 +429,7 @@ mknulldeps.sh does not work well in mixed POSIX environment with a Windows toolchain. In that case, there are still issues with the conversion of things like 'c:\Program Files' to 'c:program files' by bash. Those issues may, - eventually be solvable but for now continue to use mknulldeps.sh in + eventually be solvable but for now continue to use mkwindeps.sh in that mixed environment. define.sh @@ -528,6 +544,24 @@ indent.sh to my coding NuttX coding style. It doesn't do a really good job, however (see the comments at the top of the indent.sh file). + USAGE: + ./indent.sh [-d] -o + ./indent.sh [-d] + ./indent.sh [-d] -h + + Where: + - + A single, unformatted input file + - + A list of unformatted input files that will be reformatted in place. + -o + Write the single, reformatted to . + will not be modified. + -d + Enable script debug + -h + Show this help message and exit + refresh.sh ---------- @@ -541,7 +575,26 @@ refresh.sh new dependencies are added. So an old configuration file may not be usable anymore until it is refreshed. - The steps to refresh the file are: + Help is also available: + + $ tools/refresh.sh --help + tools/refresh.sh is a tool for refreshing board configurations + + USAGE: tools/refresh.sh [--debug|--help] / + + Where: + --debug + Enable script debug + --silent + Update board configuration without interaction + --help + Show this help message and exit + + The board directory under nuttx/configs + + The board configuration directory under nuttx/configs/ + + The steps to refresh the file taken by refresh.sh are: 1. Make tools/cmpconfig if it is not already built. 2. Copy the the defconfig file to the top-level NuttX @@ -550,6 +603,10 @@ refresh.sh 3. Execute 'make oldconfig' to update the configuration. 'make oldconfig' will prompt you for each change in the configuration that requires that you make some decision. + With the --silent option, the script will use 'make + oldefconfig' instead and you won't have to answer any + questions; the refresh will simply accept the default + value for any new configuration settings. 4. Then it runs tools/cmpconfig to show the real differences between the configuration files. Configuration files are complex and things can move around so a simple 'diff' between @@ -563,9 +620,10 @@ refresh.sh installed. 5. Finally, the refreshed defconfig file is copied back in place where it can be committed with the next set of - difference to the command line. refresh.sh will prompt - you first to avoid overwriting the defconfig file with - changes that you do not want. + difference to the command line. If you select the --silent + option, this file copy will occur autiomatically. Otherwise, + refresh.sh will prompt you first to avoid overwriting the + defconfig file with changes that you may not want. testbuild.sh ------------ diff --git a/tools/cfgdefine.c b/tools/cfgdefine.c index de91882a56c80f83ab3f0a9c5e5ad754aa61ff3a..bb9a81eee2bd821ff6c658f7796e12eda5bd79b1 100644 --- a/tools/cfgdefine.c +++ b/tools/cfgdefine.c @@ -98,7 +98,7 @@ static const char *dequote_list[] = * Private Functions ****************************************************************************/ - /* Skip over any spaces */ +/* Skip over any spaces */ static char *skip_space(char *ptr) { diff --git a/tools/cfgparser.c b/tools/cfgparser.c index 8ac52a58902f86156c44cb00f0d5fa8eca4ab3a6..959cf9e5ebf55cfa468952caf7ce0661e9660023 100644 --- a/tools/cfgparser.c +++ b/tools/cfgparser.c @@ -61,7 +61,7 @@ char line[LINESIZE+1]; * Private Functions ****************************************************************************/ - /* Skip over any spaces */ +/* Skip over any spaces */ static char *skip_space(char *ptr) { diff --git a/tools/cnvwindeps.c b/tools/cnvwindeps.c new file mode 100644 index 0000000000000000000000000000000000000000..7f71bda584e297dd8050f848c9b3fa968ddbeb8b --- /dev/null +++ b/tools/cnvwindeps.c @@ -0,0 +1,304 @@ +/**************************************************************************** + * tools/cnvwindeps.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#ifdef HOST_CYGWIN + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MAX_LINE 1024 +#define MAX_PATH 1024 + +/**************************************************************************** + * Global Data + ****************************************************************************/ + +static unsigned long g_lineno; +static char g_line[MAX_LINE]; +static char g_dequoted[MAX_PATH]; +static char g_posix[MAX_PATH]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static char *skip_spaces(char *ptr) +{ + while (*ptr && isspace((int)*ptr)) ptr++; + return ptr; +} + +static char *find_spaces(char *ptr) +{ + bool quoted = false; + + while (*ptr) + { + if (ptr[0] == '\\' && isspace((int)ptr[1])) + { + quoted = true; + ptr++; + } + else if (!quoted && isspace((int)*ptr)) + { + break; + } + else + { + quoted = false; + ptr++; + } + } + + return ptr; +} + +static bool scour_path(const char *path) +{ + /* KLUDGE: GNU make cannot handle dependencies with spaces in them. + * There may be addition characters that cause problems too. + */ + + return strchr(path, ' ') != NULL; +} + +static bool dequote_path(const char *winpath) +{ + char *dest = g_dequoted; + const char *src = winpath; + int len = 0; + bool quoted = false; + + while (*src && len < MAX_PATH) + { + if (src[0] != '\\' || (src[1] != ' ' && src[1] != '(' && src[1] != ')')) + { + *dest++ = *src; + len++; + } + else + { + quoted = true; + } + + src++; + } + + if (*src || len >= MAX_PATH) + { + fprintf(stderr, "%lu: Line truncated\n", g_lineno); + exit(EXIT_FAILURE); + } + + *dest = '\0'; + return quoted; +} + +static bool convert_path(const char *winpath) +{ + ssize_t size; + ssize_t ret; + bool quoted; + + quoted = dequote_path(winpath); + + size = cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, g_dequoted, NULL, 0); + if (size > MAX_PATH) + { + fprintf(stderr, "%lu: POSIX path too long: %lu\n", + g_lineno, (unsigned long)size); + exit(EXIT_FAILURE); + } + + ret = cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, g_dequoted, g_posix, MAX_PATH); + if (ret < 0) + { + fprintf(stderr, "%lu: cygwin_conv_path '%s' failed: %s\n", + g_lineno, g_dequoted, strerror(errno)); + exit(EXIT_FAILURE); + } + + return quoted; +} + +static void show_usage(const char *progname) +{ + fprintf(stderr, "USAGE: %s \n", progname); + exit(EXIT_FAILURE); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ + char *path; + char *next; + FILE *stream; + bool begin; + bool quoted; + bool scouring; + + if (argc != 2) + { + fprintf(stderr, "Unexpected number of arguments\n"); + show_usage(argv[0]); + } + + stream = fopen(argv[1], "r"); + if (!stream) + { + fprintf(stderr, "open %s failed: %s\n", argv[1], strerror(errno)); + exit(EXIT_FAILURE); + } + + begin = true; + scouring = false; + g_lineno = 0; + + while (fgets(g_line, MAX_LINE, stream) != NULL) + { + g_lineno++; + next = g_line; + + for (; ; ) + { + if (begin) + { + path = skip_spaces(next); + if (*path == '#') + { + /* The reset of the line is comment */ + + puts(path); + break; + } + + next = strchr(path, ':'); + if (!next) + { + fprintf(stderr, "%lu: Expected colon\n", g_lineno); + exit(EXIT_FAILURE); + } + + if (*next != '\0') + { + *next++ = '\0'; + } + + scouring = scour_path(path); + if (!scouring) + { + quoted = convert_path(path); + if (quoted) + { + printf("\"%s\":", g_posix); + } + else + { + printf("%s:", g_posix); + } + } + + begin = false; + } + else + { + path = skip_spaces(next); + next = find_spaces(path); + + if (path[0] == '\\') + { + break; + } + else if (strcmp(path, "") == 0) + { + printf("\n\n"); + begin = true; + scouring = false; + break; + } + else + { + if (*next != '\0') + { + *next++ = '\0'; + } + + if (!scouring && !scour_path(path)) + { + quoted = convert_path(path); + if (quoted) + { + printf(" \\\n\t\"%s\"", g_posix); + } + else + { + printf(" \\\n\t%s", g_posix); + } + } + } + } + } + } + + fclose(stream); + return 0; +} + +#else /* HOST_CYGWIN */ + +int main(int argc, char **argv, char **envp) +{ + fprintf(stderr, "ERROR: This tool is only available under Cygwin\n"); + return EXIT_FAILURE; +} + +#endif /* HOST_CYGWIN */ diff --git a/tools/configure.bat b/tools/configure.bat old mode 100644 new mode 100755 diff --git a/tools/configure.sh b/tools/configure.sh index 2de790506e3af33084cdb70d28e09fdb75bbd783..3ee734d6e9f6bc099ea8066692288b770321071a 100755 --- a/tools/configure.sh +++ b/tools/configure.sh @@ -144,7 +144,7 @@ winnative=`grep CONFIG_WINDOWS_NATIVE= "${src_config}" | cut -d'=' -f2` defappdir=y if [ -z "${appdir}" ]; then quoted=`grep "^CONFIG_APPS_DIR=" "${src_config}" | cut -d'=' -f2` - if [ ! -z "${appdir}" ]; then + if [ ! -z "${quoted}" ]; then appdir=`echo ${quoted} | sed -e "s/\"//g"` defappdir=n fi @@ -165,7 +165,6 @@ if [ -z "${appdir}" ]; then if [ -d "${TOPDIR}/../apps" ]; then appdir="../apps" - else # Check for a versioned apps/ directory diff --git a/tools/define.bat b/tools/define.bat old mode 100644 new mode 100755 diff --git a/tools/indent.sh b/tools/indent.sh index 866430e7e2280cd5f2e88777835ca9dc94c740d6..10bffdd60f1af0a38072a8734173fb610ced7d7b 100755 --- a/tools/indent.sh +++ b/tools/indent.sh @@ -2,7 +2,7 @@ ############################################################################ # tools/indent.sh # -# Copyright (C) 2008, 2010 Gregory Nutt. All rights reserved. +# Copyright (C) 2008, 2010, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -48,39 +48,86 @@ options="-nbad -bap -bbb -nbbo -nbc -bl -bl2 -bls -nbs -cbi2 -ncdw -nce -ci2 -cli0 -cp40 -ncs -nbfda -nbfde -di1 -nfc1 -fca -i2 -l80 -lp -ppi2 -lps -npcs -pmt -nprs -npsl -saf -sai -sbi2 -saw -sc -sob -nss -nut" -usage="USAGE: $0 " +advice="Try '$0 -h' for more information" -# Inputs +# Parse inputs -infile=$1 -outfile=$2 +unset filelist +unset outfile +files=none +mode=inplace -# Verify inputs +while [ ! -z "${1}" ]; do + case ${1} in + -d ) + set -x + ;; + -o ) + shift + outfile=${1} + mode=copy + ;; + -h ) + echo "$0 is a tool for generation of proper version files for the NuttX build" + echo "" + echo "USAGE:" + echo " $0 [-d] -o " + echo " $0 [-d] " + echo " $0 [-d] -h" + echo "" + echo "Where:" + echo " -" + echo " A single, unformatted input file" + echo " -" + echo " A list of unformatted input files that will be reformatted in place." + echo " -o " + echo " Write the single, reformatted to . " + echo " will not be modified." + echo " -d" + echo " Enable script debug" + echo " -h" + echo " Show this help message and exit" + exit 0 + ;; + * ) + if [ ! -r ${1} ]; then + echo "Readable ${1} does not exist" + echo ${advice} + exit 1 + fi + if [ -z "${filelist}" ]; then + filelist="${1}" + files=single + else + filelist="${filelist} ${1}" + files=multiple + fi + ;; + esac + shift +done -if [ -z "$infile" ]; then - echo "Missing " - echo $usage - exit 1 -fi - -if [ ! -r $infile ]; then - echo "Readable $infile does not exist" - exit 1 -fi - -if [ -z "$outfile" ]; then - echo "Missing " - echo $usage - exit 1 -fi +# Verify that at least one input file was provided -if [ -f $outfile ]; then - echo "Removing old $outfile" - rm $outfile || { echo "Failed to remove $outfile" ; exit 1 ; } +if [ "X${files}" == "Xnone" ]; then + echo "ERROR: Neither nor provided" + echo ${advice} + exit 1 fi # Perform the indentation -indent $options $infile -o $outfile - - +if [ "X${mode}" == "Xcopy" ]; then + if [ "X${files}" == "Xmultiple" ]; then + echo "ERROR: Only a single can be used with the -o option" + echo ${advice} + exit 1 + fi + if [ -f $outfile ]; then + echo "Removing old $outfile" + rm $outfile || { echo "Failed to remove $outfile" ; exit 1 ; } + fi + indent $options $filelist -o $outfile +else + indent $options $filelist +fi diff --git a/tools/mkconfig.c b/tools/mkconfig.c index 93dc7e314919f69356e3eb12882c4296c7c37a81..70160aa0bb5345e6e36808ab273713c646cc8d45 100644 --- a/tools/mkconfig.c +++ b/tools/mkconfig.c @@ -53,7 +53,7 @@ * Private Functions ****************************************************************************/ - static inline char *getfilepath(const char *name) +static inline char *getfilepath(const char *name) { snprintf(line, PATH_MAX, "%s/" DEFCONFIG, name); line[PATH_MAX] = '\0'; @@ -209,6 +209,10 @@ int main(int argc, char **argv, char **envp) printf("/* If the maximum message size is zero, then we assume that message queues\n"); printf(" * support should be disabled\n"); printf(" */\n\n"); + printf("#if !defined(CONFIG_MQ_MAXMSGSIZE) || defined(CONFIG_DISABLE_MQUEUE)\n"); + printf("# undef CONFIG_MQ_MAXMSGSIZE\n"); + printf("# define CONFIG_MQ_MAXMSGSIZE 0\n"); + printf("#endif\n\n"); printf("#if CONFIG_MQ_MAXMSGSIZE <= 0 && !defined(CONFIG_DISABLE_MQUEUE)\n"); printf("# define CONFIG_DISABLE_MQUEUE 1\n"); printf("#endif\n\n"); diff --git a/tools/mkctags.sh b/tools/mkctags.sh old mode 100644 new mode 100755 diff --git a/tools/mkdeps.bat b/tools/mkdeps.bat deleted file mode 100644 index 64b4429d10172e833da08181fc1ec99da0d1360f..0000000000000000000000000000000000000000 --- a/tools/mkdeps.bat +++ /dev/null @@ -1,200 +0,0 @@ -@echo off - -rem tools/mkdeps.sh -rem -rem Copyright (C) 2012 Gregory Nutt. All rights reserved. -rem Author: Gregory Nutt -rem -rem Redistribution and use in source and binary forms, with or without -rem modification, are permitted provided that the following conditions -rem are met: -rem -rem 1. Redistributions of source code must retain the above copyright -rem notice, this list of conditions and the following disclaimer. -rem 2. Redistributions in binary form must reproduce the above copyright -rem notice, this list of conditions and the following disclaimer in -rem the documentation and/or other materials provided with the -rem distribution. -rem 3. Neither the name NuttX nor the names of its contributors may be -rem used to endorse or promote products derived from this software -rem without specific prior written permission. -rem -rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -rem FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -rem COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -rem INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -rem BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -rem OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -rem AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -rem LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -rem ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -rem POSSIBILITY OF SUCH DAMAGE. - -rem Accumulate CFLAGS up to "--" - -set cc= -set cflags= -set altpath= -set files= -set args= -set objpath= -set suffix=.o -set debug=n - -:Loop -if "%1"=="" goto Continue - -if "%1"=="--" ( - set cc=%cflags% - set cflags=%args% - set args= - goto NextParm -) - -if "%1"=="--dep-path" ( - if "%args%"=="" ( - set altpath=%altpath% %2 - ) else ( - set args=%args% %2 - ) - shift - goto NextParm -) - -if "%1"=="--obj-path" ( - set objpath=%2 - shift - goto NextParm -) - -if "%1"=="--obj-suffix" ( - set suffix=%2 - shift - goto NextParm -) - -if "%1"=="--dep-debug" ( -rem @echo on - set debug=y - goto NextParm -) - -if "%1"=="--help" goto Usage - -if "%args%"=="" ( - set args=%1 -) else ( - set args=%args% %1 -) - -:NextParm -shift -goto Loop -:Continue - -set files=%args% - -if "%debug%"=="y" ( - echo cc=%cc% - echo cflags=%cflags% - echo files=%files% - echo altpath=%altpath% -) - -rem Now check if we have everything - -if "%cc%"=="" ( - echo ERROR: No compiler specified - goto Usage -) - -if "%files%"=="" ( - rem Don't report an error -- this happens normally in some configurations - echo # No files specified for dependency generataion - goto End -) - -rem Then get the dependencies for each file - -if "%altpath%"=="" goto NoPaths -for %%G in (%files%) do ( - set fullpath= - set file=%%G - call :Checkpaths - if "%debug%"=="y" echo %file%: fullpath=%fullpath% - if "%fullpath%"=="" goto :NoFile - - mtarg="" - if "%objpath%"=="" ( - set objname=%~n1 - set mtarg="-MT %objpath%\%objname%%suffix% - ) - - if "%debug%"=="y" echo CMD: %cc% -M %cflags% %fullpath% - %cc% -M %mtarg% %cflags% %fullpath% || goto DepFail -) -goto :End - -:NoPaths -for %%G in (%files%) do ( - set fullpath= - set file=%%G - call :CheckFile %%G -) -goto :End - -:CheckFile -if "%debug%"=="y" echo Checkfile: Checking %file% -if not exist %file% goto :NoFile -set fullpath=%file% - if "%debug%"=="y" echo CMD: %cc% -M %cflags% %fullpath% -%cc% -M %cflags% %fullpath% || goto DepFail -goto :EOF - -:CheckPaths -for %%H in (%altpath%) do ( - set tmppath=%%H\%file% - if "%debug%"=="y" echo Checkfile: Checking %tmppath% - if exist %tmppath% ( - set fullpath=%tmppath% - goto :EOF - ) -) -goto :EOF - -:NoFile -echo ERROR: No readable file at %file% -goto Usage - -:DepFail -echo ERROR: Failed to created dependencies for %file% - -:Usage -echo Usage: mkdeps [OPTIONS] CC -- CFLAGS -- file [file [file...]] -echo Where: -echo CC -echo A variable number of arguments that define how to execute the compiler -echo CFLAGS -echo The compiler compilation flags -echo file -echo One or more C files whose dependencies will be checked. Each file is expected -echo to reside in the current directory unless --dep-path is provided on the command line -echo And [OPTIONS] include: -echo --dep-debug -echo Enable script debug -echo --dep-path ^ -echo Do not look in the current directory for the file. Instead, look in to see -echo if the file resides there. --dep-path may be used multiple times to specify -echo multiple alternative location -echo --obj-path ^ -echo The final objects will not reside in this path but, rather, at the path provided by -echo ^. if provided multiple time, only the last --obj-path will be used. -echo --obj-suffix ^ -echo If and object path is provided, then the extension will be assumed to be .o. This -echo default suffix can be overrided with this command line option. -echo --help -echo Shows this message and exits - -:End diff --git a/tools/mkdeps.c b/tools/mkdeps.c index d6819ab25db1214026f3da5e049258514f871058..7c42c568e3731866b4a389ae5be69dc3c317c2f5 100644 --- a/tools/mkdeps.c +++ b/tools/mkdeps.c @@ -48,11 +48,17 @@ #include #include +#ifdef HOST_CYGWIN +# include +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define MAX_BUFFER (4096) +#define MAX_EXPAND (2048) +#define MAX_PATH (512) /* NAME_MAX is typically defined in limits.h */ @@ -101,21 +107,23 @@ static char *g_objpath = NULL; static char *g_suffix = ".o"; static int g_debug = 0; static bool g_winnative = false; -#ifdef HAVE_WINPATH +#ifdef HOST_CYGWIN static bool g_winpath = false; -static char *g_topdir = NULL; -#define DELIM "\\" -#else -#define DELIM "/" #endif static char g_command[MAX_BUFFER]; +static char g_path[MAX_PATH]; +#ifdef HOST_CYGWIN +static char g_expand[MAX_EXPAND]; +static char g_dequoted[MAX_PATH]; +static char g_posixpath[MAX_PATH]; +#endif /**************************************************************************** * Private Functions ****************************************************************************/ - /* MinGW does not seem to provide strtok_r */ +/* MinGW does not seem to provide strtok_r */ #ifndef HAVE_STRTOK_R static char *MY_strtok_r(char *str, const char *delim, char **saveptr) @@ -180,6 +188,7 @@ static char *MY_strtok_r(char *str, const char *delim, char **saveptr) { *saveptr = pend; } + return pbegin; } @@ -257,12 +266,11 @@ static void show_usage(const char *progname, const char *msg, int exitcode) fprintf(stderr, " --winnative\n"); fprintf(stderr, " By default, a POSIX-style environment is assumed (e.g., Linux, Cygwin, etc.) This option is\n"); fprintf(stderr, " inform the tool that is working in a pure Windows native environment.\n"); -#ifdef HAVE_WINPATH - fprintf(stderr, " --winpaths \n"); +#ifdef HOST_CYGWIN + fprintf(stderr, " --winpaths\n"); fprintf(stderr, " This option is useful when using a Windows native toolchain in a POSIX environment (such\n"); fprintf(stderr, " such as Cygwin). In this case, will CC generates dependency lists using Windows paths\n"); - fprintf(stderr, " (e.g., C:\\blablah\\blabla). This switch instructs the script to use 'cygpath' to convert\n"); - fprintf(stderr, " the Windows paths to Cygwin POSIXE paths.\n"); + fprintf(stderr, " (e.g., C:\\blablah\\blabla).\n"); #endif fprintf(stderr, " --help\n"); fprintf(stderr, " Shows this message and exits\n"); @@ -329,22 +337,10 @@ static void parse_args(int argc, char **argv) { g_winnative = true; } -#ifdef HAVE_WINPATH +#ifdef HOST_CYGWIN else if (strcmp(argv[argidx], "--winpath") == 0) { g_winpath = true; - if (g_topdir) - { - free(g_topdir); - } - - argidx++; - if (argidx >= argc) - { - show_usage(argv[0], "ERROR: Missing argument to --winpath", EXIT_FAILURE); - } - - g_topdir = strdup(argv[argidx]); } #endif else if (strcmp(argv[argidx], "--help") == 0) @@ -385,12 +381,8 @@ static void parse_args(int argc, char **argv) fprintf(stderr, " OBJDIR : (None)\n"); } -#ifdef HAVE_WINPATH +#ifdef HOST_CYGWIN fprintf(stderr, " Windows Paths : [%s]\n", g_winpath ? "TRUE" : "FALSE"); - if (g_winpath) - { - fprintf(stderr, " TOPDIR : [%s]\n", g_topdir); - } #endif fprintf(stderr, " Windows Native : [%s]\n", g_winnative ? "TRUE" : "FALSE"); } @@ -410,15 +402,180 @@ static void parse_args(int argc, char **argv) exit(EXIT_SUCCESS); } -#ifdef HAVE_WINPATH +#ifdef HOST_CYGWIN if (g_winnative && g_winpath) { - show_usage(argv[0], "ERROR: Both --winnative and --winpapth makes no sense", EXIT_FAILURE); + show_usage(argv[0], "ERROR: Both --winnative and --winpath makes no sense", EXIT_FAILURE); + } +#endif +} + +static const char *do_expand(const char *argument) +{ +#ifdef HOST_CYGWIN + if (g_winpath) + { + const char *src; + char *dest; + int len; + + src = argument; + dest = g_expand; + len = 0; + + while (*src && len < MAX_EXPAND) + { + if (*src == '\\') + { + /* Copy backslash */ + + *dest++ = *src++; + if (++len >= MAX_EXPAND) + { + break; + } + + /* Already expanded? */ + + if (*src == '\\') + { + /* Yes... just copy all consecutive backslashes */ + + do + { + *dest++ = *src++; + if (++len >= MAX_EXPAND) + { + break; + } + } + while (*src == '\\'); + } + else + { + /* No.. expeand */ + + *dest++ = '\\'; + if (++len >= MAX_EXPAND) + { + break; + } + } + } + else + { + *dest++ = *src++; + len++; + } + } + + if (*src) + { + fprintf(stderr, "ERROR: Truncated during expansion string is too long [%lu/%u]\n", + (unsigned long)strlen(argument), MAX_EXPAND); + exit(EXIT_FAILURE); + } + + *dest = '\0'; + return g_expand; } + else #endif + { + return argument; + } } -static void do_dependency(const char *file, char separator) +#ifdef HOST_CYGWIN +static bool dequote_path(const char *winpath) +{ + char *dest = g_dequoted; + const char *src = winpath; + int len = 0; + bool quoted = false; + + while (*src && len < MAX_PATH) + { + if (src[0] != '\\' || (src[1] != ' ' && src[1] != '(' && src[1] != ')')) + { + *dest++ = *src; + len++; + } + else + { + quoted = true; + } + + src++; + } + + if (*src || len >= MAX_PATH) + { + fprintf(stderr, "# ERROR: Path truncated\n"); + exit(EXIT_FAILURE); + } + + *dest = '\0'; + return quoted; +} +#endif + +static const char *convert_path(const char *path) +{ +#ifdef HOST_CYGWIN + if (g_winpath) + { + const char *retptr; + ssize_t size; + ssize_t ret; + bool quoted; + + quoted = dequote_path(path); + if (quoted) + { + retptr = g_posixpath; + } + else + { + retptr = &g_posixpath[1]; + } + + size = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE, g_dequoted, + NULL, 0); + if (size > (MAX_PATH-3)) + { + fprintf(stderr, "# ERROR: POSIX path too long: %lu\n", + (unsigned long)size); + exit(EXIT_FAILURE); + } + + ret = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE, g_dequoted, + &g_posixpath[1], MAX_PATH-3); + if (ret < 0) + { + fprintf(stderr, "# ERROR: cygwin_conv_path '%s' failed: %s\n", + g_dequoted, strerror(errno)); + exit(EXIT_FAILURE); + } + + if (quoted) + { + size++; + g_posixpath[0] = '"'; + g_posixpath[size] = '"'; + } + + g_posixpath[size+1] = '\0'; + return retptr; + } + else +#endif + { + return path; + } +} + +static void do_dependency(const char *file) { static const char moption[] = " -M "; struct stat buf; @@ -426,12 +583,21 @@ static void do_dependency(const char *file, char separator) char *altpath; char *path; char *lasts; + char separator; int cmdlen; int pathlen; int filelen; int totallen; int ret; + /* Initialize the separator */ + +#ifdef HOST_CYGWIN + separator = (g_winnative || g_winpath) ? '\\' : '/'; +#else + separator = g_winnative ? '\\' : '/'; +#endif + /* Copy the compiler into the command buffer */ cmdlen = strlen(g_cc); @@ -444,16 +610,6 @@ static void do_dependency(const char *file, char separator) strcpy(g_command, g_cc); - /* Copy " -M " */ - - cmdlen += strlen(moption); - if (cmdlen >= MAX_BUFFER) - { - fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n", - cmdlen, MAX_BUFFER, moption); - exit(EXIT_FAILURE); - } - /* Copy " -MT " */ if (g_objpath) @@ -462,6 +618,7 @@ static void do_dependency(const char *file, char separator) char *dupname; char *objname; char *dotptr; + const char *expanded; dupname = strdup(file); if (!dupname) @@ -477,10 +634,11 @@ static void do_dependency(const char *file, char separator) *dotptr = '\0'; } - snprintf(tmp, NAME_MAX+6, " -MT %s" DELIM "%s%s ", - g_objpath, objname, g_suffix); + snprintf(tmp, NAME_MAX+6, " -MT %s%c%s%s ", + g_objpath, separator, objname, g_suffix); + expanded = do_expand(tmp); - cmdlen += strlen(tmp); + cmdlen += strlen(expanded); if (cmdlen >= MAX_BUFFER) { fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n", @@ -488,17 +646,31 @@ static void do_dependency(const char *file, char separator) exit(EXIT_FAILURE); } - strcat(g_command, tmp); + strcat(g_command, expanded); free(dupname); } + /* Copy " -M " */ + + cmdlen += strlen(moption); + if (cmdlen >= MAX_BUFFER) + { + fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n", + cmdlen, MAX_BUFFER, moption); + exit(EXIT_FAILURE); + } + strcat(g_command, moption); /* Copy the CFLAGS into the command buffer */ if (g_cflags) { - cmdlen += strlen(g_cflags); + const char *expanded; + + expanded = do_expand(g_cflags); + cmdlen += strlen(expanded); + if (cmdlen >= MAX_BUFFER) { fprintf(stderr, "ERROR: CFLAG string is too long [%d/%d]: %s\n", @@ -506,7 +678,7 @@ static void do_dependency(const char *file, char separator) exit(EXIT_FAILURE); } - strcat(g_command, g_cflags); + strcat(g_command, expanded); } /* Add a space */ @@ -534,53 +706,55 @@ static void do_dependency(const char *file, char separator) while ((path = strtok_r(altpath, " ", &lasts)) != NULL) { + const char *expanded; + const char *converted; + /* Create a full path to the file */ pathlen = strlen(path); - totallen = cmdlen + pathlen; - if (totallen >= MAX_BUFFER) + if (pathlen >= MAX_PATH) { fprintf(stderr, "ERROR: Path is too long [%d/%d]: %s\n", - totallen, MAX_BUFFER, path); + pathlen, MAX_PATH, path); exit(EXIT_FAILURE); } - strcpy(&g_command[cmdlen], path); + strcpy(g_path, path); - if (g_command[totallen] != '\0') + if (g_path[pathlen] != '\0') { fprintf(stderr, "ERROR: Missing NUL terminator\n"); exit(EXIT_FAILURE); } - if (g_command[totallen-1] != separator) + if (g_path[pathlen-1] != separator) { - g_command[totallen] = separator; - g_command[totallen+1] = '\0'; + g_path[pathlen] = separator; + g_path[pathlen+1] = '\0'; pathlen++; - totallen++; } - filelen = strlen(file); - totallen += filelen; - if (totallen >= MAX_BUFFER) - { + filelen = strlen(file); + pathlen += filelen; + if (pathlen >= MAX_PATH) + { fprintf(stderr, "ERROR: Path+file is too long [%d/%d]\n", - totallen, MAX_BUFFER); + pathlen, MAX_PATH); exit(EXIT_FAILURE); - } + } - strcat(g_command, file); + strcat(g_path, file); /* Check that a file actually exists at this path */ if (g_debug) { fprintf(stderr, "Trying path=%s file=%s fullpath=%s\n", - path, file, &g_command[cmdlen]); + path, file, g_path); } - ret = stat(&g_command[cmdlen], &buf); + converted = convert_path(g_path); + ret = stat(converted, &buf); if (ret < 0) { altpath = NULL; @@ -590,13 +764,28 @@ static void do_dependency(const char *file, char separator) if (!S_ISREG(buf.st_mode)) { fprintf(stderr, "ERROR: File %s exists but is not a regular file\n", - &g_command[cmdlen]); + g_path); exit(EXIT_FAILURE); } - /* Okay.. we have. Create the dependency. One a failure to start the - * compiler, system() will return -1; Otherwise, the returned value - * from the compiler is in WEXITSTATUS(ret). + /* Append the expanded path to the command */ + + expanded = do_expand(g_path); + pathlen = strlen(expanded); + totallen = cmdlen + pathlen; + + if (totallen >= MAX_BUFFER) + { + fprintf(stderr, "ERROR: Path string is too long [%d/%d]: %s\n", + totallen, MAX_BUFFER, g_path); + exit(EXIT_FAILURE); + } + + strcat(g_command, expanded); + + /* Okay.. we have everything. Create the dependency. One a failure + * to start the compiler, system() will return -1; Otherwise, the + * returned value from the compiler is in WEXITSTATUS(ret). */ if (g_debug) @@ -639,155 +828,6 @@ static void do_dependency(const char *file, char separator) exit(EXIT_FAILURE); } -/* Convert a Cygwin path to a Windows path */ - -#ifdef HAVE_WINPATH -static char *cywin2windows(const char *str, const char *append, enum slashmode_e mode) -{ - static const char cygdrive[] = "/cydrive"; - char *dest; - char *newpath; - char *allocpath = NULL; - int srclen = strlen(str); - int alloclen = 0; - int drive = 0; - int lastchar; - - /* Skip any leading whitespace */ - - while (isspace(*str)) str++; - - /* Were we asked to append something? */ - - if (append) - { - alloclen = sizeof(str) + sizeof(append) + 1; - allocpath = (char *)malloc(alloclen); - if (!allocpath) - { - fprintf(stderr, "ERROR: Failed to allocate %d bytes\n", alloclen); - exit(EXIT_FAILURE); - } - - snprintf(allocpath, alloclen, "%s/%s", str, append); - str = allocpath; - } - - /* Looking for path of the form /cygdrive/c/bla/bla/bla */ - - if (strcasecmp(str, cygdrive) == 0) - { - int cygsize = sizeof(cygdrive); - if (str[cygsize] == '/') - { - cygsize++; - srclen -= cygsize; - str += cygsize; - - if (srclen <= 0) - { - fprintf(stderr, "ERROR: Unhandled path: \"%s\"\n", str); - exit(EXIT_FAILURE); - } - - drive = toupper(*str); - if (drive < 'A' || drive > 'Z') - { - fprintf(stderr, "ERROR: Drive character: \"%s\"\n", str); - exit(EXIT_FAILURE); - } - - srclen--; - str++; - alloclen = 2; - } - } - - /* Determine the size of the new path */ - - alloclen += sizeof(str) + 1; - if (mode == MODE_DBLBACK) - { - const char *tmpptr; - for (tmpptr = str; *tmpptr; tmpptr++) - { - if (*tmpptr == '/') alloclen++; - } - } - - /* Allocate memory for the new path */ - - newpath = (char *)malloc(alloclen); - if (!newpath) - { - fprintf(stderr, "ERROR: Failed to allocate %d bytes\n", alloclen); - exit(EXIT_FAILURE); - } - - dest = newpath; - - /* Copy the drive character */ - - if (drive) - { - *dest++ = drive; - *dest++ = ':'; - } - - /* Copy each character from the source, making modifications for foward - * slashes as required. - */ - - lastchar = '\0'; - for (; *str; str++) - { - if (mode != MODE_FSLASH && *str == '/') - { - if (lastchar != '/') - { - *dest++ = '\\'; - if (mode == MODE_DBLBACK) - { - *dest++ = '\\'; - } - } - } - else - { - *dest++ = *str; - } - - lastchar = *str; - } - - *dest++ = '\0'; - if (allocpath) - { - free(allocpath); - } - return dest; -} -#endif - -#ifdef HAVE_WINPATH -static void do_winpath(char *file) -{ - /* The file is in POSIX format. CC expects Windows format to generate the - * dependencies, but GNU make expect the resulting dependencies to be back - * in POSIX format. What a mess! - */ - - char *path = cywin2windows(g_topdir, file, MODE_FSLASH); - - /* Then get the dependency and perform conversions on it to make it - * palatable to the Cygwin make. - */ -#warning "Missing logic" - - free(path); -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -814,17 +854,7 @@ int main(int argc, char **argv, char **envp) * being using in a POSIX/Cygwin environment. */ -#ifdef HAVE_WINPATH - if (g_winpath) - { - do_winpath(file); - } - else -#endif - { - do_dependency(file, g_winnative ? '\\' : '/'); - } - + do_dependency(file); files = NULL; } diff --git a/tools/mkdeps.sh b/tools/mkdeps.sh deleted file mode 100755 index 8a03ac5712027ecbfb1fd886f0c83d1839da54a4..0000000000000000000000000000000000000000 --- a/tools/mkdeps.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/bash -############################################################################ -# tools/mkdeps.sh -# -# Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# -# 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. -# -############################################################################ -# -# Usage: - -show_usage () -{ - echo "" - echo "$progname [OPTIONS] CC -- CFLAGS -- file [file [file...]]" - echo "" - echo "Where:" - echo " CC" - echo " A variable number of arguments that define how to execute the compiler" - echo " CFLAGS" - echo " The compiler compilation flags" - echo " file" - echo " One or more C files whose dependencies will be checked. Each file is expected" - echo " to reside in the current directory unless --dep-path is provided on the command line" - echo "" - echo "And [OPTIONS] include:" - echo " --dep-debug" - echo " Enable script debug" - echo " --dep-path " - echo " Do not look in the current directory for the file. Instead, look in to see" - echo " if the file resides there. --dep-path may be used multiple times to specify" - echo " multiple alternative location" - echo " --obj-path " - echo " The final objects will not reside in this path but, rather, at the path provided by" - echo " . if provided multiple time, only the last --obj-path will be used." - echo " --obj-suffix " - echo " If and object path is provided, then the extension will be assumed to be .o. This" - echo " default suffix can be overrided with this command line option." - echo " --winpaths " - echo " CC generates dependency lists using Windows paths (e.g., C:\blablah\blabla). This" - echo " switch instructs the script to use 'cygpath' to convert the Windows paths to Cygwin" - echo " paths" - echo " --help" - echo " Shows this message and exits" - exit 1 -} - -dodep () -{ - unset fullpath - if [ -z "$altpath" ]; then - if [ -r $1 ]; then - fullpath=$1 - else - echo "# ERROR: No readable file at $1" - show_usage - fi - else - for path in $altpath; do - tmppath=$path/$1 - if [ -r $tmppath ]; then - fullpath=$tmppath - break; - fi - done - if [ -z "$fullpath" ]; then - echo "# ERROR: No readable file for $1 found at any location" - show_usage - fi - fi - - unset mtarg - if [ ! -z "$objpath" ]; then - srcname=`basename $1` - objname="${srcname%.*}" - mtarg="-MT ${objpath}/${objname}${suffix}" - fi - - $cc -M $mtarg $cflags $fullpath || \ - ( echo "# ERROR: $cc -M $cflags $fullpath FAILED"; exit 4; ) -} - -unset cc -unset cflags -unset files -unset args -unset altpath -unset objpath -suffix=.o -winpaths=n -unset topdir - -# Accumulate CFLAGS up to "--" -progname=$0 -while [ ! -z "$1" ]; do - case $1 in - -- ) - cc=$cflags - cflags=$args - args= - ;; - --dep-debug ) - if [ -z "$args" ]; then - set -x - else - args="$args $1" - fi - ;; - --dep-path ) - if [ -z "$args" ]; then - shift - altpath="$altpath $1" - else - args="$args $1" - fi - ;; - --obj-path ) - shift - objpath="$1" - ;; - --obj-suffix ) - shift - suffix="$1" - ;; - --winpaths ) - if [ -z "$args" ]; then - shift - winpaths=y - topdir=$1 - else - args="$args $1" - fi - ;; - --help ) - show_usage - ;; - *) - args="$args $1" - ;; - esac - shift -done -files=$args - -if [ -z "$cc" ]; then - echo "ERROR: No compiler specified" - show_usage - exit 1 -fi - -if [ -z "$files" ]; then - # Don't report an error -- this happens normally in some configurations - echo "# No files specified for dependency generataion" - exit 0 -fi - -# Check if this compiler generates Cygwin/Linux paths or Windows paths - -if [ "X${winpaths}" = "Xy" ]; then - # We will have to parse and modify each dependency (yech) - # Make sure a valid TOPDIR argument was provided - - if [ -z "$topdir" -o ! -d $topdir ]; then - echo " not specified or does not exist: $topdir" - show_usage - exit 1 - fi - - # Get the top dir expressed like the Windows GCC would use it, except - # with forward slashs - - wtopdir=`cygpath -w ${topdir} | sed -e "s,\\\\\\,/,g"` - - # Then get the dependency and perform conversions on it to make it - # palatable to the Cygwin make. This is probably not sufficiently - # general to work on all platforms (like if your disk is not C:). - - for file in $files ; do - dodep $file | sed -e "s,\\\,/,g" -e "s,${wtopdir},${topdir},g" \ - -e "s,/ ,\\\ ,g" -e "s,c:/,/cygdrive/c/,g" \ - -e "s,/$,\\\,g" - done -else - # For normal Cygwin/Linux GCC, the dependency paths are in the - # correct form and can simply be echoed on stdout - - for file in $files ; do - dodep $file - done -fi - diff --git a/tools/mksymtab.c b/tools/mksymtab.c index e9591febbcbb542b1d56e5319c75cc86c1391437..ddac7fda07433f34bdf78b5c7a7fce69a0b858d6 100644 --- a/tools/mksymtab.c +++ b/tools/mksymtab.c @@ -1,7 +1,7 @@ /**************************************************************************** * tools/mksymtab.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -234,7 +234,7 @@ int main(int argc, char **argv, char **envp) /* Now the symbol table itself */ - fprintf(outstream, "\nstruct symtab_s %s[] =\n", SYMTAB_NAME); + fprintf(outstream, "\nconst struct symtab_s %s[] =\n", SYMTAB_NAME); fprintf(outstream, "{\n"); /* Parse each line in the CVS file */ diff --git a/tools/mkwindeps.sh b/tools/mkwindeps.sh new file mode 100755 index 0000000000000000000000000000000000000000..b8851efe30047158bad1d30df56bbb4444b5c0c8 --- /dev/null +++ b/tools/mkwindeps.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# tools/mkwindeps.sh +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# + +# Uncomment to enable debug options +# set -x +# DEBUG=--dep-debug + +# Make sure that we know where we are + +TOOLDIR=$(dirname $0) + +if [ ! -x ${TOOLDIR}/mkwindeps.sh ]; then + echo "# ERROR: tools/ directory not found" + exit 1 +fi + +# Make sure that executables are ready + +MKDEPS=${TOOLDIR}/mkdeps.exe +CNVWINDEPS=${TOOLDIR}/cnvwindeps.exe + +if [ ! -x ${MKDEPS} ]; then + echo "# ERROR: tools/mkdeps.exe does not exist" + exit 1 +fi + +if [ ! -x ${CNVWINDEPS} ]; then + echo "# ERROR: tools/cnvwindeps.exe does not exist" + exit 1 +fi + +# Run the mkdeps.exe program to generate a Windows dependency file + +TMPFILE=$(mktemp) +${MKDEPS} ${DEBUG} --winpath $* > ${TMPFILE} || { echo "# ERROR: mkdeps.exe failed"; exit 1; } + +# Then convert this to a POSIX dependency file (on stdout) + +${CNVWINDEPS} ${TMPFILE} +rm -f ${TMPFILE} diff --git a/tools/nxstyle.c b/tools/nxstyle.c new file mode 100644 index 0000000000000000000000000000000000000000..4fa84eb523eb442855ff58a51f7163950600ec1f --- /dev/null +++ b/tools/nxstyle.c @@ -0,0 +1,991 @@ +/**************************************************************************** + * tools/nxstyle.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LINE_SIZE 512 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ + FILE *instream; + char line[LINE_SIZE]; + bool btabs; + bool bfunctions; + bool bstatm; + bool bfor; + bool bswitch; + bool bstring; + bool bquote; + int lineno; + int indent; + int prevnest; + int ncomment; + int nnest; + int declnest; + int prevdeclnest; + int prevncomment; + int n; + int i; + + instream = fopen(argv[1], "r"); + if (!instream) + { + fprintf(stderr, "Failed to open %s\n", argv[1]); + return 1; + } + + btabs = false; + bfunctions = false; + bswitch = false; + bstring = false; + lineno = 0; + ncomment = 0; + nnest = 0; + declnest = 0; + prevdeclnest = 0; + prevncomment = 0; + + while (fgets(line, LINE_SIZE, instream)) + { + lineno++; + indent = 0; + prevnest = nnest; + prevdeclnest = declnest; + prevncomment = ncomment; + bstatm = false; + bfor = false; /* REVISIT: Implies for() is all on one line */ + + /* STEP 1: Find the indentation level and the start of real stuff on + * the line. + */ + + for (n = 0; line[n] != '\n' && isspace((int)line[n]); n++) + { + switch (line[n]) + { + case ' ': + { + indent++; + } + break; + + case '\t': + { + if (!btabs) + { + fprintf(stderr, "TABs found. First at line %d:%d\n", lineno, n); + btabs = true; + } + + indent = (indent + 4) & ~3; + } + break; + + default: + { + fprintf(stderr, "Unexpected white space character %02x found at line %d:%d\n", line[n], lineno, n); + } + break; + } + } + + /* STEP 2: Detect some certain start of line conditions */ + /* Skip over pre-processor lines */ + + if (line[indent] == '#') + { + continue; + } + + /* Check for the comment block indicating the beginning of functions. */ + + if (!bfunctions && ncomment > 0 && + (strcmp(line, " * Private Functions\n") == 0 || + strcmp(line, " * Public Functions\n") == 0)) + { + //fprintf(stderr, "Functions begin at line %d:%d\n", lineno, n); + bfunctions = true; + } + + /* Check for some kind of declaration. + * REVISIT: The following logic fails for any non-standard types. + * REVISIT: Terminator after keyword might not be a space. Might be + * a newline, for example. struct and unions are often unnamed, for + * example. + */ + + else if (strncmp(&line[indent], "auto ", 5) == 0 || + strncmp(&line[indent], "bool ", 5) == 0 || + strncmp(&line[indent], "char ", 5) == 0 || + strncmp(&line[indent], "CODE ", 5) == 0 || + strncmp(&line[indent], "const ", 6) == 0 || + strncmp(&line[indent], "double ", 7) == 0 || +// strncmp(&line[indent], "struct ", 7) == 0 || + strncmp(&line[indent], "struct", 6) == 0 || /* May be unnamed */ + strncmp(&line[indent], "enum ", 5) == 0 || + strncmp(&line[indent], "extern ", 7) == 0 || + strncmp(&line[indent], "EXTERN ", 7) == 0 || + strncmp(&line[indent], "FAR ", 4) == 0 || + strncmp(&line[indent], "float ", 6) == 0 || + strncmp(&line[indent], "int ", 4) == 0 || + strncmp(&line[indent], "int16_t ", 8) == 0 || + strncmp(&line[indent], "int32_t ", 8) == 0 || + strncmp(&line[indent], "long ", 5) == 0 || + strncmp(&line[indent], "off_t ", 6) == 0 || + strncmp(&line[indent], "register ", 9) == 0 || + strncmp(&line[indent], "short ", 6) == 0 || + strncmp(&line[indent], "signed ", 7) == 0 || + strncmp(&line[indent], "size_t ", 7) == 0 || + strncmp(&line[indent], "ssize_t ", 8) == 0 || + strncmp(&line[indent], "static ", 7) == 0 || + strncmp(&line[indent], "time_t ", 7) == 0 || + strncmp(&line[indent], "typedef ", 8) == 0 || + strncmp(&line[indent], "uint8_t ", 8) == 0 || + strncmp(&line[indent], "uint16_t ", 9) == 0 || + strncmp(&line[indent], "uint32_t ", 9) == 0 || +// strncmp(&line[indent], "union ", 6) == 0 || + strncmp(&line[indent], "union", 5) == 0 || /* May be unnamed */ + strncmp(&line[indent], "unsigned ", 9) == 0 || + strncmp(&line[indent], "void ", 5) == 0 || + strncmp(&line[indent], "volatile ", 9) == 0) + { + /* REVISIT: Also picks up function return types */ + /* REVISIT: Logic problem for nested data/function declarations */ + + if ((!bfunctions || nnest > 0) && declnest == 0) + { + declnest = 1; + } + } + + /* Check for a keyword indicating the beginning of a statement. + * REVISIT: This, obviously, will not detect statements that do not + * begin with a C keyword (such as assignement statements). + */ + + else if (strncmp(&line[indent], "break ", 6) == 0 || + strncmp(&line[indent], "case ", 5) == 0 || +// strncmp(&line[indent], "case ", 5) == 0 || /* Part of switch */ + strncmp(&line[indent], "continue ", 9) == 0 || +// strncmp(&line[indent], "default ", 8) == 0 || /* Part of switch */ + strncmp(&line[indent], "do ", 3) == 0 || + strncmp(&line[indent], "else ", 5) == 0 || + strncmp(&line[indent], "goto ", 5) == 0 || + strncmp(&line[indent], "if ", 3) == 0 || + strncmp(&line[indent], "return ", 7) == 0 || +// strncmp(&line[indent], "switch ", 7) == 0 || /* Doesn't follow pattern */ + strncmp(&line[indent], "while ", 6) == 0) + { + bstatm = true; + } + + /* Spacing works a little differently for and switch statements */ + + else if (strncmp(&line[indent], "for ", 4) == 0) + { + bfor = true; + bstatm = true; + } + else if (strncmp(&line[indent], "switch ", 7) == 0) + { + bswitch = true; + } + + /* Also check for C keywords with missing white space */ + + else if (strncmp(&line[indent], "do(", 3) == 0 || + strncmp(&line[indent], "if(", 3) == 0 || + strncmp(&line[indent], "while(", 6) == 0) + { + fprintf(stderr, "Missing whitespace after keyword at line %d:%d\n", lineno, n); + bstatm = true; + } + else if (strncmp(&line[indent], "for(", 4) == 0) + { + fprintf(stderr, "Missing whitespace after keyword at line %d:%d\n", lineno, n); + bfor = true; + bstatm = true; + } + else if (strncmp(&line[indent], "switch(", 7) == 0) + { + fprintf(stderr, "Missing whitespace after keyword at line %d:%d\n", lineno, n); + bswitch = true; + } + + /* STEP 3: Parse each character on the line */ + + bquote = false; + for (; line[n] != '\n' && line[n] != '\0'; n++) + { + if (line[n] == '/' && !bstring) + { + /* Check for start of a C comment */ + + if (line[n+1] == '*') + { + if (line[n+2] == '\n') + { + fprintf(stderr, "C comment on separate line at %d:%d\n", + lineno, n); + } + else if (line[n+2] != ' ' && line[n+2] != '*') + { + fprintf(stderr, + "Missing space after opening C comment at line %d:%d\n", + lineno, n); + } + + ncomment++; + n++; + continue; + } + + /* Check for end of a C comment */ + + else if (n > 0 && line[n-1] == '*') + { + if (n < 2) + { + fprintf(stderr, "Closing C comment not indented at line %d:%d\n", + lineno, n); + } + else if (line[n-2] != ' ' && line[n-2] != '*') + { + fprintf(stderr, + "Missing space before closing C comment at line %d:%d\n", + lineno, n); + } + +#if 0 + /* REVISIT: Generates false alarms when portions of an + * expression are commented out within the expression. + */ + + if (line[n+1] != '\n') + { + fprintf(stderr, + "Garbage on line after C comment at line %d:%d\n", + lineno, n); + } +#endif + + if (ncomment > 0) + { + ncomment--; + } + else + { + ncomment = 0; + fprintf(stderr, + "Closing without opening comment at line %d:%d\n", + lineno, n); + } + } + + /* Check for C++ style comments */ + + else if (line[n+1] == '/') + { + fprintf(stderr, "C++ style comment on at %d:%d\n", + lineno, n); + n++; + continue; + } + } + + /* Check for a string... ignore if we are in the middle of a + * comment. + */ + + if (ncomment == 0) + { + /* Backslash quoted charater */ + + if (line[n] == '\\') + { + bquote = true; + n++; + } + + /* Check for quoated characters: \" in string */ + + if (line[n] == '"' && !bquote) + { + bstring = !bstring; + } + + bquote = false; + } + + /* The reset of the line is only examined of we are in a comment + * or a string. + * + * REVISIT: Should still check for whitespace at the end of the + * line. + */ + + if (ncomment == 0 && !bstring) + { + switch (line[n]) + { + /* Handle logic nested with curly braces */ + + case '{': + { + if (n > indent) + { + if (declnest == 0) + { + fprintf(stderr, + "Left bracket not on separate line at %d:%d\n", + lineno, n); + } + } + else if (line[n+1] != '\n') + { + if (declnest == 0) + { + fprintf(stderr, + "Garbage follows left bracket at line %d:%d\n", + lineno, n); + } + } + + nnest++; + if (declnest > 0) + { + declnest++; + } + } + break; + + case '}': + { + if (nnest < 1) + { + fprintf(stderr, "Unmatched right brace at line %d:%d\n", lineno, n); + } + else + { + nnest--; + if (nnest < 1) + { + nnest = 0; + bswitch = false; + } + } + + if (declnest < 3) + { + declnest = 0; + } + else + { + declnest--; + } + + if (n > indent) + { + if (declnest == 0) + { + fprintf(stderr, + "Right bracket not on separate line at %d:%d\n", + lineno, n); + } + } + else if (line[n+1] != '\n' && + line[n+1] != ',' && + line[n+1] != ';') + { + /* One case where there may be garbage after the right + * bracket is, for example, when declaring a until or + * structure variable using an un-named union or + * structure. + */ + + if (prevdeclnest <= 0 || declnest > 0) + { + fprintf(stderr, + "Garbage follows right bracket at line %d:%d\n", + lineno, n); + } + } + } + break; + + /* Check for inappropriate space around parentheses */ + + case '(': + { + if (line[n+1] == ' ' /* && !bfor */) + { + fprintf(stderr, + "Space follows left parenthesis at line %d:%d\n", + lineno, n); + } + } + break; + + case ')': + { + /* Allow ')' as first thing on the line (n == indent) + * Allow "for (xx; xx; )" (bfor == true) + */ + + if (n > 0 && n != indent && line[n-1] == ' ' && !bfor) + { + fprintf(stderr, + "Space precedes right parenthesis at line %d:%d\n", + lineno, n); + } + } + break; + + /* Check for inappropriate space around square brackets */ + + case '[': + { + if (line[n+1] == ' ') + { + fprintf(stderr, + "Space follows left bracket at line %d:%d\n", + lineno, n); + } + } + break; + + case ']': + { + if (n > 0 && line[n-1] == ' ') + { + fprintf(stderr, + "Space precedes right bracket at line %d:%d\n", + lineno, n); + } + } + break; + + /* Semi-colon may terminate a declaration */ + + case ';': + { + if (!isspace((int)line[n+1])) + { + fprintf(stderr, "Missing whitespace after semicolon at line %d:%d\n", + lineno, n); + } + + /* Semicolon terminates a declaration/definition if there + * was no left curly brace (i.e., declnest is only 1). + */ + + if (declnest == 1) + { + declnest = 0; + } + } + break; + + /* Semi-colon may terminate a declaration */ + + case ',': + { + if (!isspace((int)line[n+1])) + { + fprintf(stderr, "Missing whitespace after comma at line %d:%d\n", + lineno, n); + } + } + break; + + case '\r': + { + fprintf(stderr, + "Carriage return detected at line %d:%d\n", + lineno, n); + } + break; + + /* Skip over character constants */ + + case '\'': + { + int endndx = n + 2; + + if (line[n+1] != '\n' && line[n+1] != '\0') + { + if (line[n+1] == '\\') + { + for (; + line[endndx] != '\n' && + line[endndx] != '\0' && + line[endndx] != '\''; + endndx++); + } + + n = endndx + 1; + } + } + break; + + /* Check for space at the end of the line */ + + case '\n': + { + if (n > 0 && isspace((int)line[n-1])) + { + fprintf(stderr, + "Dangling whitespace at the end of line %d:%d\n", + lineno, n); + } + } + break; + + /* Check for space around various operators */ + + case '-': + /* -> */ + + if (line[n+1] == '>') + { + n++; + break; + } + + case '+': + /* ++, -- */ + + if (line[n+1] == line[n]) + { + n++; + break; + } + + case '&': + /* && */ + + if (line[n] == '&' && line[n+1] == line[n]) + { + int curr; + int next; + + curr = n; + n++; + next = n + 1; + + if (line[curr-1] != ' ') + { + fprintf(stderr, + "Operator/assignment must be preceded with whitespace at line %d:%d\n", + lineno, curr); + } + + if (line[next] != ' ' && line[next] != '\n') + { + fprintf(stderr, + "Operator/assignment needs whitespace separation at line %d:%d\n", + lineno, curr); + } + + break; + } + + /* & OR &()*/ + + else if (isalpha((int)line[n+1]) || line[n+1] == '_' || line[n+1] == '(') + { + break; + } + + case '/': + { + if (line[n] == '/') + { + if (line[n-1] == '*') + { + n++; + break; + } + else if (line[n+1] == '/') + { + fprintf(stderr, "C++ style comment on at %d:%d\n", + lineno, n); + n++; + break; + } + } + } + + case '*': + { + /* *\/, ** */ + + if (line[n] == '*' && + (line[n+1] == '/' || + line[n+1] == '*')) + { + n++; + break; + } + + /* *, *() */ + + else if (isalpha((int)line[n+1]) || + line[n+1] == '_' || + line[n+1] == '(') + { + break; + } + + /* ( *) */ + + else if (line[n+1] == ')') + { + /* REVISIT: This gives false alarms on syntax like *--ptr */ + + if (line[n-1] != ' ') + { + fprintf(stderr, + "Operator/assignment must be preceded with whitespace at line %d:%d\n", + lineno, n); + } + + break; + } + } + + case '%': + { + if (isalnum((int)line[n+1])) + { + break; + } + } + + case '<': + case '>': + case '|': + case '^': + case '=': + { + int curr; + int next; + + curr = n; + if (line[curr-1] != ' ') + { + fprintf(stderr, + "Operator/assignment must be preceded with whitespace at line %d:%d\n", + lineno, curr); + } + + next = n+1; + + /* <<, >>, <<=, >>= */ + + if (line[curr] == '>' || line[curr] == '<') + { + if (line[next] == line[curr]) + { + next++; + n++; + } + + if (line[next] == '=') + { + next++; + n++; + } + } + else if (line[next] == '=' || line[next] == line[n]) + { + next++; + n++; + } + + /* REVISIT: This gives false alarms on syntax like *--ptr */ + + if (line[curr] != '-' && line[next] != ' ' && line[next] != '\n') + { + fprintf(stderr, + "Operator/assignment needs whitespace separation at line %d:%d\n", + lineno, curr); + } + } + break; + + case '~': + case '!': + { + int curr; + int next; + + curr = n; + next = n + 1; + if (line[next] == '=' || line[next] == line[n]) + { + next++; + n++; + + if (line[next] != ' ' && line[next] != '\n') + { + fprintf(stderr, + "Operator/assignment needs whitespace separation at line %d:%d\n", + lineno, curr); + } + } + + if (line[curr-1] != ' ' && line[curr-1] != '(') + { + fprintf(stderr, + "Operator/assignment must be preceded with whitespace at line %d:%d\n", + lineno, curr); + } + } + break; + + default: + break; + } + } + } + + /* STEP 4: Check alignment */ + + /* Within a comment block, we need only check on the alignment of the + * comment. + */ + + if ((ncomment > 0 || prevncomment > 0) && !bstring) + { + if (indent == 0 && line[0] != '/') + { + fprintf(stderr, "No indentation line %d:%d\n", + lineno, indent); + } + else if (indent == 1 && line[0] == ' ' && line[1] == '*') + { + /* Good indentation */ + } + else if (indent > 0 && line[indent] == '\n') + { + fprintf(stderr, "Whitespace on blank line at line %d:%d\n", + lineno, indent); + } + else if (indent > 0 && indent < 2) + { + fprintf(stderr, "Insufficient indentation line %d:%d\n", + lineno, indent); + } + else if (indent > 0 && !bswitch) + { + if (line[indent] == '/') + { + if ((indent & 3) != 2) + { + fprintf(stderr, + "Bad comment alignment at line %d:%d\n", + lineno, indent); + } + + /* REVISIT: This screws up in cases where there is C code, + * followed by a comment that continues on the next line. + */ + + else if (line[indent+1] != '*') + { + fprintf(stderr, + "Missing asterisk in comment at line %d:%d\n", + lineno, indent); + } + } + else if (line[indent] == '*') + { + /* REVISIT: Generates false alarms on comments at the end of + * the line if there is nothing preceding (such as the aligned + * comments with a structure field definition). So disabled for + * comments before beginning of function definitions. + */ + + if ((indent & 3) != 3 && bfunctions && declnest == 0) + { + fprintf(stderr, + "Bad comment block alignment at line %d:%d\n", + lineno, indent); + } + + if (line[indent+1] != ' ' && + line[indent+1] != '\n' && + line[indent+1] != '/') + { + fprintf(stderr, + "Invalid character after asterisk in comment block at line %d:%d\n", + lineno, indent); + } + } + + /* If this is not the line containing the comment start, then this + * line should begin with '*' + */ + + else if (prevncomment > 0) + { + fprintf(stderr, "Missing asterisk in comment block at line %d:%d\n", + lineno, indent); + } + } + } + + /* Check for various alignment outside of the comment block */ + + else if ((ncomment > 0 || prevncomment > 0) && !bstring) + { + if (indent == 0 && strchr("\n#{}", line[0]) == NULL) + { + /* Ignore if we are at global scope */ + + if (prevnest > 0) + { + bool blabel = false; + + if (isalpha((int)line[indent])) + { + for (i = indent + 1; isalnum((int)line[i]) || line[i] == '_'; i++); + blabel = (line[i] == ':'); + } + + if (!blabel) + { + fprintf(stderr, "No indentation line %d:%d\n", + lineno, indent); + } + } + } + else if (indent == 1 && line[0] == ' ' && line[1] == '*') + { + /* Good indentation */ + } + else if (indent > 0 && line[indent] == '\n') + { + fprintf(stderr, "Whitespace on blank line at line %d:%d\n", + lineno, indent); + } + else if (indent > 0 && indent < 2) + { + fprintf(stderr, "Insufficient indentation line %d:%d\n", + lineno, indent); + } + else if (line[indent] == '{') + { + /* REVISIT: False alarms in data initializers and switch statements */ + + if ((indent & 3) != 0 && !bswitch && declnest == 0) + { + fprintf(stderr, "Bad left brace alignment at line %d:%d\n", + lineno, indent); + } + } + else if (line[indent] == '}') + { + /* REVISIT: False alarms in data initializers and switch statements */ + + if ((indent & 3) != 0 && !bswitch && prevdeclnest == 0) + { + fprintf(stderr, "Bad right brace alignment at line %d:%d\n", + lineno, indent); + } + } + else if (indent > 0) + { + /* REVISIT: Generates false alarms when a statement continues on + * the next line. The bstatm check limits to lines beginnnig with + * C keywords. + * REVISIT: The bstatm check will not detect statements that + * do not begin with a C keyword (such as assignement statements). + * REVISIT: Generates false alarms on comments at the end of + * the line if there is nothing preceding (such as the aligned + * comments with a structure field definition). So disabled for + * comments before beginning of function definitions. + */ + + if ((bstatm || /* Begins with C keyword */ + (line[indent] == '/' && bfunctions)) && /* Comment in functions */ + !bswitch && /* Not in a switch */ + declnest == 0) /* Not a data definition */ + { + if ((indent & 3) != 2) + { + fprintf(stderr, "Bad alignment at line %d:%d\n", + lineno, indent); + } + } + + /* Crazy cases. There should be no small odd alignements + * outside of comment/string. Odd alignments are possible + * on continued lines, but not if they are small. + */ + + else if (indent == 1 || indent == 3) + { + fprintf(stderr, "Small odd alignment at line %d:%d\n", + lineno, indent); + } + } + } + } + + if (ncomment > 0 || bstring) + { + fprintf(stderr, "In a comment/string at end of file\n"); + } + + fclose(instream); + return 0; +} diff --git a/tools/refresh.sh b/tools/refresh.sh index a35b25b4196f8ff861805e57d7576eb6848ef126..01df311b6068019becc126435e1f9dc9d9780695 100755 --- a/tools/refresh.sh +++ b/tools/refresh.sh @@ -36,12 +36,16 @@ USAGE="USAGE: $0 [--debug|--help] /" ADVICE="Try '$0 --help' for more information" unset CONFIG +silent=n while [ ! -z "$1" ]; do case $1 in --debug ) set -x ;; + --silent ) + silent=y + ;; --help ) echo "$0 is a tool for refreshing board configurations" echo "" @@ -50,6 +54,8 @@ while [ ! -z "$1" ]; do echo "Where:" echo " --debug" echo " Enable script debug" + echo " --silent" + echo " Update board configuration without interaction" echo " --help" echo " Show this help message and exit" echo " " @@ -157,9 +163,13 @@ fi cp -a $DEFCONFIG .config || \ { echo "ERROR: Failed to copy $DEFCONFIG to .config"; exit 1; } -# Then run oldconfig +# Then run oldconfig or oldefconfig -make oldconfig +if [ "X${silent}" == "Xy" ]; then + make olddefconfig +else + make oldconfig +fi # Show differences @@ -168,14 +178,21 @@ $CMPCONFIG $DEFCONFIG .config # Save the refreshed configuration -read -p "Save the new configuration (y/n)?" -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then +if [ "X${silent}" == "Xy" ]; then echo "Saving the new configuration file" mv .config $DEFCONFIG || \ { echo "ERROR: Failed to move .config to $DEFCONFIG"; exit 1; } chmod 644 $DEFCONFIG +else + read -p "Save the new configuration (y/n)?" -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]] + then + echo "Saving the new configuration file" + mv .config $DEFCONFIG || \ + { echo "ERROR: Failed to move .config to $DEFCONFIG"; exit 1; } + chmod 644 $DEFCONFIG + fi fi # Restore any previous .config file diff --git a/tools/testbuild.sh b/tools/testbuild.sh index a441196e81569379bd4bceeee728e791c1682083..8f5bb56d4b947b83619b8da1ce9fdcc009903dfc 100755 --- a/tools/testbuild.sh +++ b/tools/testbuild.sh @@ -44,12 +44,12 @@ unset testfile function showusage { echo "" echo "USAGE: $progname [-w|l] [-c|n] [-s] " - echo "USAGE: $progname -h" + echo " $progname -h" echo "" - echo "where" + echo "Where:" echo " -w|l selects Windows (w) or Linux (l). Default: Linux" echo " -c|n selects Windows native (n) or Cygwin (c). Default Cygwin" - echo " -s Use C++ long size_t in new operator. Default unsigned long" + echo " -s Use C++ unsigned long size_t in new operator. Default unsigned int" echo " -h will show this help test and terminate" echo " selects the list of configurations to test. No default" echo "" @@ -73,7 +73,7 @@ while [ ! -z "$1" ]; do wenv=cygwin ;; -n ) - wenv=n + wenv=native ;; -s ) sizet=long @@ -142,23 +142,30 @@ function configure { kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_MSYS kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_OTHER + kconfig-tweak --file $nuttx/.config --enable CONFIG_SIM_X8664_SYSTEMV + kconfig-tweak --file $nuttx/.config --disable CONFIG_SIM_X8664_MICROSOFT + kconfig-tweak --file $nuttx/.config --disable CONFIG_SIM_M32 else echo " Select CONFIG_HOST_WINDOWS=y" kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_WINDOWS kconfig-tweak --file $nuttx/.config --disable CONFIG_HOST_LINUX if [ "X$wenv" == "Xcygwin" ]; then - echo " Select CONFIG_HOST_CYGWIN=y" + echo " Select CONFIG_WINDOWS_CYGWIN=y" kconfig-tweak --file $nuttx/.config --enable CONFIG_WINDOWS_CYGWIN kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_NATIVE else - echo " Select CONFIG_HOST_MSYS=y" + echo " Select CONFIG_WINDOWS_NATIVE=y" kconfig-tweak --file $nuttx/.config --enable CONFIG_WINDOWS_NATIVE kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_CYGWIN fi kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_MSYS kconfig-tweak --file $nuttx/.config --disable CONFIG_WINDOWS_OTHER + + kconfig-tweak --file $nuttx/.config --enable CONFIG_SIM_X8664_MICROSOFT + kconfig-tweak --file $nuttx/.config --disable CONFIG_SIM_X8664_SYSTEMV + kconfig-tweak --file $nuttx/.config --disable CONFIG_SIM_M32 fi kconfig-tweak --file $nuttx/.config --disable CONFIG_HOST_OSX @@ -166,25 +173,27 @@ function configure { if [ "X$sizet" == "Xlong" ]; then echo " Select CONFIG_CXX_NEWLONG=y" - kconfig-tweak --file $nuttx/.config --enable CONFIG_CXX_NEWLONG else echo " Disable CONFIG_CXX_NEWLONG" kconfig-tweak --file $nuttx/.config --disable CONFIG_CXX_NEWLONG fi - setting=`grep TOOLCHAIN $nuttx/.config | grep =y` - varname=`echo $setting | cut -d'=' -f1` - if [ ! -z "varname" ]; then - echo " Disabling $varname" - kconfig-tweak --file $nuttx/.config --disable $varname - fi + if [ "X$toolchain" != "X" ]; then + setting=`grep TOOLCHAIN $nuttx/.config | grep =y` + varname=`echo $setting | cut -d'=' -f1` + if [ ! -z "varname" ]; then + echo " Disabling $varname" + kconfig-tweak --file $nuttx/.config --disable $varname + fi - echo " Enabling $toolchain" - kconfig-tweak --file $nuttx/.config --enable $toolchain + echo " Enabling $toolchain" + kconfig-tweak --file $nuttx/.config --enable $toolchain + fi echo " Refreshing..." - kconfig-conf --olddefconfig Kconfig 1>/dev/null + cd $nuttx || { echo "ERROR: failed to CD to $nuttx"; exit 1; } + make olddefconfig 1>/dev/null 2>&1 } # Perform the next build @@ -232,10 +241,12 @@ for line in $testlist; do showusage fi - toolchain=`echo $line | cut -d',' -f2` - if [ -z "$toolchain" ]; then - echo "ERROR no tool configuration" - showusage + unset toolchain; + if [ "X$config" != "X$line" ]; then + toolchain=`echo $line | cut -d',' -f2` + if [ -z "$toolchain" ]; then + echo " Warning: no tool configuration" + fi fi # Perform the build test diff --git a/tools/xmlrpc_test.py b/tools/xmlrpc_test.py old mode 100644 new mode 100755 diff --git a/wireless/.gitignore b/wireless/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4b32ec6a3dad99cabafd7be62b05f4422d3d4aeb --- /dev/null +++ b/wireless/.gitignore @@ -0,0 +1,10 @@ +/Make.dep +/.depend +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/wireless/Kconfig b/wireless/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..440e30a665c4d9008efd2650c795aa9a2417b027 --- /dev/null +++ b/wireless/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config WIRELESS + bool "Wireless Support" + default n + depends on EXPERIMENTAL + ---help--- + Enables overall support for Wireless library. + +if WIRELESS + +source wireless/ieee802154/Kconfig + +endif # WIRELESS diff --git a/wireless/Makefile b/wireless/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..85f69bd118f91e46342ce07d7d0ed8783dfc53e3 --- /dev/null +++ b/wireless/Makefile @@ -0,0 +1,96 @@ +############################################################################ +# wireless/Makefile +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +DELIM ?= $(strip /) + +ifeq ($(WINTOOL),y) +INCDIROPT = -w +endif + +# Add files to the build + +DEPPATH = --dep-path . + +ASRCS = +CSRCS = +VPATH = . + +# Add IEEE 802.15.4 files to the build + +include ieee802154$(DELIM)Make.defs + +# Include support for various drivers. Each Make.defs file will add its +# files to the source file list, add its DEPPATH info, and will add +# the appropriate paths to the VPATH variable + +ifeq ($(CONFIG_WIRELESS_FORMAT_PCM),y) + CSRCS += pcm_decode.c +endif + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +BIN = libwireless$(LIBEXT) + +all: $(BIN) + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(BIN): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, $(BIN)) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..18d5a8753c3921f81659ddb851563f945c87a33a --- /dev/null +++ b/wireless/ieee802154/Kconfig @@ -0,0 +1,15 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config IEEE802154 + bool "IEEE 802.15.4 Wireless Support" + default n + depends on EXPERIMENTAL + ---help--- + Enables support for the IEEE 802.14.5Wireless library. + +if IEEE802154 + +endif # IEEE802154 diff --git a/wireless/ieee802154/Make.defs b/wireless/ieee802154/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..9e0c66391b473ff910ac8f19f74990e43a01cc18 --- /dev/null +++ b/wireless/ieee802154/Make.defs @@ -0,0 +1,46 @@ +############################################################################ +# wireless/ieee802145/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_IEEE802154),y) + +# Include IEEE 802.15.4 support + +# Include wireless devices build support + +DEPPATH += --dep-path wireless/ieee802154 +VPATH += :wireless/ieee802154 +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)wireless$(DELIM)ieee802154} + +endif # CONFIG_IEEE802154