Close

Creating debug/trace and logging macros

A project log for Sparkfun RED-V bare metal

I wanted to learn RISC-V, not on an emulator, but on a real bare metal RISC-V processor. Even though Sparkfun RED-V is no longer produced.

olaf-baeyensOlaf Baeyens 10/27/2024 at 17:370 Comments

We need some kind of debugging/logging/tracing when we build our OS

So we need to define in constants.cs we now defined logging levels

# Debugging Levels =====================================================

# Define constants for debug levels
.set DEBUG_LEVEL_RELEASE, 0 
.set DEBUG_LEVEL_NORMAL, 1 
.set DEBUG_LEVEL_VERBOSE, 2 

# Set default DEBUG_LEVEL if not defined
.ifndef DEBUG_LEVEL
    .set DEBUG_LEVEL, DEBUG_LEVEL_NORMAL
.endif

# Tracing Levels =======================================================

.set TRACE_LEVEL_NO_TRACING, 0
.set TRACE_LEVEL_TRACING, 1

# Set default TRACE_LEVEL if not defined
.ifndef TRACE_LEVEL
    .set TRACE_LEVEL, TRACE_LEVEL_TRACING
.endif

# Logging Levels =======================================================

.set LOG_LEVEL_NONE, 0
.set LOG_LEVEL_INFO, 1
.set LOG_LEVEL_WARN, 2
.set LOG_LEVEL_ERROR, 3
.set LOG_LEVEL_DEBUG, 4
.set LOG_LEVEL_TRACE, 5

# Set default LOG_LEVEL if not defined
.ifndef LOG_LEVEL
    .set LOG_LEVEL, LOG_LEVEL_INFO
.endif

Then we define the debug macro.

(I think we need to do some push and pop of registers in the future but for now this is enough.)

# debug-macros.s
.include "./src/include/constants.s"

# ===============================================================
# DEBUG message_ptr 
# ===============================================================
.if DEBUG_LEVEL > 0
    .macro DEBUG message_ptr
        la      a0, STRINGS_DEBUG_START_MSG
        jal     puts    
        la      a0, \message_ptr
        jal     puts
        la      a0, CRLF
        jal     puts            
    .endm
.else
    .macro DEBUG message_ptr
        # No operation when DEBUG is disabled
    .endm   
.endif

And we are creating logging macros:

(I think we need to do some push and pop of registers in the future but for now this is enough.)

# -----------------------------------------------------------------------
# Generic LOG macro
# -----------------------------------------------------------------------
.macro LOG message_ptr, level
    # Only log if the current LOG_LEVEL is greater than or equal to the specified level
    .if LOG_LEVEL >= \level
        la      a0, STRINGS_LOG_START_MSG
        jal     puts    
        la      a0, \message_ptr
        jal     puts
        la      a0, CRLF
        jal     puts
    .endif
.endm

# ===============================================================
# Specific log level macros for convenience
# ===============================================================

# LOG_INFO message_ptr
.macro LOG_INFO message_ptr
    .if LOG_LEVEL >= LOG_LEVEL_INFO
        LOG \message_ptr, LOG_LEVEL_INFO
    .endif
.endm

# LOG_WARN message_ptr
.macro LOG_WARN message_ptr
    .if LOG_LEVEL >= LOG_LEVEL_WARN
        LOG \message_ptr, LOG_LEVEL_WARN
    .endif
.endm

# LOG_ERROR message_ptr
.macro LOG_ERROR message_ptr
    .if LOG_LEVEL >= LOG_LEVEL_ERROR
        LOG \message_ptr, LOG_LEVEL_ERROR
    .endif
.endm

 Now we can use it like this:

    LOG_INFO            VERSION_INFO

    LOG_INFO            STRINGS_TEST_START_MSG
    LOG_INFO            SEPARATOR_DOUBLE_LINE

    LOG_INFO            STRINGS_TEST_STRCPY_MSG
    STRCPY              scratch1024, STRING_TEST_MSG
    LOG_INFO            scratch1024

Discussions