Skip to content

Commit

Permalink
risc-v/qemu-rv: Add LED Driver for QEMU RISC-V 32-bit and 64-bit
Browse files Browse the repository at this point in the history
- This PR adds the LED Driver for QEMU RISC-V 32-bit and 64-bit (User LEDs and Auto LEDs)
- QEMU RISC-V LED Driver will be used by the Rust Blinky App for Google Summer of Code
- Blinking the LED is probably the most common Embedded Demo, and now it's supported by QEMU RISC-V
- We added NuttX Configs rv-virt:leds and rv-virt:leds64 to support User LEDs for 32-bit and 64-bit RISC-V
- Turning on/off a Simulated User LED will print a log message: "LED 1 set to 1"
- The code is derived from NuttX PinePhone LED Driver
  • Loading branch information
rushabhvg committed Jul 25, 2024
1 parent cde13a7 commit feb7160
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Documentation/platforms/risc-v/qemu-rv/boards/rv-virt/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,16 @@ ksmp64

Identical to the `knsh64`_ configuration but with SMP support.

leds
----

Similar to the `nsh`_ configuration, but with User LEDs support for 32-bit RISC-V.

leds64
------

Similar to the `nsh64`_ configuration, but with User LEDs support for 64-bit RISC-V.

netnsh
------

Expand Down
1 change: 1 addition & 0 deletions boards/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,7 @@ config ARCH_BOARD_RV32M1_VEGA
config ARCH_BOARD_QEMU_RV_VIRT
bool "QEMU RV Virt"
depends on ARCH_CHIP_QEMU_RV
select ARCH_HAVE_LEDS
---help---
This is the board configuration for the port of NuttX to the
QEMU RV32 Virt board. This board features the QEMU RV32 CPU.
Expand Down
71 changes: 71 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/configs/leds/defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_DISABLE_OS_API is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
CONFIG_16550_ADDRWIDTH=0
CONFIG_16550_UART0=y
CONFIG_16550_UART0_BASE=0x10000000
CONFIG_16550_UART0_CLOCK=3686400
CONFIG_16550_UART0_IRQ=37
CONFIG_16550_UART0_SERIAL_CONSOLE=y
CONFIG_16550_UART=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="rv-virt"
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
CONFIG_ARCH_CHIP="qemu-rv"
CONFIG_ARCH_CHIP_QEMU_RV32=y
CONFIG_ARCH_CHIP_QEMU_RV=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILTIN=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_ZERO=y
CONFIG_ELF=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_LEDS=y
CONFIG_FS_HOSTFS=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_LIBM=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PATH_INITIAL="/system/bin"
CONFIG_RAM_SIZE=33554432
CONFIG_RAM_START=0x80000000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RISCV_SEMIHOSTING_HOSTFS=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2021
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_USEC_PER_TICK=1000
CONFIG_USERLED=y
CONFIG_USERLED_LOWER=y
75 changes: 75 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/configs/leds64/defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_DISABLE_OS_API is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
CONFIG_16550_ADDRWIDTH=0
CONFIG_16550_UART0=y
CONFIG_16550_UART0_BASE=0x10000000
CONFIG_16550_UART0_CLOCK=3686400
CONFIG_16550_UART0_IRQ=37
CONFIG_16550_UART0_SERIAL_CONSOLE=y
CONFIG_16550_UART=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="rv-virt"
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
CONFIG_ARCH_CHIP="qemu-rv"
CONFIG_ARCH_CHIP_QEMU_RV64=y
CONFIG_ARCH_CHIP_QEMU_RV=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_A=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BCH=y
CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILTIN=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEVICE_TREE=y
CONFIG_DEV_ZERO=y
CONFIG_ELF=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_LEDS=y
CONFIG_FS_HOSTFS=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=3072
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_LIBM=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PATH_INITIAL="/system/bin"
CONFIG_RAM_SIZE=33554432
CONFIG_RAM_START=0x80000000
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RISCV_SEMIHOSTING_HOSTFS=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2021
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_STACKSIZE=3072
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_USEC_PER_TICK=1000
CONFIG_USERLED=y
CONFIG_USERLED_LOWER=y
18 changes: 18 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@
* Pre-processor Definitions
****************************************************************************/

/* LED definitions **********************************************************/

/* LED index values for use with board_userled() */

