diff --git a/.clang-tidy b/.clang-tidy index b7b219b..df603e2 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,72 +4,69 @@ WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false CheckOptions: - - # naming - readability-identifier-naming.StructCase: 'lower_case' - readability-identifier-naming.MemberCase: 'lower_case' - readability-identifier-naming.ConstantCase: 'lower_case' - readability-identifier-naming.ConstantParameterCase: 'lower_case' - readability-identifier-naming.ConstantPointerParameterCase: 'lower_case' - readability-identifier-naming.EnumCase: 'lower_case' - readability-identifier-naming.EnumConstantCase: 'UPPER_CASE' - readability-identifier-naming.FunctionCase: 'lower_case' - readability-identifier-naming.GlobalConstantCase: 'lower_case' - readability-identifier-naming.GlobalConstantPointerCase: 'lower_case' - readability-identifier-naming.GlobalFunctionCase: 'lower_case' - readability-identifier-naming.GlobalPointerCase: 'lower_case' - readability-identifier-naming.GlobalVariableCase: 'lower_case' - readability-identifier-naming.LocalConstantCase: 'lower_case' - readability-identifier-naming.LocalConstantPointerCase: 'lower_case' - readability-identifier-naming.FunctionCase: 'lower_case' - readability-identifier-naming.LocalPointerCase: 'lower_case' - readability-identifier-naming.LocalVariableCase: 'lower_case' - # readability-identifier-naming.MacroDefinitionCase: ['lower_case','UPPER_CASE'] # We cannot use that as we have variable macro casing - readability-identifier-naming.ParameterCase: 'lower_case' - readability-identifier-naming.ParameterPackCase: 'lower_case' - readability-identifier-naming.PointerParameterCase: 'lower_case' - readability-identifier-naming.StaticConstantCase: 'lower_case' - readability-identifier-naming.StaticVariableCase: 'lower_case' - readability-identifier-naming.TypeAliasCase: 'lower_case' - readability-identifier-naming.TypedefCase: 'lower_case' - readability-identifier-naming.TypedefIgnoredRegexp: 'va_list' # regex of accepted violations - readability-identifier-naming.FunctionCase: 'lower_case' - readability-identifier-naming.UnionCase: 'lower_case' - readability-identifier-naming.VariableCase: 'lower_case' + 'readability-identifier-naming.StructCase': 'lower_case' + 'readability-identifier-naming.MemberCase': 'lower_case' + 'readability-identifier-naming.ConstantCase': 'lower_case' + 'readability-identifier-naming.ConstantParameterCase': 'lower_case' + 'readability-identifier-naming.ConstantPointerParameterCase': 'lower_case' + 'readability-identifier-naming.EnumCase': 'lower_case' + 'readability-identifier-naming.EnumConstantCase': 'UPPER_CASE' + 'readability-identifier-naming.FunctionCase': 'lower_case' + 'readability-identifier-naming.GlobalConstantCase': 'lower_case' + 'readability-identifier-naming.GlobalConstantPointerCase': 'lower_case' + 'readability-identifier-naming.GlobalFunctionCase': 'lower_case' + 'readability-identifier-naming.GlobalPointerCase': 'lower_case' + 'readability-identifier-naming.GlobalVariableCase': 'lower_case' + 'readability-identifier-naming.LocalConstantCase': 'lower_case' + 'readability-identifier-naming.LocalConstantPointerCase': 'lower_case' + 'readability-identifier-naming.FunctionCase': 'lower_case' + 'readability-identifier-naming.LocalPointerCase': 'lower_case' + 'readability-identifier-naming.LocalVariableCase': 'lower_case' + + # readability-identifier-naming.MacroDefinitionCase: ['lower_case','UPPER_CASE'] # We cannot use that as we have variable macro casing + 'readability-identifier-naming.ParameterCase': 'lower_case' + 'readability-identifier-naming.ParameterPackCase': 'lower_case' + 'readability-identifier-naming.PointerParameterCase': 'lower_case' + 'readability-identifier-naming.StaticConstantCase': 'lower_case' + 'readability-identifier-naming.StaticVariableCase': 'lower_case' + 'readability-identifier-naming.TypeAliasCase': 'lower_case' + 'readability-identifier-naming.TypedefCase': 'lower_case' + 'readability-identifier-naming.TypedefIgnoredRegexp': 'va_list' # regex of accepted violations + 'readability-identifier-naming.FunctionCase': 'lower_case' + 'readability-identifier-naming.UnionCase': 'lower_case' + 'readability-identifier-naming.VariableCase': 'lower_case' + + # Types have no prefix: + 'readability-identifier-naming.StructPrefix': '' + 'readability-identifier-naming.UnionPrefix': '' + 'readability-identifier-naming.EnumPrefix': '' + 'readability-identifier-naming.TypedefPrefix': '' + + # Types have an '_t' suffix: + 'readability-identifier-naming.StructSuffix': '_t' + 'readability-identifier-naming.UnionSuffix': '_t' + 'readability-identifier-naming.EnumSuffix': '_t' + 'readability-identifier-naming.TypedefSuffix': '_t' - # Types have no prefix: - readability-identifier-naming.StructPrefix: '' - readability-identifier-naming.UnionPrefix: '' - readability-identifier-naming.EnumPrefix: '' - readability-identifier-naming.TypedefPrefix: '' - - # Types have an '_t' suffix: - readability-identifier-naming.StructSuffix: '_t' - readability-identifier-naming.UnionSuffix: '_t' - readability-identifier-naming.EnumSuffix: '_t' - readability-identifier-naming.TypedefSuffix: '_t' - - - - # defined by default - llvm-else-after-return.WarnOnConditionVariables: 'false' - modernize-loop-convert.MinConfidence: reasonable - modernize-replace-auto-ptr.IncludeStyle: llvm - cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false' - google-readability-namespace-comments.ShortNamespaceLines: '10' - cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;' - cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false' - cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU' - google-readability-braces-around-statements.ShortStatementLines: '1' - cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true' - google-readability-namespace-comments.SpacesBeforeComments: '2' - modernize-loop-convert.MaxCopySize: '16' - modernize-pass-by-value.IncludeStyle: llvm - modernize-use-nullptr.NullMacros: 'NULL' - llvm-qualified-auto.AddConstToQualified: 'false' - modernize-loop-convert.NamingStyle: CamelCase - llvm-else-after-return.WarnOnUnfixable: 'false' - google-readability-function-size.StatementThreshold: '800' + # defined by default + llvm-else-after-return.WarnOnConditionVariables: 'false' + modernize-loop-convert.MinConfidence: reasonable + modernize-replace-auto-ptr.IncludeStyle: llvm + cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false' + google-readability-namespace-comments.ShortNamespaceLines: '10' + cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;' + cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false' + cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU' + google-readability-braces-around-statements.ShortStatementLines: '1' + cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true' + google-readability-namespace-comments.SpacesBeforeComments: '2' + modernize-loop-convert.MaxCopySize: '16' + modernize-pass-by-value.IncludeStyle: llvm + modernize-use-nullptr.NullMacros: 'NULL' + llvm-qualified-auto.AddConstToQualified: 'false' + modernize-loop-convert.NamingStyle: CamelCase + llvm-else-after-return.WarnOnUnfixable: 'false' + google-readability-function-size.StatementThreshold: '800' # lower_case, diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0736f8f..1e82bac 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -39,3 +39,14 @@ jobs: - name: Build Statistics run: | riscv32-unknown-elf-size -B build/main.elf + + - name: Create firmware image + run: ./packimage.py + + - name: Upload + uses: actions/upload-artifact@v3 + with: + name: Firmware + path: | + build/main.elf + build/main.bin diff --git a/.github/workflows/guidelines.yaml b/.github/workflows/guidelines.yaml new file mode 100644 index 0000000..5e91935 --- /dev/null +++ b/.github/workflows/guidelines.yaml @@ -0,0 +1,54 @@ +name: Code Check + +on: + push: + branches: ['main'] + pull_request: + branches: ['main', 'format_tooling'] + +jobs: + validate-format: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + + - name: Run clang-format style check + uses: jidicula/clang-format-action@v4.11.0 + with: + clang-format-version: '16' + check-path: '.' + + static-analysis: + runs-on: ubuntu-22.04 + + # might be enabled in the future: + # https://github.com/marketplace/actions/clang-tidy-review + + steps: + - uses: actions/checkout@v3 + + - name: Install clang-tidy + run: | + # see https://apt.llvm.org/ + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 16 + + sudo apt-get install -y clang-tidy-16 + + - name: Fetch & install RISC-V GNU Compiler Toolchain + run: | + curl -Lo riscv32-elf-ubuntu-22.04-nightly.tar.gz 'https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.06.09/riscv32-elf-ubuntu-22.04-nightly-2023.06.09-nightly.tar.gz' + tar -xf riscv32-elf-ubuntu-22.04-nightly.tar.gz + echo "${PWD}/riscv/bin" >> $GITHUB_PATH + + - name: Configure CMake + run: cmake -B "${{github.workspace}}/build" -DCMAKE_BUILD_TYPE=Debug -DTARGET_ARCH=rv32imac + + - name: Run clang-tidy + run: | + echo "scan the following files:" + jq -r '.[].file' build/compile_commands.json | grep '\.[ch]$' + clang-tidy --version + clang-tidy -p build $(jq -r '.[].file' build/compile_commands.json | grep '\.[ch]$') --warnings-as-errors="*" diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d2a2a3..5b419a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,18 +7,28 @@ cmake_minimum_required(VERSION 3.10.0) set(CMAKE_C_COMPILER riscv32-unknown-elf-gcc) set(CMAKE_C_COMPILER_FORCED true) +set(target_arch rv32imac_zifencei_zicsr) +if(DEFINED TARGET_ARCH) + set(target_arch "${TARGET_ARCH}") +endif() + +set(target_abi ilp32) +if(DEFINED TARGET_ABI) + set(target_abi "${TARGET_ABI}") +endif() + set(common_compiler_flags - -flto # Optimize the code at link time, on the whole program. - -ffreestanding # We do not compile against an OS. - -march=rv32imac_zifencei_zicsr # Selects the target CPU. - -mabi=ilp32 - -nodefaultlibs # Do not link any default libraries like libgcc or libc. - -O2 # Optimize the code. - -ggdb # Generate debug information in default extended format. - -fsanitize=undefined # Adds sanitizer for undefined behaviour. - -fsanitize-undefined-trap-on-error # Invoke a trap instruction instead of calling into the UBsan runtime. - -Werror=return-type # Error when a function doesn't return a value, but declares to do so. - -Wall -Wextra # Ramp up warning level. + -flto # Optimize the code at link time, on the whole program. + -ffreestanding # We do not compile against an OS. + -march=${target_arch} # Selects the target CPU. + -mabi=${target_abi} # Selects target ABI + -nodefaultlibs # Do not link any default libraries like libgcc or libc. + -O2 # Optimize the code. + -ggdb # Generate debug information in default extended format. + -fsanitize=undefined # Adds sanitizer for undefined behaviour. + -fsanitize-undefined-trap-on-error # Invoke a trap instruction instead of calling into the UBsan runtime. + -Werror=return-type # Error when a function doesn't return a value, but declares to do so. + -Wall -Wextra # Ramp up warning level. ) # we must pass the same options to GCC and LD when using LTO, as the linker will actually do the codegen @@ -33,8 +43,8 @@ project(badgeros C ASM) # Define executable file. set(target main.elf) add_executable(${target} - ${CMAKE_CURRENT_LIST_DIR}/src/log.c - ${CMAKE_CURRENT_LIST_DIR}/src/main.c + ${CMAKE_CURRENT_LIST_DIR}/src/log.c + ${CMAKE_CURRENT_LIST_DIR}/src/main.c ) target_include_directories(${target} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) diff --git a/packimage.py b/packimage.py index f2cdb5b..16648c1 100755 --- a/packimage.py +++ b/packimage.py @@ -4,7 +4,7 @@ import os # Use objcopy to extract the image from the ELF file. -os.system("riscv32-unknown-linux-gnu-objcopy -O binary build/main.elf build/main.bin") +os.system("riscv32-unknown-elf-objcopy -O binary build/main.elf build/main.bin") # Open the generated file for appending a checksum. fd = open("build/main.bin", "+ab") @@ -26,15 +26,17 @@ fd.seek(1, 0) seg_num = fd.read(1)[0] + def readword(): raw = fd.read(4) return raw[0] + (raw[1] << 8) + (raw[2] << 16) + (raw[3] << 24) + # Compute checksum. fd.seek(24) for _ in range(seg_num): seg_laddr = readword() - seg_len = readword() + seg_len = readword() for _ in range(seg_len): xsum_state ^= fd.read(1)[0] diff --git a/port/esp32c6/src/clkconfig.c b/port/esp32c6/src/clkconfig.c index f82d474..1e0021d 100644 --- a/port/esp32c6/src/clkconfig.c +++ b/port/esp32c6/src/clkconfig.c @@ -208,10 +208,10 @@ static uint32_t clk_compute_div(uint32_t source_hz, uint32_t target_hz) { uint_fast8_t closest_num = 0; // Perform a search. - for (uint_fast8_t num = 2; num < 64; num++) { + for (uint_fast8_t num = 2; num < 64; num++) { uint_fast8_t den = (fractional * num) >> 24; uint32_t frac = (den << 24) / num; - int32_t err = frac - fractional; + int32_t err = (int32_t)(frac - fractional); if (err < 0) err = -err; if (err < closest_err) { closest_err = err; diff --git a/src/log.c b/src/log.c index f71d945..bdf5eb6 100644 --- a/src/log.c +++ b/src/log.c @@ -9,7 +9,7 @@ typedef __builtin_va_list va_list; #define va_end(x) __builtin_va_end(x) #define va_arg(x,y) __builtin_va_arg(x,y) -#define isvalidlevel(level) (level >= 0 && level < 5) +#define isvalidlevel(level) ((level) >= 0 && (level) < 5) static const char *prefix[] = { "FATAL ", diff --git a/src/main.c b/src/main.c index c61acdd..3214ebc 100644 --- a/src/main.c +++ b/src/main.c @@ -38,6 +38,6 @@ void main() { io_pull(NULL, 22, IO_PULL_UP); while (1) { int64_t now = time_us(); - io_write(NULL, 15, (now / 1000000) & 1 ^ io_read(NULL, 22)); + io_write(NULL, 15, ((now / 1000000) & 1) ^ io_read(NULL, 22)); } }