Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test code for RT-Thread #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os
from building import *

objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)

for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))

Return('objs')
49 changes: 49 additions & 0 deletions Source/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
menu "CMSIS-NN submodule config"

menuconfig PKG_USING_CMSIS_NN
bool "Enable CMSIS-NN pacakge"
default n

if PKG_USING_CMSIS_NN
config CMSIS_NN_ACTIVATION
bool "Activation functions"
default y

config CMSIS_NN_BASICMATHSNN
bool "Basic math functions"
default y

config CMSIS_NN_CONCATENATION
bool "Concatenation functions"
default y

config CMSIS_NN_CONVOLUTION
bool "Convolution functions"
default y

config CMSIS_NN_FULLYCONNECTED
bool "Fully connection functions"
default y

config CMSIS_NN_LSTM
bool "LSTM functions"
default y

config CMSIS_NN_POOLING
bool "Pooling functions"
default y

config CMSIS_NN_RESHAPE
bool "Reshape functions"
default y

config CMSIS_NN_SOFTMAX
bool "Softmax functions"
default y

config CMSIS_NN_SVDF
bool "SVDF functions"
default y
endif

endmenu
69 changes: 69 additions & 0 deletions Source/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import os
from building import *

# enable all module by default
ACTIVATION = True
BASICMATHSNN = True
CONCATENATION = True
CONVOLUTION = True
FULLYCONNECTED = True
LSTM = True
POOLING = True
RESHAPE = True
SOFTMAX = True
SVDF = True

# CMSIS-NN papckage Kconfig option value
USE_CMSIS_NN_CONFIG = GetDepend(['PKG_USING_CMSIS_NN'])

# Kconfig sourced, and CMSIS-NN package enabled
if USE_CMSIS_NN_CONFIG:
ACTIVATION = GetDepend(['CMSIS_NN_ACTIVATION'])
BASICMATHSNN = GetDepend(['CMSIS_NN_BASICMATHSNN'])
CONCATENATION = GetDepend(['CMSIS_NN_CONCATENATION'])
CONVOLUTION = GetDepend(['CMSIS_NN_CONVOLUTION'])
FULLYCONNECTED = GetDepend(['CMSIS_NN_FULLYCONNECTED'])
LSTM = GetDepend(['CMSIS_NN_LSTM'])
POOLING = GetDepend(['CMSIS_NN_POOLING'])
RESHAPE = GetDepend(['CMSIS_NN_RESHAPE'])
SOFTMAX = GetDepend(['CMSIS_NN_SOFTMAX'])
SVDF = GetDepend(['CMSIS_NN_SVDF'])

# Always needed if any other module above is on.
NNSUPPORT = ACTIVATION or BASICMATHSNN or CONCATENATION or CONVOLUTION or \
FULLYCONNECTED or LSTM or POOLING or RESHAPE or SOFTMAX or SVDF

submodules = (
(ACTIVATION, 'ActivationFunctions'),
(BASICMATHSNN, 'BasicMathFunctions'),
(CONCATENATION, 'ConcatenationFunctions'),
(CONVOLUTION, 'ConvolutionFunctions'),
(FULLYCONNECTED, 'FullyConnectedFunctions'),
(LSTM, 'LSTMFunctions'),
(NNSUPPORT, 'NNSupportFunctions'),
(POOLING, 'PoolingFunctions'),
(RESHAPE, 'ReshapeFunctions'),
(SOFTMAX, 'SoftmaxFunctions'),
(SVDF, 'SVDFunctions')
)

# print('USE_CMSIS_NN_CONFIG=', USE_CMSIS_NN_CONFIG)
# print('submodules=', submodules)

cwd = GetCurrentDir()

CPPPATH = [cwd + '/../Include']
SOURCES = []

for m in submodules:
if m[0]:
SOURCES += Glob(m[1] + '/*.c')

LOCAL_CCFLAGS = ["-Ofast"]

objs = DefineGroup(name='CMSIS-NN', src=SOURCES, depend=[''],
CPPPATH=CPPPATH,
LOCAL_CCFLAGS=LOCAL_CCFLAGS,
)

