freertos: release the generic version source code

freertos runs on the second core (small one) of the CPU
This commit is contained in:
carbon
2023-10-19 14:31:43 +08:00
parent e266c53351
commit ca03037500
2166 changed files with 694154 additions and 58149 deletions

View File

@ -0,0 +1,3 @@
#!/bin/bash -eu
NO_COVERAGE=1 EXTRA_VERIFAST_ARGS=-stats make queue list | grep overhead: | sort | uniq

View File

@ -0,0 +1,20 @@
# Generate callgraph
## Requirements
- python3
- pycparser
- graphviz/dot
- [inconsolata](https://fonts.google.com/specimen/Inconsolata)
## Instructions
```
cd scripts
git clone https://github.com/eliben/pycparser.git #< you need this for pycparser's libc headers even if pycparser is installed
mkdir fake_include
touch fake_include/threading.h
gcc -E -I pycparser/utils/fake_libc_include/ -I ../include/ -I fake_include/ ../queue/*.c > out.pp
./callgraph.py > out.dot
dot -Nfontname=inconsolata -Tpng -o callgraph.png out.dot
```

View File

@ -0,0 +1,83 @@
#!/usr/bin/env python3
from __future__ import print_function
from pycparser import c_parser, c_ast, parse_file
import sys
ignore_callee = set(['mutex_acquire', 'mutex_release'])
ignore_caller = set(['caller_reinstates_queue_predicate'])
proven = [
'prvCopyDataFromQueue',
'prvCopyDataToQueue',
'prvInitialiseNewQueue',
'prvIsQueueEmpty',
'prvIsQueueFull',
'prvLockQueue',
'prvUnlockQueue',
'uxQueueMessagesWaiting',
'uxQueueSpacesAvailable',
'vQueueDelete',
'xQueueGenericCreate',
'xQueueGenericReset',
'xQueueGenericSend',
'xQueueGenericSendFromISR',
'xQueueIsQueueEmptyFromISR',
'xQueueIsQueueFullFromISR',
'xQueuePeek',
'xQueuePeekFromISR',
'xQueueReceive',
'xQueueReceiveFromISR',
]
modeled = [
'setInterruptMask',
'clearInterruptMask',
'setInterruptMaskFromISR',
'clearInterruptMaskFromISR',
'vTaskSuspendAll',
'xTaskResumeAll',
]
CALLMAP = set()
class FuncCallVisitor(c_ast.NodeVisitor):
def __init__(self, caller):
self.caller = caller
def visit_FuncCall(self, node):
callee = node.name.name
if callee not in ignore_callee:
CALLMAP.add((node.name.name, self.caller))
class FuncDefVisitor(c_ast.NodeVisitor):
def visit_FuncDef(self, node):
caller = node.decl.name
if caller in ignore_caller:
return
if caller.startswith('wrapper_'):
caller = caller[8:]
v = FuncCallVisitor(caller)
v.visit(node)
def show_func_calls(filename):
ast = parse_file(filename, use_cpp=False)
v = FuncDefVisitor()
v.visit(ast)
if __name__ == "__main__":
filename = 'out.pp'
show_func_calls(filename)
print('digraph G {')
print(' rankdir=LR;')
print(' node [style = filled, colorscheme = set13;];')
for f in proven:
print(' %s [fillcolor = 3];' % f)
for f in modeled:
print(' %s [fillcolor = 2];' % f)
for (callee, caller) in CALLMAP:
print(' %s -> %s;' % (callee, caller))
print('}')

View File

@ -0,0 +1,42 @@
# Generate diffs between FreeRTOS source and proofs
## Requirements
- python3
- ctags 5.8
- diff 3.4+
- [diff2html](https://diff2html.xyz/)
## Instructions
The following will extract per-function files from the original FreeRTOS source
implementation and the proof directory.
```
cd scripts
./generate_diff_files.sh
# will extract to ./FreeRTOS-Kernel/generated and ./queue/generated and ./list/generated
```
Then use `diff` for a side-by-side comparison. Note that the `--color=always`
flag needs v3.4+:
```
diff --color=always --width=$COLUMNS --suppress-common-lines --side-by-side FreeRTOS-Kernel/generated queue/generated | less -r
diff --color=always --width=$COLUMNS --suppress-common-lines --side-by-side FreeRTOS-Kernel/generated list/generated | less -r
```
Or generate a html report using `diff2html`:
```
diff -u FreeRTOS-Kernel/generated queue/generated | diff2html -i stdin
diff -u FreeRTOS-Kernel/generated list/generated | diff2html -i stdin
```
The expectation is that the proofs make minimal changes to the original source
implementation in the form of:
- VeriFast annotations `/*@...@*/` and `//*...`
- Additional comments explaining the proof `/*...*/`
- Flagged changes within `#if[n]def VERIFAST`

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python3
from __future__ import print_function
import sys
from enum import Enum
class Extractor(object):
@staticmethod
def __parse_ctags(tags_filename):
def convert_excmd(excmd):
assert excmd.endswith(';"')
linenum = excmd[:-2] # remove ';"'
return int(linenum)
result = {}
with open(tags_filename) as f:
for line in f:
if line.startswith('!'):
continue
parts = line.split('\t')
funcname = parts[0]
funcfile = parts[1]
linenum = convert_excmd(parts[2])
result[funcname] = (funcfile, linenum)
return result
def __init__(self, tags_filename):
self.map = Extractor.__parse_ctags(tags_filename)
class State(Enum):
INIT = 0
HEAD = 1
BODY = 2
def text_of_funcname(self, funcname):
if funcname not in self.map:
return []
funcfile, linenum = self.map[funcname]
result = []
state, bracecount = Extractor.State.INIT, 0
with open(funcfile) as f:
for i, line in enumerate(f, start=1): # ctags counts linenums from 1
if state == Extractor.State.INIT and linenum <= i:
state = Extractor.State.HEAD
if state == Extractor.State.HEAD:
result.append(line)
lbrace = line.count('{')
rbrace = line.count('}')
bracecount += lbrace
bracecount -= rbrace
if '{' in line:
state = Extractor.State.BODY
continue
if state == Extractor.State.BODY:
result.append(line)
lbrace = line.count('{')
rbrace = line.count('}')
bracecount += lbrace
bracecount -= rbrace
if bracecount == 0:
break
return result
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: %s <tagfile> <funcname>" % sys.argv[0])
sys.exit(1)
tag_filename = sys.argv[1]
funcname = sys.argv[2]
extractor = Extractor('tags')
result = extractor.text_of_funcname(funcname)
print(''.join(result))
sys.exit(0)

View File

@ -0,0 +1,70 @@
#!/bin/bash -eu
QUEUE_FUNCS=(
prvCopyDataFromQueue
prvCopyDataToQueue
prvInitialiseNewQueue
prvIsQueueEmpty
prvIsQueueFull
prvUnlockQueue
uxQueueMessagesWaiting
uxQueueSpacesAvailable
vQueueDelete
xQueueGenericCreate
xQueueGenericReset
xQueueGenericSend
xQueueGenericSendFromISR
xQueueIsQueueEmptyFromISR
xQueueIsQueueFullFromISR
xQueuePeek
xQueuePeekFromISR
xQueueReceive
xQueueReceiveFromISR
)
LIST_FUNCS=(
uxListRemove
vListInitialise
vListInitialiseItem
vListInsertEnd
vListInsert
)
if [ ! -d "FreeRTOS-Kernel" ]; then
git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git
fi
pushd FreeRTOS-Kernel > /dev/null
rm -rf tags generated
ctags --excmd=number queue.c
mkdir generated
for f in ${QUEUE_FUNCS[@]}; do
../extract.py tags $f > generated/$f.c
done
ctags --excmd=number list.c
for f in ${LIST_FUNCS[@]}; do
../extract.py tags $f > generated/$f.c
done
popd > /dev/null
echo "created: FreeRTOS-Kernel/generated"
ln -fs ../queue .
pushd queue > /dev/null
rm -rf tags generated
ctags --excmd=number *.c
mkdir generated
for f in ${QUEUE_FUNCS[@]}; do
../scripts/extract.py tags $f > generated/$f.c
done
popd > /dev/null
echo "created: queue/generated"
ln -fs ../list .
pushd list > /dev/null
rm -rf tags generated
ctags --excmd=number *.c
mkdir generated
for f in ${LIST_FUNCS[@]}; do
../scripts/extract.py tags $f > generated/$f.c
done
popd > /dev/null
echo "created: list/generated"