typedef enum
{
BOARD_LED1 = 0,
BOARD_LED2 = 1,
BOARD_LED3 = 2,
BOARD_LEDS /* Number of LEDs */
} led_typedef_enum;

/* LED bits for use with board_userled_all() */

#define BOARD_LED1_BIT (1 << BOARD_LED1)
#define BOARD_LED2_BIT (1 << BOARD_LED2)
#define BOARD_LED3_BIT (1 << BOARD_LED3)

#define LED_STARTED 0 /* N/A */
#define LED_HEAPALLOCATE 1 /* N/A */
#define LED_IRQSENABLED 2 /* N/A */
Expand Down
8 changes: 8 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ CSRCS += $(if $(wildcard romfs_boot.c), romfs_boot.c, romfs_stub.c)
endif
endif

ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += qemu_rv_autoleds.c
endif

ifeq ($(CONFIG_USERLED),y)
CSRCS += qemu_rv_userleds.c
endif

include $(TOPDIR)/boards/Board.mk

# don't use single-colon targets as they may coflict with those included ones.
Expand Down
14 changes: 14 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/src/qemu_rv_appinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
#include "riscv_internal.h"
#include "romfs.h"

#ifdef CONFIG_USERLED
#include <nuttx/leds/userled.h>
#endif

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -181,6 +185,16 @@ void board_late_initialize(void)
mount(NULL, "/proc", "procfs", 0, NULL);

#endif

#ifdef CONFIG_USERLED
/* Register the LED driver */

int ret = userled_lower_initialize("/dev/userleds");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret);
}
#endif
}

#ifdef CONFIG_BOARDCTL_POWEROFF
Expand Down
145 changes: 145 additions & 0 deletions boards/risc-v/qemu-rv/rv-virt/src/qemu_rv_autoleds.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/****************************************************************************
* boards/risc-v/qemu-rv/rv-virt/src/qemu_rv_autoleds.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>

#include <stdint.h>
#include <stdbool.h>
#include <debug.h>

#include <sys/param.h>

#include <nuttx/board.h>
#include <arch/board/board.h>

#include "chip.h"

#ifdef CONFIG_ARCH_LEDS

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: board_autoled_initialize
*
* Description:
* 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_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_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
* conventions for "Microprocessor-Specific Interfaces" or the "Board-
* Specific Interfaces" as described above.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/

void board_autoled_initialize(void)
{
}

/****************************************************************************
* Name: board_autoled_on
*
* Description:
* Set the LED configuration into the ON condition for the state provided
* by the led parameter. This may be one of:
*
* LED_STARTED NuttX has been started
* LED_HEAPALLOCATE Heap has been allocated
* LED_IRQSENABLED Interrupts enabled
* LED_STACKCREATED Idle stack created
* LED_INIRQ In an interrupt
* LED_SIGNAL In a signal handler
* LED_ASSERTION An assertion failed
* LED_PANIC The system has crashed
* LED_IDLE MCU is in sleep mode
*
* Where these values are defined in a board-specific way in the standard
* board.h header file exported by every architecture.
*
* Input Parameters:
* led - Identifies the LED state to put in the ON state (which may or may
* not equate to turning an LED on)
*
* Returned Value:
* None
*
****************************************************************************/

void board_autoled_on(int led)
{
/* This stub is required for supporting User LEDs */

UNUSED(led);
}

/****************************************************************************
* Name: board_autoled_off
*
* Description:
* Set the LED configuration into the OFF condition for the state provided
* by the led parameter. This may be one of:
*
* LED_INIRQ Leaving an interrupt
* LED_SIGNAL Leaving a signal handler
* LED_ASSERTION Recovering from an assertion failure
* LED_PANIC The system has crashed (blinking).
* LED_IDLE MCU is not in sleep mode
*
* Where these values are defined in a board-specific way in the standard
* board.h header file exported by every architecture.
*
* Input Parameters:
* led - Identifies the LED state to put in the OFF state (which may or may
* not equate to turning an LED off)
*
* Returned Value:
* None
*
****************************************************************************/

void board_autoled_off(int led)
{
/* This stub is required for supporting User LEDs */

UNUSED(led);
}

#endif /* CONFIG_ARCH_LEDS */
Loading

0 comments on commit feb7160

Please sign in to comment.