Return('objs')
12 changes: 12 additions & 0 deletions Tests/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os
from building import *

objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)

for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))

Return('objs')
12 changes: 12 additions & 0 deletions Tests/UnitTest/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os
from building import *

objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)

for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))

Return('objs')
12 changes: 12 additions & 0 deletions Tests/UnitTest/TestCases/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os
from building import *

objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)

for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))

Return('objs')
5 changes: 5 additions & 0 deletions Tests/UnitTest/fix_testCode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
grep --color -lr 'setUp' TestCases/ | xargs sed -i 's|void setUp(void)|__attribute__((weak)) void setUp(void)|g'
grep --color -lr 'tearDown' TestCases/ | xargs sed -i 's|void tearDown(void)|__attribute__((weak)) void tearDown(void)|g'
grep --color -lr 'resetTest' TestCases/ | xargs sed -i 's|void resetTest(void)|__attribute__((weak)) void resetTest(void)|g'
grep --color -lr 'verifyTest' TestCases/ | xargs sed -i 's|void verifyTest(void)|__attribute__((weak)) void verifyTest(void)|g'
2 changes: 2 additions & 0 deletions Tests/UnitTest/fix_testData.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
grep --color -lr '^const ' TestCases/TestData/ | xargs sed -i 's|^const |static const |g'
55 changes: 54 additions & 1 deletion Tests/UnitTest/unittest_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,50 @@ def is_func_to_parse(func):
f.write(line)


COMMAND_CODE_TEMPLATE='''/* AUTOGENERATED FILE. DO NOT EDIT. */
#include <finsh.h>

extern int {runner_name}(void);

MSH_CMD_EXPORT_ALIAS({runner_name}, {cmd_name}, {runner_name});
'''

COMMAND_SCONS_TEMPLATE = '''#AUTOGENERATED FILE. DO NOT EDIT.
import os
from building import *

objs = []
cwd = GetCurrentDir()

SOURCES = [
{src_list}
]

LOCAL_CCFLAGS = [
'-Dmalloc=rt_malloc',
'-Dfree=rt_free',
'-include rt-thread.h'
]

objs = DefineGroup(name='Unity', src=SOURCES, depend=[''], CPPPATH=[])

Return('objs')
'''


def generate_command_code(runner_file, runner_name):
cmd_name = runner_name.replace('unity_test_arm', '').replace('_runner', '')
cmd_code = COMMAND_CODE_TEMPLATE.format(runner_name=runner_name, cmd_name=cmd_name)
with open(runner_file, 'tw+', encoding='utf-8') as f:
f.write(cmd_code)


def generate_command_scons(scons_file, source_list):
scons_code = COMMAND_SCONS_TEMPLATE.format(src_list=',\n '.join([f"'{src}'" for src in source_list]))
with open(scons_file, 'wt+', encoding='utf-8') as f:
f.write(scons_code)


def parse_tests(targets, main_tests, specific_test=None):
"""
Generate test runners, extract and return path to unit test(s).
Expand Down Expand Up @@ -449,7 +493,16 @@ def parse_tests(targets, main_tests, specific_test=None):
os.remove(old_files)

# Generate test runners
run_command('ruby ' + UNITY_PATH + 'auto/generate_test_runner.rb ' + test_code + ' ' + test_runner)
runner_name = os.path.basename(test_runner).replace('.c', '')
cmd_file = test_runner.replace('unity_test', 'finsh_cmd')
scons_file = os.path.dirname(test_code) + '/../SConscript'
src_list = [test_code, test_runner, cmd_file]
src_list = [src.replace(f'{directory}/{dir}/', '') for src in src_list ]
print(f'EXEC: ruby {UNITY_PATH}auto/generate_test_runner.rb --main_name={runner_name} {test_code} {test_runner}')
run_command(f'ruby {UNITY_PATH}auto/generate_test_runner.rb --main_name={runner_name} {test_code} {test_runner}')
generate_command_code(cmd_file, runner_name)
generate_command_scons(scons_file, src_list)

test_found = parse_test(test_runner, targets)
if not test_found:
return False
Expand Down