kopia lustrzana https://github.com/SP8EBC/ParaTNC
Porównaj commity
16 Commity
Autor | SHA1 | Data |
---|---|---|
Mateusz Lubecki | f93c4e553e | |
Mateusz Lubecki | 6a0766e22c | |
Mateusz Lubecki | 73ab9cac33 | |
Mateusz Lubecki | 012e2b3557 | |
Mateusz Lubecki | 428f6a2360 | |
Mateusz Lubecki | 15829704be | |
Mateusz Lubecki | 9b52612eec | |
Mateusz Lubecki | d5614dbf53 | |
Mateusz Lubecki | ef26fd94e7 | |
Mateusz Lubecki | f62de2051a | |
SP8EBC | 4ced3c5b39 | |
Mateusz Lubecki | 733dbfa13b | |
Mateusz Lubecki | 654540fcf3 | |
Mateusz Lubecki | 228a64e5b7 | |
Mateusz Lubecki | b642c3c540 | |
Mateusz Lubecki | ee541a54dc |
|
@ -352,6 +352,7 @@
|
|||
<listOptionValue builtIn="false" value="PARATNC_HWREV_B"/>
|
||||
<listOptionValue builtIn="false" value="PARATNC_HWREV_C"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other.994195951" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other" useByScannerDiscovery="true" value="-fstack-usage -fdump-rtl-dfinish" valueType="string"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.29354374" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1656265940" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler">
|
||||
|
@ -415,7 +416,7 @@
|
|||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat.1654419641" name="Use float with nano printf (-u _printf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.1892757950" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys.1858899549" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap.826060236" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap.826060236" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap" value="false" valueType="boolean"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.1803255576" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
@ -493,7 +494,7 @@
|
|||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.useprintffloat.1403039114" name="Use float with nano printf (-u _printf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.useprintffloat" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref.139846170" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys.1761390492" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printmap.1092992084" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printmap" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printmap.1092992084" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printmap" value="false" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1243003593" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.233822233"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.2101502496" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.753718364"/>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="842559031985696342" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="871033396245946614" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
@ -16,7 +16,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="813754081161391399" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="819814870235430554" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": ["PARAMETEO", "STM32L471xx"],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Debug STM32L476_ParaMETEO",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/STM32L476_ParaMETEO/ParaTNC.elf",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"ax25_t.h": "c",
|
||||
"*.tcc": "c",
|
||||
"variant.h": "c",
|
||||
"sim800c_tcpip.h": "c",
|
||||
"rte_main.h": "c",
|
||||
"config_data.h": "c",
|
||||
"random": "c",
|
||||
"message.h": "c"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "make STM32L476_ParaMETEO",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"all"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/STM32L476_ParaMETEO"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "clean STM32L476_ParaMETEO",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"clean"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/STM32L476_ParaMETEO"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
61
README.md
61
README.md
|
@ -218,6 +218,7 @@ This is done by invoking a command:
|
|||
'sudo echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.d/stlink_v1.conf'
|
||||
What will create a new file called 'stlink_v1.conf' in modprobe directory. After the system reboot changes should
|
||||
be applied and the programmer should be free to go. The kernel log should looks somehow like this below
|
||||
|
||||
[90639.895886] usb 2-1.1: new full-speed USB device number 13 using ehci-pci
|
||||
[90639.990288] usb 2-1.1: New USB device found, idVendor=0483, idProduct=3744
|
||||
[90639.990294] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
|
||||
|
@ -229,11 +230,59 @@ be applied and the programmer should be free to go. The kernel log should looks
|
|||
|
||||
The next step is to install texane-stlink which supports the ST-Link/V1 programmer and can be used to read an write
|
||||
the flash memory. Installation is quite straight forward
|
||||
'git clone git://github.com/texane/stlink.git'
|
||||
'cd stlink.git'
|
||||
'make'
|
||||
'cd build/Relase'
|
||||
'sudo cp st-* /usr/bin'
|
||||
|
||||
'git clone git://github.com/texane/stlink.git'
|
||||
'cd stlink.git'
|
||||
'make'
|
||||
'cd build/Relase'
|
||||
'sudo cp st-* /usr/bin'
|
||||
|
||||
At the end the HEX file can be loaded into the microcontroler by typing a command
|
||||
'sudo st-flash --format ihex write /dev/sr0 ParaTNC.hex'
|
||||
|
||||
'sudo st-flash --format ihex write /dev/sr0 ParaTNC.hex'
|
||||
|
||||
#### LOADING THE HEX FILE INTO ParaTNC or ParaMETEO TARGET USING STLINK/V2
|
||||
|
||||
mateusz@mateusz-ThinkCentre-M720q:~/Documents/___STM32/ParaTNC/STM32L476_ParaMETEO$ st-flash erase
|
||||
st-flash 1.7.0-120-gbeffed4
|
||||
/usr/local/stlink/chips: No such file or directory
|
||||
2023-11-17T07:43:18 INFO common.c: L47x/L48x: 96 KiB SRAM, 1024 KiB flash in at least 2 KiB pages.
|
||||
Mass erasing
|
||||
|
||||
and then programming itself
|
||||
|
||||
mateusz@mateusz-ThinkCentre-M720q:~/Documents/___STM32/ParaTNC/STM32L476_ParaMETEO$ st-flash --format ihex write ParaTNC.hex
|
||||
st-flash 1.7.0-120-gbeffed4
|
||||
/usr/local/stlink/chips: No such file or directory
|
||||
2023-11-17T07:44:47 INFO common.c: L47x/L48x: 96 KiB SRAM, 1024 KiB flash in at least 2 KiB pages.
|
||||
2023-11-17T07:44:47 INFO common.c: Attempting to write 111504 (0x1b390) bytes to stm32 address: 134217728 (0x8000000)
|
||||
|
||||
2023-11-17T07:44:48 INFO common.c: Finished erasing 55 pages of 2048 (0x800) bytes
|
||||
2023-11-17T07:44:48 INFO common.c: Starting Flash write for F2/F4/F7/L4
|
||||
2023-11-17T07:44:48 INFO flash_loader.c: Successfully loaded flash loader in sram
|
||||
2023-11-17T07:44:48 INFO flash_loader.c: Clear DFSR
|
||||
2023-11-17T07:44:48 INFO flash_loader.c: Clear CFSR
|
||||
2023-11-17T07:44:48 INFO flash_loader.c: Clear HFSR
|
||||
2023-11-17T07:44:51 INFO common.c: Starting verification of write complete
|
||||
2023-11-17T07:44:52 INFO common.c: Flash written and verified! jolly good!
|
||||
|
||||
#### LOADING THE HEX FILE INTO ParaTNC or ParaMETEO TARGET USING ROM BOOTLOADER AND STM32FLASH software
|
||||
|
||||
Examples:
|
||||
Get device information:
|
||||
stm32flash /dev/ttyS0
|
||||
or:
|
||||
stm32flash /dev/i2c-0
|
||||
|
||||
Write with verify and then start execution:
|
||||
stm32flash -w filename -v -g 0x0 /dev/ttyS0
|
||||
|
||||
Read flash to file:
|
||||
stm32flash -r filename /dev/ttyS0
|
||||
|
||||
Read 100 bytes of flash from 0x1000 to stdout:
|
||||
stm32flash -r - -S 0x1000:100 /dev/ttyS0
|
||||
|
||||
Start execution:
|
||||
stm32flash -g 0x0 /dev/ttyS0
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ C_SRCS += \
|
|||
../src/PathConfig.c \
|
||||
../src/TimerConfig.c \
|
||||
../src/_write.c \
|
||||
../src/backup_registers.c \
|
||||
../src/button_paratnc.c \
|
||||
../src/delay.c \
|
||||
../src/dummy.c \
|
||||
|
@ -21,6 +22,7 @@ C_SRCS += \
|
|||
../src/rte_rtu.c \
|
||||
../src/rte_wx.c \
|
||||
../src/software_version.c \
|
||||
../src/variant_parameteo.c \
|
||||
../src/wx_handler.c \
|
||||
../src/wx_handler_humidity.c \
|
||||
../src/wx_handler_pressure.c \
|
||||
|
@ -32,6 +34,7 @@ OBJS += \
|
|||
./src/PathConfig.o \
|
||||
./src/TimerConfig.o \
|
||||
./src/_write.o \
|
||||
./src/backup_registers.o \
|
||||
./src/button_paratnc.o \
|
||||
./src/delay.o \
|
||||
./src/dummy.o \
|
||||
|
@ -45,6 +48,7 @@ OBJS += \
|
|||
./src/rte_rtu.o \
|
||||
./src/rte_wx.o \
|
||||
./src/software_version.o \
|
||||
./src/variant_parameteo.o \
|
||||
./src/wx_handler.o \
|
||||
./src/wx_handler_humidity.o \
|
||||
./src/wx_handler_pressure.o \
|
||||
|
@ -56,6 +60,7 @@ C_DEPS += \
|
|||
./src/PathConfig.d \
|
||||
./src/TimerConfig.d \
|
||||
./src/_write.d \
|
||||
./src/backup_registers.d \
|
||||
./src/button_paratnc.d \
|
||||
./src/delay.d \
|
||||
./src/dummy.d \
|
||||
|
@ -69,6 +74,7 @@ C_DEPS += \
|
|||
./src/rte_rtu.d \
|
||||
./src/rte_wx.d \
|
||||
./src/software_version.d \
|
||||
./src/variant_parameteo.d \
|
||||
./src/wx_handler.d \
|
||||
./src/wx_handler_humidity.d \
|
||||
./src/wx_handler_pressure.d \
|
||||
|
|
|
@ -0,0 +1,430 @@
|
|||
# pylint: disable = invalid-name, too-few-public-methods
|
||||
|
||||
import re
|
||||
import pprint
|
||||
import os
|
||||
import sys
|
||||
from typing import List, Tuple, Dict, Any
|
||||
from subprocess import check_output
|
||||
|
||||
# Constants
|
||||
rtl_ext_end = ".dfinish"
|
||||
su_ext = '.su'
|
||||
obj_ext = '.o'
|
||||
manual_ext = '.msu'
|
||||
read_elf_path = os.getenv("CROSS_COMPILE", "") + "readelf"
|
||||
stdout_encoding = "utf-8" # System dependant
|
||||
|
||||
|
||||
class Printable:
|
||||
def __repr__(self) -> str:
|
||||
return "<" + type(self).__name__ + "> " + pprint.pformat(vars(self), indent=4, width=1)
|
||||
|
||||
|
||||
class Symbol(Printable):
|
||||
# value: int = -1
|
||||
# size: int = -1
|
||||
type: str = "uninitialized"
|
||||
binding: str = "uninitialized"
|
||||
name: str = "uninitialized"
|
||||
|
||||
|
||||
CallNode = Dict[str, Any]
|
||||
|
||||
|
||||
def calc_wcs(fxn_dict2: CallNode, parents: List[CallNode]) -> None:
|
||||
"""
|
||||
Calculates the worst case stack for a fxn that is declared (or called from) in a given file.
|
||||
:param parents: This function gets called recursively through the call graph. If a function has recursion the
|
||||
tuple file, fxn will be in the parents stack and everything between the top of the stack and the matching entry
|
||||
has recursion.
|
||||
:return:
|
||||
"""
|
||||
|
||||
# If the wcs is already known, then nothing to do
|
||||
if 'wcs' in fxn_dict2:
|
||||
return
|
||||
|
||||
# Check for pointer calls
|
||||
if fxn_dict2['has_ptr_call']:
|
||||
fxn_dict2['wcs'] = 'unbounded'
|
||||
return
|
||||
|
||||
# Check for recursion
|
||||
if fxn_dict2 in parents:
|
||||
fxn_dict2['wcs'] = 'unbounded'
|
||||
return
|
||||
|
||||
# Calculate WCS
|
||||
call_max = 0
|
||||
for call_dict in fxn_dict2['r_calls']:
|
||||
|
||||
# Calculate the WCS for the called function
|
||||
calc_wcs(call_dict, parents + [fxn_dict2])
|
||||
|
||||
# If the called function is unbounded, so is this function
|
||||
if call_dict['wcs'] == 'unbounded':
|
||||
fxn_dict2['wcs'] = 'unbounded'
|
||||
return
|
||||
|
||||
# Keep track of the call with the largest stack use
|
||||
call_max = max(call_max, call_dict['wcs'])
|
||||
|
||||
# Propagate Unresolved Calls
|
||||
for unresolved_call in call_dict['unresolved_calls']:
|
||||
fxn_dict2['unresolved_calls'].add(unresolved_call)
|
||||
|
||||
fxn_dict2['wcs'] = call_max + fxn_dict2['local_stack']
|
||||
|
||||
|
||||
class CallGraph:
|
||||
globals: Dict[str, CallNode] = {}
|
||||
locals: Dict[str, Dict[str, CallNode]] = {}
|
||||
weak: Dict[str, CallNode] = {}
|
||||
|
||||
def read_obj(self, tu: str) -> None:
|
||||
"""
|
||||
Reads the file tu.o and gets the binding (global or local) for each function
|
||||
:param self: a object used to store information about each function, results go here
|
||||
:param tu: name of the translation unit (e.g. for main.c, this would be 'main')
|
||||
"""
|
||||
|
||||
for s in read_symbols(tu[0:tu.rindex(".")] + obj_ext):
|
||||
|
||||
if s.type == 'FUNC':
|
||||
if s.binding == 'GLOBAL':
|
||||
# Check for multiple declarations
|
||||
if s.name in self.globals or s.name in self.locals:
|
||||
raise Exception(f'Multiple declarations of {s.name}')
|
||||
self.globals[s.name] = {'tu': tu, 'name': s.name, 'binding': s.binding}
|
||||
elif s.binding == 'LOCAL':
|
||||
# Check for multiple declarations
|
||||
if s.name in self.locals and tu in self.locals[s.name]:
|
||||
raise Exception(f'Multiple declarations of {s.name}')
|
||||
|
||||
if s.name not in self.locals:
|
||||
self.locals[s.name] = {}
|
||||
|
||||
self.locals[s.name][tu] = {'tu': tu, 'name': s.name, 'binding': s.binding}
|
||||
elif s.binding == 'WEAK':
|
||||
if s.name in self.weak:
|
||||
raise Exception(f'Multiple declarations of {s.name}')
|
||||
self.weak[s.name] = {'tu': tu, 'name': s.name, 'binding': s.binding}
|
||||
else:
|
||||
raise Exception(f'Error Unknown Binding "{s.binding}" for symbol: {s.name}')
|
||||
|
||||
def find_fxn(self, tu: str, fxn: str):
|
||||
"""
|
||||
Looks up the dictionary associated with the function.
|
||||
:param self: a object used to store information about each function
|
||||
:param tu: The translation unit in which to look for locals functions
|
||||
:param fxn: The function name
|
||||
:return: the dictionary for the given function or None
|
||||
"""
|
||||
|
||||
if fxn in self.globals:
|
||||
return self.globals[fxn]
|
||||
try:
|
||||
return self.locals[fxn][tu]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def find_demangled_fxn(self, tu: str, fxn: str):
|
||||
"""
|
||||
Looks up the dictionary associated with the function.
|
||||
:param self: a object used to store information about each function
|
||||
:param tu: The translation unit in which to look for locals functions
|
||||
:param fxn: The function name
|
||||
:return: the dictionary for the given function or None
|
||||
"""
|
||||
for f in self.globals.values():
|
||||
if 'demangledName' in f:
|
||||
if f['demangledName'] == fxn:
|
||||
return f
|
||||
for f in self.locals.values():
|
||||
if tu in f:
|
||||
if 'demangledName' in f[tu]:
|
||||
if f[tu]['demangledName'] == fxn:
|
||||
return f[tu]
|
||||
return None
|
||||
|
||||
def read_rtl(self, tu: str, rtl_ext: str) -> None:
|
||||
"""
|
||||
Read an RTL file and finds callees for each function and if there are calls via function pointer.
|
||||
:param self: a object used to store information about each function, results go here
|
||||
:param tu: the translation unit
|
||||
"""
|
||||
|
||||
# Construct A Call Graph
|
||||
function = re.compile(r'^;; Function (.*) \((\S+), funcdef_no=\d+(, [a-z_]+=\d+)*\)( \([a-z ]+\))?$')
|
||||
static_call = re.compile(r'^.*\(call.*"(.*)".*$')
|
||||
other_call = re.compile(r'^.*call .*$')
|
||||
|
||||
with open(tu + rtl_ext, "rt", encoding="latin_1") as file_:
|
||||
for line_ in file_:
|
||||
m = function.match(line_)
|
||||
if m:
|
||||
fxn_name = m.group(2)
|
||||
fxn_dict2 = self.find_fxn(tu, fxn_name)
|
||||
if not fxn_dict2:
|
||||
pprint.pprint(self)
|
||||
raise Exception(f"Error locating function {fxn_name} in {tu}")
|
||||
|
||||
fxn_dict2['demangledName'] = m.group(1)
|
||||
fxn_dict2['calls'] = set()
|
||||
fxn_dict2['has_ptr_call'] = False
|
||||
continue
|
||||
|
||||
m = static_call.match(line_)
|
||||
if m:
|
||||
fxn_dict2['calls'].add(m.group(1))
|
||||
# print("Call: {0} -> {1}".format(current_fxn, m.group(1)))
|
||||
continue
|
||||
|
||||
m = other_call.match(line_)
|
||||
if m:
|
||||
fxn_dict2['has_ptr_call'] = True
|
||||
continue
|
||||
|
||||
def read_su(self, tu: str) -> None:
|
||||
"""
|
||||
Reads the 'local_stack' for each function. Local stack ignores stack used by callees.
|
||||
:param self: a object used to store information about each function, results go here
|
||||
:param tu: the translation unit
|
||||
:return:
|
||||
"""
|
||||
# Needs to be able to handle both cases, i.e.:
|
||||
# c:\\userlibs\\gcc\\arm-none-eabi\\include\\assert.h:41:6:__assert_func 16 static
|
||||
# main.c:113:6:vAssertCalled 8 static
|
||||
# Now Matches six groups https://regex101.com/r/Imi0sq/1
|
||||
|
||||
su_line = re.compile(r'^(.+):(\d+):(\d+):(.+)\t(\d+)\t(\S+)$')
|
||||
i = 1
|
||||
|
||||
with open(tu[0:tu.rindex(".")] + su_ext, "rt", encoding="latin_1") as file_:
|
||||
for line in file_:
|
||||
m = su_line.match(line)
|
||||
if m:
|
||||
fxn = m.group(4)
|
||||
fxn_dict2 = self.find_demangled_fxn(tu, fxn)
|
||||
fxn_dict2['local_stack'] = int(m.group(5))
|
||||
else:
|
||||
print(f"error parsing line {i} in file {tu}")
|
||||
i += 1
|
||||
|
||||
def read_manual(self, file: str) -> None:
|
||||
"""
|
||||
reads the manual stack useage files.
|
||||
:param self: a object used to store information about each function, results go here
|
||||
:param file: the file name
|
||||
"""
|
||||
|
||||
with open(file, "rt", encoding="latin_1") as file_:
|
||||
for line in file_:
|
||||
fxn, stack_sz = line.split()
|
||||
if fxn in self.globals:
|
||||
raise Exception(f"Redeclared Function {fxn}")
|
||||
self.globals[fxn] = {'wcs': int(stack_sz),
|
||||
'calls': set(),
|
||||
'has_ptr_call': False,
|
||||
'local_stack': int(stack_sz),
|
||||
'is_manual': True,
|
||||
'name': fxn,
|
||||
'demangledName': fxn,
|
||||
'tu': '#MANUAL',
|
||||
'binding': 'GLOBAL'}
|
||||
|
||||
def validate_all_data(self) -> None:
|
||||
"""
|
||||
Check that every entry in the call graph has the following fields:
|
||||
.calls, .has_ptr_call, .local_stack, .scope, .src_line
|
||||
"""
|
||||
|
||||
def validate_dict(d):
|
||||
if not ('calls' in d and 'has_ptr_call' in d and 'local_stack' in d
|
||||
and 'name' in d and 'tu' in d):
|
||||
print(f"Error data is missing in fxn dictionary {d}")
|
||||
|
||||
# Loop through every global and local function
|
||||
# and resolve each call, save results in r_calls
|
||||
for fxn_dict2 in self.globals.values():
|
||||
validate_dict(fxn_dict2)
|
||||
|
||||
for l_dict in self.locals.values():
|
||||
for fxn_dict2 in l_dict.values():
|
||||
validate_dict(fxn_dict2)
|
||||
|
||||
def resolve_all_calls(self) -> None:
|
||||
def resolve_calls(fxn_dict2: CallNode) -> None:
|
||||
fxn_dict2['r_calls'] = []
|
||||
fxn_dict2['unresolved_calls'] = set()
|
||||
|
||||
for call in fxn_dict2['calls']:
|
||||
call_dict = self.find_fxn(fxn_dict2['tu'], call)
|
||||
if call_dict:
|
||||
fxn_dict2['r_calls'].append(call_dict)
|
||||
else:
|
||||
fxn_dict2['unresolved_calls'].add(call)
|
||||
|
||||
# Loop through every global and local function
|
||||
# and resolve each call, save results in r_calls
|
||||
for fxn_dict in self.globals.values():
|
||||
resolve_calls(fxn_dict)
|
||||
|
||||
for l_dict in self.locals.values():
|
||||
for fxn_dict in l_dict.values():
|
||||
resolve_calls(fxn_dict)
|
||||
|
||||
def calc_all_wcs(self) -> None:
|
||||
# Loop through every global and local function
|
||||
# and resolve each call, save results in r_calls
|
||||
for fxn_dict in self.globals.values():
|
||||
calc_wcs(fxn_dict, [])
|
||||
|
||||
for l_dict in self.locals.values():
|
||||
for fxn_dict in l_dict.values():
|
||||
calc_wcs(fxn_dict, [])
|
||||
|
||||
def print_all_fxns(self) -> None:
|
||||
|
||||
def print_fxn(row_format: str, fxn_dict2: CallNode) -> None:
|
||||
unresolved = fxn_dict2['unresolved_calls']
|
||||
stack = str(fxn_dict2['wcs'])
|
||||
if unresolved:
|
||||
unresolved_str = f"({' ,'.join(unresolved)})"
|
||||
if stack != 'unbounded':
|
||||
stack = "unbounded:" + stack
|
||||
else:
|
||||
unresolved_str = ''
|
||||
|
||||
print(row_format.format(fxn_dict2['tu'], fxn_dict2['demangledName'], stack, unresolved_str))
|
||||
|
||||
def get_order(val) -> int:
|
||||
return 1 if val == 'unbounded' else -val
|
||||
|
||||
# Loop through every global and local function
|
||||
# and resolve each call, save results in r_calls
|
||||
d_list = []
|
||||
for fxn_dict in self.globals.values():
|
||||
d_list.append(fxn_dict)
|
||||
|
||||
for l_dict in self.locals.values():
|
||||
for fxn_dict in l_dict.values():
|
||||
d_list.append(fxn_dict)
|
||||
|
||||
d_list.sort(key=lambda item: get_order(item['wcs']))
|
||||
|
||||
# Calculate table width
|
||||
tu_width = max(max(len(d['tu']) for d in d_list), 16)
|
||||
name_width = max(max(len(d['name']) for d in d_list), 13)
|
||||
row_format = "{:<" + str(tu_width + 2) + "} {:<" + str(name_width + 2) + "} {:>14} {:<17}"
|
||||
|
||||
# Print out the table
|
||||
print("")
|
||||
print(row_format.format('Translation Unit', 'Function Name', 'Stack', 'Unresolved Dependencies'))
|
||||
for d in d_list:
|
||||
print_fxn(row_format, d)
|
||||
|
||||
|
||||
def read_symbols(file: str) -> List[Symbol]:
|
||||
|
||||
def to_symbol(read_elf_line: str) -> Symbol:
|
||||
v = read_elf_line.split()
|
||||
|
||||
s2 = Symbol()
|
||||
# s2.value = int(v[1], 16)
|
||||
# if ('x' in v[2]):
|
||||
# #raise Exception(f'Mixed symbol sizes in \'{v}\' ')
|
||||
# s2.size=int(v[2].split('x')[1],16)
|
||||
# else:
|
||||
# s2.size = int(v[2])
|
||||
s2.type = v[3]
|
||||
s2.binding = v[4]
|
||||
s2.name = v[7] if len(v) >= 8 else ""
|
||||
|
||||
return s2
|
||||
output = check_output([read_elf_path, "-s", "-W", file]).decode(stdout_encoding)
|
||||
lines = output.splitlines()[3:]
|
||||
return [to_symbol(line) for line in lines]
|
||||
|
||||
|
||||
def find_rtl_ext() -> str:
|
||||
# Find the rtl_extension
|
||||
|
||||
for _, _, filenames in os.walk('.'):
|
||||
for f in filenames:
|
||||
if f.endswith(rtl_ext_end):
|
||||
rtl_ext = f[f[:-len(rtl_ext_end)].rindex("."):]
|
||||
print("rtl_ext = " + rtl_ext)
|
||||
return rtl_ext
|
||||
|
||||
print("Could not find any files ending with '.dfinish'. Check that the script is being run from the correct "
|
||||
"directory. Check that the code was compiled with the correct flags")
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def find_files(rtl_ext: str) -> Tuple[List[str], List[str]]:
|
||||
tu: List[str] = []
|
||||
manual: List[str] = []
|
||||
all_files: List[str] = []
|
||||
for root, _, filenames in os.walk('.'):
|
||||
for filename in filenames:
|
||||
all_files.append(os.path.join(root, filename))
|
||||
for f in [f for f in all_files if os.path.isfile(f) and f.endswith(rtl_ext)]:
|
||||
base = f[0:-len(rtl_ext)]
|
||||
short_base = base[0:base.rindex(".")]
|
||||
if short_base + su_ext in all_files and short_base + obj_ext in all_files:
|
||||
tu.append(base)
|
||||
print(f'Reading: {base}{rtl_ext}, {short_base}{su_ext}, {short_base}{obj_ext}')
|
||||
|
||||
for f in [f for f in all_files if os.path.isfile(f) and f.endswith(manual_ext)]:
|
||||
manual.append(f)
|
||||
print(f'Reading: {f}')
|
||||
|
||||
# Print some diagnostic messages
|
||||
if not tu:
|
||||
print("Could not find any translation units to analyse")
|
||||
sys.exit(-1)
|
||||
|
||||
return tu, manual
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# Find the appropriate RTL extension
|
||||
rtl_ext = find_rtl_ext()
|
||||
|
||||
# Find all input files
|
||||
call_graph: CallGraph = CallGraph()
|
||||
tu_list, manual_list = find_files(rtl_ext)
|
||||
|
||||
# Read the input files
|
||||
for tu in tu_list:
|
||||
call_graph.read_obj(tu) # This must be first
|
||||
|
||||
for fxn in call_graph.weak.values():
|
||||
if fxn['name'] not in call_graph.globals:
|
||||
call_graph.globals[fxn['name']] = fxn
|
||||
|
||||
for tu in tu_list:
|
||||
call_graph.read_rtl(tu, rtl_ext)
|
||||
for tu in tu_list:
|
||||
call_graph.read_su(tu)
|
||||
|
||||
# Read manual files
|
||||
for m in manual_list:
|
||||
call_graph.read_manual(m)
|
||||
|
||||
# Validate Data
|
||||
call_graph.validate_all_data()
|
||||
|
||||
# Resolve All Function Calls
|
||||
call_graph.resolve_all_calls()
|
||||
|
||||
# Calculate Worst Case Stack For Each Function
|
||||
call_graph.calc_all_wcs()
|
||||
|
||||
# Print A Nice Message With Each Function and the WCS
|
||||
call_graph.print_all_fxns()
|
||||
|
||||
|
||||
main()
|
|
@ -0,0 +1,251 @@
|
|||
#!/usr/bin/perl -w
|
||||
# avstack.pl: AVR stack checker
|
||||
# Copyright (C) 2013 Daniel Beer <dlbeer@gmail.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
# above copyright notice and this permission notice appear in all
|
||||
# copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# Usage
|
||||
# -----
|
||||
#
|
||||
# This script requires that you compile your code with -fstack-usage.
|
||||
# This results in GCC generating a .su file for each .o file. Once you
|
||||
# have these, do:
|
||||
#
|
||||
# ./avstack.pl <object files>
|
||||
#
|
||||
# This will disassemble .o files to construct a call graph, and read
|
||||
# frame size information from .su. The call graph is traced to find, for
|
||||
# each function:
|
||||
#
|
||||
# - Call height: the maximum call height of any callee, plus 1
|
||||
# (defined to be 1 for any function which has no callees).
|
||||
#
|
||||
# - Inherited frame: the maximum *inherited* frame of any callee, plus
|
||||
# the GCC-calculated frame size of the function in question.
|
||||
#
|
||||
# Using these two pieces of information, we calculate a cost (estimated
|
||||
# peak stack usage) for calling the function. Functions are then listed
|
||||
# on stdout in decreasing order of cost.
|
||||
#
|
||||
# Functions which are recursive are marked with an 'R' to the left of
|
||||
# them. Their cost is calculated for a single level of recursion.
|
||||
#
|
||||
# The peak stack usage of your entire program can usually be estimated
|
||||
# as the stack cost of "main", plus the maximum stack cost of any
|
||||
# interrupt handler which might execute.
|
||||
|
||||
use strict;
|
||||
|
||||
# Configuration: set these as appropriate for your architecture/project.
|
||||
|
||||
my $objdump = "/usr/local/bin/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-objdump";
|
||||
my $call_cost = 32;
|
||||
|
||||
# First, we need to read all object and corresponding .su files. We're
|
||||
# gathering a mapping of functions to callees and functions to frame
|
||||
# sizes. We're just parsing at this stage -- callee name resolution
|
||||
# comes later.
|
||||
|
||||
my %frame_size; # "func@file" -> size
|
||||
my %call_graph; # "func@file" -> {callees}
|
||||
my %addresses; # "addr@file" -> "func@file"
|
||||
|
||||
my %global_name; # "func" -> "func@file"
|
||||
my %ambiguous; # "func" -> 1
|
||||
|
||||
foreach (@ARGV) {
|
||||
# Disassemble this object file to obtain a callees. Sources in the
|
||||
# call graph are named "func@file". Targets in the call graph are
|
||||
# named either "offset@file" or "funcname". We also keep a list of
|
||||
# the addresses and names of each function we encounter.
|
||||
my $objfile = $_;
|
||||
my $source;
|
||||
|
||||
open(DISASSEMBLY, "$objdump -dr $objfile|") ||
|
||||
die "Can't disassemble $objfile";
|
||||
while (<DISASSEMBLY>) {
|
||||
chomp;
|
||||
|
||||
if (/^([0-9a-fA-F]+) <(.*)>:/) {
|
||||
my $a = $1;
|
||||
my $name = $2;
|
||||
|
||||
$source = "$name\@$objfile";
|
||||
$call_graph{$source} = {};
|
||||
$ambiguous{$name} = 1 if defined($global_name{$name});
|
||||
$global_name{$name} = "$name\@$objfile";
|
||||
|
||||
$a =~ s/^0*//;
|
||||
$addresses{"$a\@$objfile"} = "$name\@$objfile";
|
||||
}
|
||||
|
||||
if (/: R_[A-Za-z0-9_]+_CALL[ \t]+(.*)/) {
|
||||
my $t = $1;
|
||||
|
||||
if ($t eq ".text") {
|
||||
$t = "\@$objfile";
|
||||
} elsif ($t =~ /^\.text\+0x(.*)$/) {
|
||||
$t = "$1\@$objfile";
|
||||
}
|
||||
|
||||
$call_graph{$source}->{$t} = 1;
|
||||
}
|
||||
}
|
||||
close(DISASSEMBLY);
|
||||
|
||||
# Extract frame sizes from the corresponding .su file.
|
||||
if ($objfile =~ /^(.*).o$/) {
|
||||
my $sufile = "$1.su";
|
||||
|
||||
open(SUFILE, "<$sufile") || die "Can't open $sufile";
|
||||
while (<SUFILE>) {
|
||||
$frame_size{"$1\@$objfile"} = $2 + $call_cost
|
||||
if /^.*:([^\t ]+)[ \t]+([0-9]+)/;
|
||||
}
|
||||
close(SUFILE);
|
||||
}
|
||||
}
|
||||
|
||||
# In this step, we enumerate each list of callees in the call graph and
|
||||
# try to resolve the symbols. We omit ones we can't resolve, but keep a
|
||||
# set of them anyway.
|
||||
|
||||
my %unresolved;
|
||||
|
||||
foreach (keys %call_graph) {
|
||||
my $from = $_;
|
||||
my $callees = $call_graph{$from};
|
||||
my %resolved;
|
||||
|
||||
foreach (keys %$callees) {
|
||||
my $t = $_;
|
||||
|
||||
if (defined($addresses{$t})) {
|
||||
$resolved{$addresses{$t}} = 1;
|
||||
} elsif (defined($global_name{$t})) {
|
||||
$resolved{$global_name{$t}} = 1;
|
||||
warn "Ambiguous resolution: $t" if defined ($ambiguous{$t});
|
||||
} elsif (defined($call_graph{$t})) {
|
||||
$resolved{$t} = 1;
|
||||
} else {
|
||||
$unresolved{$t} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$call_graph{$from} = \%resolved;
|
||||
}
|
||||
|
||||
# Create fake edges and nodes to account for dynamic behaviour.
|
||||
$call_graph{"INTERRUPT"} = {};
|
||||
|
||||
foreach (keys %call_graph) {
|
||||
$call_graph{"INTERRUPT"}->{$_} = 1 if /^__vector_/;
|
||||
}
|
||||
|
||||
# Trace the call graph and calculate, for each function:
|
||||
#
|
||||
# - inherited frames: maximum inherited frame of callees, plus own
|
||||
# frame size.
|
||||
# - height: maximum height of callees, plus one.
|
||||
# - recursion: is the function called recursively (including indirect
|
||||
# recursion)?
|
||||
|
||||
my %has_caller;
|
||||
my %visited;
|
||||
my %total_cost;
|
||||
my %call_depth;
|
||||
|
||||
sub trace {
|
||||
my $f = shift;
|
||||
|
||||
if ($visited{$f}) {
|
||||
$visited{$f} = "R" if $visited{$f} eq "?";
|
||||
return;
|
||||
}
|
||||
|
||||
$visited{$f} = "?";
|
||||
|
||||
my $max_depth = 0;
|
||||
my $max_frame = 0;
|
||||
|
||||
my $targets = $call_graph{$f} || die "Unknown function: $f";
|
||||
if (defined($targets)) {
|
||||
foreach (keys %$targets) {
|
||||
my $t = $_;
|
||||
|
||||
$has_caller{$t} = 1;
|
||||
trace($t);
|
||||
|
||||
my $is = $total_cost{$t};
|
||||
my $d = $call_depth{$t};
|
||||
|
||||
$max_frame = $is if $is > $max_frame;
|
||||
$max_depth = $d if $d > $max_depth;
|
||||
}
|
||||
}
|
||||
|
||||
$call_depth{$f} = $max_depth + 1;
|
||||
$total_cost{$f} = $max_frame + ($frame_size{$f} || 0);
|
||||
$visited{$f} = " " if $visited{$f} eq "?";
|
||||
}
|
||||
|
||||
foreach (keys %call_graph) { trace $_; }
|
||||
|
||||
# Now, print results in a nice table.
|
||||
printf " %-30s %8s %8s %8s\n",
|
||||
"Func", "Cost", "Frame", "Height";
|
||||
print "------------------------------------";
|
||||
print "------------------------------------\n";
|
||||
|
||||
my $max_iv = 0;
|
||||
my $main = 0;
|
||||
|
||||
foreach (sort { $total_cost{$b} <=> $total_cost{$a} } keys %visited) {
|
||||
my $name = $_;
|
||||
|
||||
if (/^(.*)@(.*)$/) {
|
||||
$name = $1 unless $ambiguous{$name};
|
||||
}
|
||||
|
||||
my $tag = $visited{$_};
|
||||
my $cost = $total_cost{$_};
|
||||
|
||||
$name = $_ if $ambiguous{$name};
|
||||
$tag = ">" unless $has_caller{$_};
|
||||
|
||||
if (/^__vector_/) {
|
||||
$max_iv = $cost if $cost > $max_iv;
|
||||
} elsif (/^main@/) {
|
||||
$main = $cost;
|
||||
}
|
||||
|
||||
if ($ambiguous{$name}) { $name = $_; }
|
||||
|
||||
printf "%s %-30s %8d %8d %8d\n", $tag, $name, $cost,
|
||||
$frame_size{$_} || 0, $call_depth{$_};
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
print "Peak execution estimate (main + worst-case IV):\n";
|
||||
printf " main = %d, worst IV = %d, total = %d\n",
|
||||
$total_cost{$global_name{"main"}},
|
||||
$total_cost{"INTERRUPT"},
|
||||
$total_cost{$global_name{"main"}} + $total_cost{"INTERRUPT"};
|
||||
|
||||
print "\n";
|
||||
|
||||
print "The following functions were not resolved:\n";
|
||||
foreach (keys %unresolved) { print " $_\n"; }
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm __stackanalysis/*
|
||||
#cp WCS.py __stackanalysis/WCS.py
|
||||
cp avstack.pl __stackanalysis/avstack.pl
|
||||
|
||||
find . -maxdepth 5 -type f -name "*.su" -exec bash -c 'filename=$(basename -- {}); echo $filename; cp {} __stackanalysis/$filename' \;
|
||||
|
||||
find . -maxdepth 5 -type f -name "*.dfinish" -exec bash -c 'filename=$(basename -- {}); echo $filename; cp {} __stackanalysis/$filename' \;
|
||||
|
||||
find . -maxdepth 5 -type f -name "*.o" -exec bash -c 'filename=$(basename -- {}); echo $filename; cp {} __stackanalysis/$filename' \;
|
||||
|
||||
cd ./__stackanalysis/
|
||||
rm startup_stm32l471xx.*
|
||||
perl avstack.pl *.o > ../stack_analysis.report
|
||||
#python3.10 WCS.py
|
|
@ -0,0 +1,33 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../src/configuration_nvm/config_data_default.c \
|
||||
../src/configuration_nvm/config_data_first.c \
|
||||
../src/configuration_nvm/config_data_second.c \
|
||||
../src/configuration_nvm/configuration_handler.c
|
||||
|
||||
OBJS += \
|
||||
./src/configuration_nvm/config_data_default.o \
|
||||
./src/configuration_nvm/config_data_first.o \
|
||||
./src/configuration_nvm/config_data_second.o \
|
||||
./src/configuration_nvm/configuration_handler.o
|
||||
|
||||
C_DEPS += \
|
||||
./src/configuration_nvm/config_data_default.d \
|
||||
./src/configuration_nvm/config_data_first.d \
|
||||
./src/configuration_nvm/config_data_second.d \
|
||||
./src/configuration_nvm/configuration_handler.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
src/configuration_nvm/%.o: ../src/configuration_nvm/%.c src/configuration_nvm/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../src/kiss_protocol/kiss_callback.c \
|
||||
../src/kiss_protocol/kiss_communication.c \
|
||||
../src/kiss_protocol/kiss_communication_aprsmsg.c \
|
||||
../src/kiss_protocol/kiss_did.c \
|
||||
../src/kiss_protocol/kiss_nrc_response.c
|
||||
|
||||
OBJS += \
|
||||
./src/kiss_protocol/kiss_callback.o \
|
||||
./src/kiss_protocol/kiss_communication.o \
|
||||
./src/kiss_protocol/kiss_communication_aprsmsg.o \
|
||||
./src/kiss_protocol/kiss_did.o \
|
||||
./src/kiss_protocol/kiss_nrc_response.o
|
||||
|
||||
C_DEPS += \
|
||||
./src/kiss_protocol/kiss_callback.d \
|
||||
./src/kiss_protocol/kiss_communication.d \
|
||||
./src/kiss_protocol/kiss_communication_aprsmsg.d \
|
||||
./src/kiss_protocol/kiss_did.d \
|
||||
./src/kiss_protocol/kiss_nrc_response.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
src/kiss_protocol/%.o: ../src/kiss_protocol/%.c src/kiss_protocol/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../src/stored_configuration_nvm/config_data_default.c \
|
||||
../src/stored_configuration_nvm/config_data_first.c \
|
||||
../src/stored_configuration_nvm/config_data_second.c \
|
||||
../src/stored_configuration_nvm/configuration_handler.c
|
||||
|
||||
OBJS += \
|
||||
./src/stored_configuration_nvm/config_data_default.o \
|
||||
./src/stored_configuration_nvm/config_data_first.o \
|
||||
./src/stored_configuration_nvm/config_data_second.o \
|
||||
./src/stored_configuration_nvm/configuration_handler.o
|
||||
|
||||
C_DEPS += \
|
||||
./src/stored_configuration_nvm/config_data_default.d \
|
||||
./src/stored_configuration_nvm/config_data_first.d \
|
||||
./src/stored_configuration_nvm/config_data_second.d \
|
||||
./src/stored_configuration_nvm/configuration_handler.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
src/stored_configuration_nvm/%.o: ../src/stored_configuration_nvm/%.c src/stored_configuration_nvm/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ C_DEPS += \
|
|||
src/%.o: ../src/%.c src/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ C_SRCS += \
|
|||
../system/src/aprs/crc.c \
|
||||
../system/src/aprs/dac.c \
|
||||
../system/src/aprs/digi.c \
|
||||
../system/src/aprs/message.c \
|
||||
../system/src/aprs/status.c \
|
||||
../system/src/aprs/telemetry.c \
|
||||
../system/src/aprs/wx.c
|
||||
|
@ -25,6 +26,7 @@ OBJS += \
|
|||
./system/src/aprs/crc.o \
|
||||
./system/src/aprs/dac.o \
|
||||
./system/src/aprs/digi.o \
|
||||
./system/src/aprs/message.o \
|
||||
./system/src/aprs/status.o \
|
||||
./system/src/aprs/telemetry.o \
|
||||
./system/src/aprs/wx.o
|
||||
|
@ -38,6 +40,7 @@ C_DEPS += \
|
|||
./system/src/aprs/crc.d \
|
||||
./system/src/aprs/dac.d \
|
||||
./system/src/aprs/digi.d \
|
||||
./system/src/aprs/message.d \
|
||||
./system/src/aprs/status.d \
|
||||
./system/src/aprs/telemetry.d \
|
||||
./system/src/aprs/wx.d
|
||||
|
@ -47,7 +50,7 @@ C_DEPS += \
|
|||
system/src/aprs/%.o: ../system/src/aprs/%.c system/src/aprs/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ system/src/cmsis/stm32l4xx/%.o: ../system/src/cmsis/stm32l4xx/%.S system/src/cms
|
|||
system/src/cmsis/stm32l4xx/%.o: ../system/src/cmsis/stm32l4xx/%.c system/src/cmsis/stm32l4xx/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ C_DEPS += \
|
|||
system/src/davis_vantage/%.o: ../system/src/davis_vantage/%.c system/src/davis_vantage/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ C_DEPS += \
|
|||
system/src/diag/%.o: ../system/src/diag/%.c system/src/diag/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ C_DEPS += \
|
|||
system/src/drivers/l4/%.o: ../system/src/drivers/l4/%.c system/src/drivers/l4/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ C_DEPS += \
|
|||
system/src/drivers/%.o: ../system/src/drivers/%.c system/src/drivers/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/dust_sensor/sds011.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/dust_sensor/sds011.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/dust_sensor/sds011.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/dust_sensor/%.o: ../system/src/dust_sensor/%.c system/src/dust_sensor/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/fatfs/diskio.c \
|
||||
../system/src/fatfs/ff.c \
|
||||
../system/src/fatfs/ffsystem.c \
|
||||
../system/src/fatfs/ffunicode.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/fatfs/diskio.o \
|
||||
./system/src/fatfs/ff.o \
|
||||
./system/src/fatfs/ffsystem.o \
|
||||
./system/src/fatfs/ffunicode.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/fatfs/diskio.d \
|
||||
./system/src/fatfs/ff.d \
|
||||
./system/src/fatfs/ffsystem.d \
|
||||
./system/src/fatfs/ffunicode.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/fatfs/%.o: ../system/src/fatfs/%.c system/src/fatfs/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/gsm/sim800c.c \
|
||||
../system/src/gsm/sim800c_engineering.c \
|
||||
../system/src/gsm/sim800c_gprs.c \
|
||||
../system/src/gsm/sim800c_poolers.c \
|
||||
../system/src/gsm/sim800c_tcpip.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/gsm/sim800c.o \
|
||||
./system/src/gsm/sim800c_engineering.o \
|
||||
./system/src/gsm/sim800c_gprs.o \
|
||||
./system/src/gsm/sim800c_poolers.o \
|
||||
./system/src/gsm/sim800c_tcpip.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/gsm/sim800c.d \
|
||||
./system/src/gsm/sim800c_engineering.d \
|
||||
./system/src/gsm/sim800c_gprs.d \
|
||||
./system/src/gsm/sim800c_poolers.d \
|
||||
./system/src/gsm/sim800c_tcpip.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/gsm/%.o: ../system/src/gsm/%.c system/src/gsm/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/http_client/http_client.c \
|
||||
../system/src/http_client/http_client_headers.c \
|
||||
../system/src/http_client/http_client_rx_callback.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/http_client/http_client.o \
|
||||
./system/src/http_client/http_client_headers.o \
|
||||
./system/src/http_client/http_client_rx_callback.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/http_client/http_client.d \
|
||||
./system/src/http_client/http_client_headers.d \
|
||||
./system/src/http_client/http_client_rx_callback.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/http_client/%.o: ../system/src/http_client/%.c system/src/http_client/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ C_DEPS += \
|
|||
system/src/modbus_rtu/%.o: ../system/src/modbus_rtu/%.c system/src/modbus_rtu/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ C_DEPS += \
|
|||
system/src/stm32l4-hal-driver/%.o: ../system/src/stm32l4-hal-driver/%.c system/src/stm32l4-hal-driver/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/crc_.c \
|
||||
../system/src/float_average.c \
|
||||
../system/src/float_to_string.c \
|
||||
../system/src/int_average.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/crc_.o \
|
||||
./system/src/float_average.o \
|
||||
./system/src/float_to_string.o \
|
||||
./system/src/int_average.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/crc_.d \
|
||||
./system/src/float_average.d \
|
||||
./system/src/float_to_string.d \
|
||||
./system/src/int_average.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/%.o: ../system/src/%.c system/src/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../system/src/tiny-aes/aes.c
|
||||
|
||||
OBJS += \
|
||||
./system/src/tiny-aes/aes.o
|
||||
|
||||
C_DEPS += \
|
||||
./system/src/tiny-aes/aes.d
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
system/src/tiny-aes/%.o: ../system/src/tiny-aes/%.c system/src/tiny-aes/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ C_DEPS += \
|
|||
system/src/umb_master/%.o: ../system/src/umb_master/%.c system/src/umb_master/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ C_DEPS += \
|
|||
system/src/ve_direct_protocol/%.o: ../system/src/ve_direct_protocol/%.c system/src/ve_direct_protocol/subdir.mk
|
||||
@echo 'Building file: $<'
|
||||
@echo 'Invoking: Cross ARM C Compiler'
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -g3 -DDEBUG -DUSE_FULL_LL_DRIVER -DSTM32L471xx -DPARAMETEO -USTM32F10X_MD_VL -UPARATNC_HWREV_A -UPARATNC_HWREV_B -UPARATNC_HWREV_C -I"../include" -I"../include/configuration_nvm" -I"../include/etc" -I"../system/include/tiny-aes" -I"../system/include/aprs" -I"../system/include" -I"../system/include/cmsis/stm32l4xx" -I"../system/include/cmsis/stm32l4xx/device" -I"../system/include/stm32l4-hal-driver" -I"../system/include/stm32l4-hal-driver/Legacy" -std=gnu11 -Wunused-function -Wall -Wa,-adhlns="$@.lst" -fstack-usage -fdump-rtl-dfinish -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
|
||||
@echo 'Finished building: $<'
|
||||
@echo ' '
|
||||
|
||||
|
|
|
@ -58,6 +58,6 @@
|
|||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="IWDG"/> <peripheral name="DBGMCU"/> <peripheral name="USART3"/> </peripherals> "/>
|
||||
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="IWDG"/> <peripheral name="DBGMCU"/> <peripheral name="RTC"/> </peripherals> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -13,6 +13,7 @@
|
|||
#include "gsm/sim800c_tcpip.h"
|
||||
#include "ax25.h"
|
||||
#include "telemetry.h"
|
||||
#include "message.h"
|
||||
|
||||
|
||||
typedef enum aprsis_return {
|
||||
|
@ -50,7 +51,7 @@ void aprsis_init(
|
|||
aprsis_return_t aprsis_connect_and_login(const char * address, uint8_t address_ln, uint16_t port, uint8_t auto_send_beacon);
|
||||
aprsis_return_t aprsis_connect_and_login_default(uint8_t auto_send_beacon);
|
||||
sim800_return_t aprsis_disconnect(void);
|
||||
void aprsis_receive_callback(srl_context_t* srl_context);
|
||||
//void aprsis_receive_callback(srl_context_t* srl_context);
|
||||
void aprsis_check_alive(void);
|
||||
int aprsis_check_connection_attempt_alive(void);
|
||||
|
||||
|
@ -96,11 +97,14 @@ telemetry_description_t aprsis_send_description_telemetry(uint8_t async,
|
|||
const char * callsign_with_ssid);
|
||||
|
||||
void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid);
|
||||
void aprsis_send_server_conn_status(const char * callsign_with_ssid);
|
||||
void aprsis_send_server_comm_counters(const char * callsign_with_ssid);
|
||||
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, uint16_t voltage);
|
||||
void aprsis_send_gpsstatus(const char * callsign_with_ssid);
|
||||
void aprsis_send_gsm_status(const char * callsign_with_ssid);
|
||||
void aprsis_send_ack_for_message(const message_t * const message);
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
char * aprsis_get_tx_buffer(void);
|
||||
#endif
|
||||
uint8_t aprsis_get_aprsis_logged(void);
|
||||
|
||||
void aprsis_debug_set_simulate_timeout(void);
|
||||
|
|
|
@ -44,6 +44,14 @@ inline uint32_t backup_reg_get_monitor(void) {
|
|||
return REGISTER_MONITOR;
|
||||
}
|
||||
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX (1U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON (1U << 1U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY (1U << 2U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR (1U << 3U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE (1U << 4U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS (1U << 5U)
|
||||
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING (1U << 6U)
|
||||
|
||||
uint32_t backup_reg_get_configuration(void);
|
||||
void backup_reg_set_configuration(uint32_t value);
|
||||
void backup_reg_set_bits_configuration(uint32_t value);
|
||||
|
@ -81,6 +89,12 @@ void backup_reg_set_telemetry(uint16_t);
|
|||
void backup_reg_get_packet_counters(uint8_t * beacon_counter, uint8_t * meteo_counter, uint8_t * meteo_gsm_counter);
|
||||
void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counter, uint8_t meteo_gsm_counter);
|
||||
|
||||
void backup_reg_increment_aprsis_check_reset(void);
|
||||
void backup_reg_increment_weather_measurements_check_reset(void);
|
||||
void backup_reg_increment_dallas_degraded_reset(void);
|
||||
void backup_reg_increment_is_rtc_ok_check_reset(void);
|
||||
|
||||
void backup_assert(uint32_t assert);
|
||||
|
||||
|
||||
#endif /* BACKUP_REGISTERS_H_ */
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
* $WIZ$ type = "int"
|
||||
* $WIZ$ min = 1
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
//extern uint8_t kiss_txdelay;
|
||||
//#define CONFIG_AFSK_PREAMBLE_LEN (kiss_txdelay*10UL)
|
||||
#define CONFIG_AFSK_PREAMBLE_LEN 400UL /// 300
|
||||
|
||||
/**
|
||||
|
@ -36,8 +32,6 @@
|
|||
* $WIZ$ type = "int"
|
||||
* $WIZ$ min = 1
|
||||
*/
|
||||
//extern uint8_t kiss_txtail;
|
||||
//#define CONFIG_AFSK_TRAILER_LEN (kiss_txtail*10UL)
|
||||
#define CONFIG_AFSK_TRAILER_LEN 50UL
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* dallas_temperature_limits.h
|
||||
*
|
||||
* Created on: Nov 16, 2023
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef ETC_DALLAS_TEMPERATURE_LIMITS_H_
|
||||
#define ETC_DALLAS_TEMPERATURE_LIMITS_H_
|
||||
|
||||
|
||||
#define DALLAS_TEMPERATURE_LIMITS_LOW -32.0f
|
||||
|
||||
#define DALLAS_TEMPERATURE_LIMITS_HI 64.0f
|
||||
|
||||
#define DALLAS_TEMPERATURE_NEG_SLEW -16
|
||||
|
||||
#define DALLAS_TEMPERATURE_POS_SLEW 16
|
||||
|
||||
#define DALLAS_MAX_LIMIT_OF_DEGRADED 64U
|
||||
|
||||
|
||||
#endif /* ETC_DALLAS_TEMPERATURE_LIMITS_H_ */
|
|
@ -37,12 +37,14 @@ extern char did_dummy_data;
|
|||
ENTRY(0x1501U, gsm_sim800_simcard_status_string) \
|
||||
ENTRY(0x1502U, gsm_sim800_cellid) \
|
||||
ENTRY(0x1503U, gsm_sim800_lac) \
|
||||
ENTRY(0x5555U, main_test_string) \
|
||||
|
||||
#define DIDS_FLOAT(ENTRY) \
|
||||
ENTRY(0x2000U, rte_wx_temperature_average_external_valid, DID_EMPTY, DID_EMPTY) \
|
||||
ENTRY(0x2001U, rte_wx_temperature_internal_valid, DID_EMPTY, DID_EMPTY) \
|
||||
ENTRY(0x2002U, rte_wx_pressure_history[0], rte_wx_pressure_history[1], rte_wx_pressure_history[2]) \
|
||||
ENTRY(0x1505U, gsm_sim800_signal_level_dbm, DID_EMPTY, DID_EMPTY) \
|
||||
ENTRY(0x2222U, main_test_float, DID_EMPTY, DID_EMPTY) \
|
||||
|
||||
#define DIDS_NUMERIC(ENTRY) \
|
||||
ENTRY(0x1000U, master_time, DID_EMPTY, DID_EMPTY) \
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* misc_config.h
|
||||
* Misc configuration which doesn't match to any other place
|
||||
*
|
||||
*
|
||||
* Created on: Apr 15, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef ETC_MISC_CONFIG_H_
|
||||
#define ETC_MISC_CONFIG_H_
|
||||
|
||||
#define RTE_WX_PROBLEMS_MAX_THRESHOLD 10
|
||||
|
||||
|
||||
|
||||
#endif /* ETC_MISC_CONFIG_H_ */
|
|
@ -45,7 +45,7 @@
|
|||
/**
|
||||
* Do not uncomment this on production devices
|
||||
*/
|
||||
//#define INHIBIT_CUTOFF
|
||||
#define INHIBIT_CUTOFF
|
||||
|
||||
/**
|
||||
* Intermediate STOP2 cycle lenght within L7 or L6 mode.
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* kiss_communication_aprsmsg.h
|
||||
*
|
||||
* Created on: May 5, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef KISS_COMMUNICATION_KISS_COMMUNICATION_APRSMSG_H_
|
||||
#define KISS_COMMUNICATION_KISS_COMMUNICATION_APRSMSG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum kiss_communication_aprsmsg_transport_t {
|
||||
|
||||
/**
|
||||
* Transport KISS diagnostic messages as plain unencrypted hex-string
|
||||
* which looks like
|
||||
* HSxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
* Where 'HS' is a prefix and all 'x' are binary data. Because of
|
||||
* size limit of message content lenght, which is 67 characters,
|
||||
* this payload can have no more than 32 bytes. Each byte is
|
||||
* encoded in two characters + 'HS' prefix
|
||||
*/
|
||||
APRSMSG_TRANSPORT_HEXSTRING,
|
||||
|
||||
/**
|
||||
* Transport KISS diagnostic messages, encrypted using AES128 cipher
|
||||
* in ECB mode and then put into message as a hex string. It looks
|
||||
* like that
|
||||
* Pyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
* Where 'P' is contant prefix. 'yy' is a two-character salt to protect
|
||||
* agains problems with electronic codebook mode. The rest of 'x' is exactly
|
||||
* 62 characters, what resembles:
|
||||
* - 58 hexstring characters / 29 bytes of KISS diagnostic message,
|
||||
* - 4 hextring characters / 2 bytes of the salt (two characters)
|
||||
*
|
||||
* An example:
|
||||
* 06FF1122334455000000000000000000000000000000000000000000006D6E - clear message in binary
|
||||
* - 06FF11223344550000000 (...) - KISS message padded with zeros to 58 characters / 29 bytes
|
||||
* - 6D6E - four characters / 2 bytes of salt
|
||||
*
|
||||
* da1044bfccd776eb8b717ec3f945a4b799616a3bf4bf5ba08ba1f2d39301e5f0 - encrypted with AES128-ECB
|
||||
*
|
||||
* Pmnda1044bfccd776eb8b717ec3f945a4b799616a3bf4bf5ba08ba1f2d39301e5f0 - encrypted & transported
|
||||
* - P - constant prefix
|
||||
* - 'mn' - two characters of salt
|
||||
* - 'da1044bf (...)' ebcrypted message
|
||||
*
|
||||
* Internally the controller holds salt value from last UDS request in RTC backup register as a 16bit word.
|
||||
* Each request is checked and a salt value cannot be smaller than the previous one, the check is done by
|
||||
* 'converting' two character into one uint16_t value in way presented below"
|
||||
* 'mn' - 'm' 0x6D, 'n' 0x6E => 0x6D6E
|
||||
* Value of the salt could be reverted only if it is bigger than 0x7A00 ('~' as a first char), but it may
|
||||
* be reverted only if 0x2100 < new_salt_value < 0x2200. In another words: reverted salt must have '!'
|
||||
* as a first character.
|
||||
*
|
||||
* Because UDS requests and responses are transmitted as APRS text message salt must contain only printable
|
||||
* characters (of course except tab and space)
|
||||
*
|
||||
* Responses generated by the controller also contains salt, which is
|
||||
*
|
||||
*
|
||||
*/
|
||||
APRSMSG_TRANSPORT_ENCRYPTED_HEXSTRING,
|
||||
|
||||
|
||||
/**
|
||||
* Just an echo request
|
||||
*/
|
||||
APRSMSG_TRANSPORT_ECHO,
|
||||
|
||||
/**
|
||||
* Unallowed salt value
|
||||
*/
|
||||
APRSMSG_TRANSPORT_ERROR_SALT,
|
||||
|
||||
/**
|
||||
* Transport type is known to the application, but it is not implemented yet.
|
||||
*/
|
||||
APRSMSG_TRANSPORT_ERROR_UNSUPPORTED,
|
||||
|
||||
APRSMSG_TRANSPORT_NOT_KISS,
|
||||
|
||||
APRSMSG_TRANSPORT_UNINITIALIZED
|
||||
|
||||
} kiss_communication_aprsmsg_transport_t;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message_payload
|
||||
* @param message_payload_ln
|
||||
* @return
|
||||
*/
|
||||
kiss_communication_aprsmsg_transport_t kiss_communication_aprsmsg_check_type(uint8_t * message_payload, uint16_t message_payload_ln);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message_payload pointer to characters buffer with APRS text message, containing encoded UDS diag request
|
||||
* @param message_payload_ln length of buffer pointed by message_payload. processing will be done until first non-hex character (non 0-9 / a-f) or this length
|
||||
* @param output_binary_buffer pointer to binary buffer where decoded data will be copied to.
|
||||
* @param output_ln
|
||||
* @return length of decoded UDS request or zero if message_payload doesn't contain valid hexstring with UDS request
|
||||
*/
|
||||
uint16_t kiss_communication_aprsmsg_decode_hexstring(uint8_t * message_payload, uint16_t message_payload_ln, uint8_t * output_binary_buffer, uint16_t output_ln);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input_binary_buffer
|
||||
* @param input_ln
|
||||
* @param output_message
|
||||
* @param output_message_max_ln
|
||||
* @return
|
||||
*/
|
||||
uint16_t kiss_communication_aprsmsg_encode_hexstring(uint8_t * input_binary_buffer, uint16_t input_ln, uint8_t * output_message, uint16_t output_message_max_ln);
|
||||
|
||||
|
||||
#endif /* KISS_COMMUNICATION_KISS_COMMUNICATION_APRSMSG_H_ */
|
|
@ -44,7 +44,7 @@
|
|||
{ \
|
||||
.identifier = id, \
|
||||
.first_data = (void*)string_pointer, \
|
||||
.first_data_size = 0, \
|
||||
.first_data_size = sizeof(string_pointer), \
|
||||
.second_data = (void*)0xDEADBEEFu, \
|
||||
.second_data_size = 0, \
|
||||
.third_data = (void*)0xDEADBEEFu, \
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
#define SYSTICK_TICKS_PER_SECONDS 100
|
||||
#define SYSTICK_TICKS_PERIOD 10
|
||||
|
||||
#define INTERNAL_WATCHDOG
|
||||
#define EXTERNAL_WATCHDOG
|
||||
//#define INTERNAL_WATCHDOG
|
||||
//#define EXTERNAL_WATCHDOG
|
||||
|
||||
#define PWR_SWITCH_BOTH
|
||||
|
||||
|
@ -73,6 +73,10 @@ extern uint8_t main_woken_up;
|
|||
|
||||
extern int8_t main_cpu_load;
|
||||
|
||||
extern const float main_test_float;
|
||||
|
||||
extern const char main_test_string[11];
|
||||
|
||||
extern char after_tx_lock;
|
||||
|
||||
extern unsigned short rx10m, tx10m, digi10m, digidrop10m, kiss10m;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "stored_configuration_nvm/config_data.h"
|
||||
#include "message.h"
|
||||
|
||||
//!< Set immediately after waking up in RTC interrupt handler
|
||||
#define RTE_MAIN_WOKEN_UP_RTC_INTERRUPT 1u
|
||||
|
@ -14,7 +15,14 @@
|
|||
//!< Set after everything was reinitialized from
|
||||
#define RTE_MAIN_WOKEN_UP_EXITED 4u
|
||||
|
||||
extern uint8_t rte_main_trigger_gsm_status_packet;
|
||||
extern message_t rte_main_received_message;
|
||||
|
||||
extern message_t rte_main_message_for_transmitting;
|
||||
|
||||
//!< Trigger preparing and sending ACK
|
||||
extern uint8_t rte_main_trigger_message_ack;
|
||||
|
||||
extern uint8_t rte_main_trigger_gsm_aprsis_counters_packet;
|
||||
|
||||
extern uint8_t rte_main_trigger_gsm_loginstring_packet;
|
||||
|
||||
|
@ -22,7 +30,7 @@ extern uint8_t rte_main_trigger_gsm_telemetry_values;
|
|||
|
||||
extern uint8_t rte_main_trigger_gsm_telemetry_descriptions;
|
||||
|
||||
extern uint8_t rte_main_trigger_gsm_status_gsm;
|
||||
extern uint8_t rte_main_trigger_gsm_status;
|
||||
|
||||
//!< Trigger some reinitialization after waking up from deep sleep
|
||||
extern uint8_t rte_main_woken_up;
|
||||
|
@ -33,7 +41,6 @@ extern uint8_t rte_main_boot_cycles, rte_main_hard_faults;
|
|||
extern uint32_t rte_main_hardfault_lr, rte_main_hardfault_pc;
|
||||
|
||||
extern uint8_t rte_main_trigger_status;
|
||||
extern uint8_t rte_main_trigger_modbus_status;
|
||||
|
||||
extern uint8_t rte_main_trigger_wx_packet;
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ extern ms5611_qf_t rte_wx_ms5611_qf;
|
|||
extern bme280_qf_t rte_wx_bme280_qf;
|
||||
extern analog_wind_qf_t rte_wx_wind_qf;
|
||||
extern uint8_t rte_wx_humidity_available;
|
||||
extern uint8_t rte_wx_dallas_degraded_counter;
|
||||
|
||||
|
||||
extern umb_frame_t rte_wx_umb;
|
||||
|
@ -103,6 +104,7 @@ extern "C"
|
|||
void rte_wx_init(void);
|
||||
void rte_wx_update_last_measuremenet_timers(uint16_t measurement_type);
|
||||
void rte_wx_reset_last_measuremenet_timers(uint16_t measurement_type);
|
||||
int8_t rte_wx_check_weather_measurements(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#ifndef SOFTWARE_VERSION_H_
|
||||
#define SOFTWARE_VERSION_H_
|
||||
|
||||
#define SW_VER "EB02"
|
||||
#define SW_DATE "31102023"
|
||||
#define SW_VER "EC00"
|
||||
#define SW_DATE "05052024"
|
||||
#define SW_KISS_PROTO "B"
|
||||
|
||||
extern const char software_version_str[5];
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include "stdint.h"
|
||||
|
||||
int variant_validate_is_within_ram(uint32_t address);
|
||||
|
||||
int variant_validate_is_within_ram(void * address);
|
||||
int variant_validate_is_within_flash(void * address);
|
||||
|
||||
|
||||
#endif /* VARIANT_H_ */
|
||||
|
|
|
@ -56,7 +56,7 @@ ENTRY(Reset_Handler)
|
|||
_estack = 0x20018000; /* end of RAM */
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
_Min_Stack_Size = 0x800; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
|
|
207
src/aprsis.c
207
src/aprsis.c
|
@ -8,7 +8,10 @@
|
|||
#include "aprsis.h"
|
||||
#include "etc/aprsis_config.h"
|
||||
#include "text.h"
|
||||
#include "backup_registers.h"
|
||||
|
||||
#include "aprs/status.h"
|
||||
#include "aprs/message.h"
|
||||
|
||||
#include "gsm/sim800c.h"
|
||||
#include "gsm/sim800c_poolers.h"
|
||||
|
@ -19,6 +22,12 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#define STATIC
|
||||
#else
|
||||
#define STATIC static
|
||||
#endif
|
||||
|
||||
srl_context_t * aprsis_serial_port;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +43,7 @@ gsm_sim800_state_t * aprsis_gsm_modem_state;
|
|||
/**
|
||||
* Buffer for sending packet to aprs-is
|
||||
*/
|
||||
char aprsis_packet_tx_buffer[APRSIS_TX_BUFFER_LN];
|
||||
static char aprsis_packet_tx_buffer[APRSIS_TX_BUFFER_LN];
|
||||
|
||||
/**
|
||||
* Lenght of buffer
|
||||
|
@ -74,6 +83,16 @@ const char * aprsis_default_server_address;
|
|||
*/
|
||||
const char * aprsis_callsign_with_ssid;
|
||||
|
||||
/**
|
||||
* Pointer to callsign from configuration
|
||||
*/
|
||||
const char * aprsis_callsign;
|
||||
|
||||
/**
|
||||
* ssid from configuration
|
||||
*/
|
||||
uint8_t aprsis_ssid;
|
||||
|
||||
/**
|
||||
* Lenght of APRS-IS server address string
|
||||
*/
|
||||
|
@ -180,6 +199,109 @@ char aprsis_login_string_reveived[APRSIS_LOGIN_STRING_RECEIVED_LN];
|
|||
*/
|
||||
#define MAXIMUM_CALL_SSID_DASH_LN 10
|
||||
|
||||
/**
|
||||
* Checks if data in a buffer contains APRS message
|
||||
* @param message
|
||||
* @param message_ln
|
||||
* @return position at which content of message starts
|
||||
*/
|
||||
STATIC uint16_t aprsis_check_is_message(const uint8_t * const message, const uint16_t message_ln) {
|
||||
// example message
|
||||
// Details:"SP8EBC>APX216,TCPIP*,qAC,NINTH::SR9WXZ :tedt{0s}\r\n", '\0' <repeats 715 times>
|
||||
|
||||
// go through a buffer and look for double ':'
|
||||
|
||||
uint16_t message_start_position = 0;
|
||||
|
||||
for (int i = 0; i < message_ln; i++) {
|
||||
const uint8_t * this_character = message + i;
|
||||
|
||||
const uint8_t * next_character = message + i + 1;
|
||||
|
||||
if (*this_character == 0x00) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*this_character == ':') && (*next_character == ':')) {
|
||||
message_start_position = i + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return message_start_position;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param srl_context
|
||||
*/
|
||||
STATIC void aprsis_receive_callback(srl_context_t* srl_context) {
|
||||
|
||||
const uint8_t * buffer = srl_get_rx_buffer(srl_context);
|
||||
|
||||
const uint16_t message_ln = srl_context->srl_rx_bytes_counter;
|
||||
|
||||
// if something was actually received
|
||||
if (srl_context->srl_rx_state == SRL_RX_DONE) {
|
||||
// check if this is keepalive message
|
||||
if (*buffer == '#') {
|
||||
// set last timestamps
|
||||
aprsis_last_keepalive_ts = main_get_master_time();
|
||||
aprsis_last_keepalive_long_ts = main_get_master_time();
|
||||
|
||||
// increase received keepalive counter
|
||||
aprsis_keepalive_received_counter++;
|
||||
|
||||
// restart receiving from serial port
|
||||
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
|
||||
}
|
||||
else {
|
||||
// check if this is an aprs message
|
||||
const int message_position = aprsis_check_is_message(buffer, message_ln);
|
||||
|
||||
// if yes try to decode it
|
||||
if (message_position != 0) {
|
||||
|
||||
// prevent overwriting message received from radio channel if it hasn't been serviced yet
|
||||
if (rte_main_received_message.source == MESSAGE_SOURCE_UNINITIALIZED) {
|
||||
|
||||
// if decoding was successfull
|
||||
if (message_decode(buffer, message_ln, message_position, MESSAGE_SOURCE_APRSIS, &rte_main_received_message) == 0) {
|
||||
|
||||
// check if it is for me
|
||||
if (message_is_for_me(aprsis_callsign, aprsis_ssid, &rte_main_received_message) == 0) {
|
||||
// trigger preparing ACK
|
||||
rte_main_trigger_message_ack = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
;
|
||||
}
|
||||
|
||||
aprsis_another_received_counter++;
|
||||
|
||||
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
* @param gsm_modem_state
|
||||
* @param callsign
|
||||
* @param ssid
|
||||
* @param passcode
|
||||
* @param default_server
|
||||
* @param default_port
|
||||
* @param reset_on_timeout
|
||||
* @param callsign_with_ssid
|
||||
*/
|
||||
void aprsis_init(
|
||||
srl_context_t * context,
|
||||
gsm_sim800_state_t * gsm_modem_state,
|
||||
|
@ -212,6 +334,10 @@ void aprsis_init(
|
|||
|
||||
aprsis_reset_on_timeout = reset_on_timeout;
|
||||
|
||||
aprsis_callsign = callsign;
|
||||
|
||||
aprsis_ssid = ssid;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,7 +429,7 @@ aprsis_return_t aprsis_connect_and_login(const char * address, uint8_t address_l
|
|||
aprsis_logged = 1;
|
||||
|
||||
// trigger GSM status APRS-IS packet, when connection is ready
|
||||
rte_main_trigger_gsm_status_gsm = 1;
|
||||
rte_main_trigger_gsm_status = 1;
|
||||
|
||||
// set current timestamp as last
|
||||
aprsis_last_keepalive_ts = master_time;
|
||||
|
@ -394,29 +520,6 @@ sim800_return_t aprsis_disconnect(void) {
|
|||
return out;
|
||||
}
|
||||
|
||||
void aprsis_receive_callback(srl_context_t* srl_context) {
|
||||
|
||||
// if something was actually received
|
||||
if (srl_context->srl_rx_state == SRL_RX_DONE) {
|
||||
// check if this is keepalive message
|
||||
if (*(srl_get_rx_buffer(srl_context)) == '#') {
|
||||
aprsis_last_keepalive_ts = main_get_master_time();
|
||||
|
||||
aprsis_last_keepalive_long_ts = main_get_master_time();
|
||||
|
||||
aprsis_keepalive_received_counter++;
|
||||
|
||||
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
|
||||
}
|
||||
else {
|
||||
aprsis_another_received_counter++;
|
||||
|
||||
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pooler function which check periodically if APRS-IS connection is alive.
|
||||
*/
|
||||
|
@ -524,6 +627,11 @@ void aprsis_send_wx_frame(
|
|||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX);
|
||||
}
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
||||
float max_wind_speed = 0.0f, temp = 0.0f;
|
||||
|
@ -602,6 +710,11 @@ void aprsis_send_beacon(
|
|||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON);
|
||||
}
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
||||
aprsis_packet_tx_message_size = snprintf(
|
||||
|
@ -721,6 +834,8 @@ void aprsis_prepare_telemetry(
|
|||
|
||||
/**
|
||||
* Sends to APRS-IS prepared telemetry frame prepared in advance
|
||||
* @param async
|
||||
* @param callsign_with_ssid
|
||||
*/
|
||||
void aprsis_send_telemetry(uint8_t async, const char * callsign_with_ssid) {
|
||||
|
||||
|
@ -734,6 +849,11 @@ void aprsis_send_telemetry(uint8_t async, const char * callsign_with_ssid) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY);
|
||||
}
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
||||
aprsis_packet_tx_message_size = snprintf(
|
||||
|
@ -793,6 +913,11 @@ telemetry_description_t aprsis_send_description_telemetry(uint8_t async,
|
|||
return next;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR);
|
||||
}
|
||||
|
||||
telemetry_create_description_string(config_basic, what, main_own_aprs_msg, OWN_APRS_MSG_LN);
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
@ -831,6 +956,11 @@ void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE);
|
||||
}
|
||||
|
||||
aprsis_igated_counter++;
|
||||
|
||||
// prepare buffer for message
|
||||
|
@ -906,12 +1036,17 @@ void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid) {
|
|||
|
||||
}
|
||||
|
||||
void aprsis_send_server_conn_status(const char * callsign_with_ssid) {
|
||||
void aprsis_send_server_comm_counters(const char * callsign_with_ssid) {
|
||||
|
||||
if (aprsis_logged == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS);
|
||||
}
|
||||
|
||||
memset (aprsis_packet_tx_buffer, 0x00, APRSIS_TX_BUFFER_LN);
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
@ -938,6 +1073,11 @@ void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, ui
|
|||
return;
|
||||
}
|
||||
|
||||
if (gsm_sim800_tcpip_tx_busy() == 1) {
|
||||
// will die here
|
||||
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING);
|
||||
}
|
||||
|
||||
memset (aprsis_packet_tx_buffer, 0x00, APRSIS_TX_BUFFER_LN);
|
||||
|
||||
aprsis_tx_counter++;
|
||||
|
@ -956,7 +1096,7 @@ void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, ui
|
|||
|
||||
}
|
||||
|
||||
void aprsis_send_gpsstatus(const char * callsign_with_ssid) {
|
||||
void aprsis_send_gsm_status(const char * callsign_with_ssid) {
|
||||
if (aprsis_logged == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -979,9 +1119,22 @@ void aprsis_send_gpsstatus(const char * callsign_with_ssid) {
|
|||
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
void aprsis_send_ack_for_message(const message_t * const message) {
|
||||
aprsis_packet_tx_message_size = message_create_ack_for((uint8_t*)aprsis_packet_tx_buffer, APRSIS_TX_BUFFER_LN - 1, message);
|
||||
|
||||
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
|
||||
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
char * aprsis_get_tx_buffer(void) {
|
||||
return aprsis_packet_tx_buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t aprsis_get_aprsis_logged(void) {
|
||||
return aprsis_logged;
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
#define REGISTER_COUNTERS RTC->BKP4R
|
||||
#define REGISTER_LAST_SLTIM RTC->BKP6R
|
||||
#define REGISTER_PACKET_COUNTERS RTC->BKP7R
|
||||
#define REGISTER_RESET_CHECK_FAIL RTC->BKP8R
|
||||
#define REGISTER_ASSERT RTC->BKP9R
|
||||
#endif
|
||||
|
||||
#define BACKUP_REG_INHIBIT_PWR_SWITCH_PERIODIC_H 1u
|
||||
#define BACKUP_REG_ALL_PWRSAVE_STATES_BITMASK (0xFFu << 2)
|
||||
|
||||
|
||||
// backup registers (ParaTNC)
|
||||
// 0 ->
|
||||
// 2 -> boot and hard fault count
|
||||
|
@ -39,6 +42,8 @@
|
|||
// 5 -> monitor
|
||||
// 6 -> last sleep time
|
||||
// 7 -> weather and telemetry timers & counters
|
||||
// 8 -> counters of resets caused by validation checks failures
|
||||
// 9 -> assert register
|
||||
|
||||
// 7th register map
|
||||
// xxxxyyAA - telemetry frames counter
|
||||
|
@ -47,6 +52,12 @@
|
|||
// xxAAyyyy - value of packet_tx_beacon_counter
|
||||
// Axxxyyyy - checksum
|
||||
|
||||
// 8th register map
|
||||
// xxxxyyAA - resets caused by 'aprsis_check_connection_attempt_alive()'
|
||||
// xxxxAAyy - resets caused by 'rte_wx_check_weather_measurements()'
|
||||
// xxAAyyyy - resets caused by value of 'rte_wx_dallas_degraded_counter'
|
||||
// AAxxyyyy - resets caused by 'system_is_rtc_ok()'
|
||||
|
||||
static void backup_reg_unclock(void) {
|
||||
// enable access to backup domain
|
||||
PWR->CR1 |= PWR_CR1_DBP;
|
||||
|
@ -93,7 +104,7 @@ inline static uint8_t backup_reg_get_checksum(uint32_t reg) {
|
|||
|
||||
inline static void backup_reg_set_checksum(volatile uint32_t * reg, const uint8_t checksum) {
|
||||
|
||||
if (variant_validate_is_within_ram((const uint32_t)reg) != 0) {
|
||||
if (variant_validate_is_within_ram((void*)reg) != 0) {
|
||||
// clear existing checksum
|
||||
(*reg) &= (0xFFFFFFFF ^ 0xF0000000);
|
||||
|
||||
|
@ -421,7 +432,10 @@ uint32_t backup_reg_get_last_sleep_duration(void) {
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param in
|
||||
*/
|
||||
void backup_reg_set_last_sleep_duration(uint32_t in) {
|
||||
#ifdef PARAMETEO
|
||||
backup_reg_unclock();
|
||||
|
@ -512,6 +526,12 @@ void backup_reg_set_telemetry(uint16_t in) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param beacon_counter
|
||||
* @param meteo_counter
|
||||
* @param meteo_gsm_counter
|
||||
*/
|
||||
void backup_reg_get_packet_counters(uint8_t * beacon_counter, uint8_t * meteo_counter, uint8_t * meteo_gsm_counter) {
|
||||
#ifdef PARAMETEO
|
||||
uint32_t reg_value = REGISTER_PACKET_COUNTERS;
|
||||
|
@ -539,6 +559,12 @@ void backup_reg_get_packet_counters(uint8_t * beacon_counter, uint8_t * meteo_co
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param beacon_counter
|
||||
* @param meteo_counter
|
||||
* @param meteo_gsm_counter
|
||||
*/
|
||||
void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counter, uint8_t meteo_gsm_counter) {
|
||||
#ifdef PARAMETEO
|
||||
volatile uint32_t reg_value = REGISTER_PACKET_COUNTERS;
|
||||
|
@ -572,3 +598,115 @@ void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counte
|
|||
|
||||
#endif
|
||||
}
|
||||
|
||||
void backup_reg_increment_aprsis_check_reset(void) {
|
||||
#ifdef PARAMETEO
|
||||
// REGISTER_RESET_CHECK_FAIL
|
||||
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
|
||||
|
||||
// get existing value
|
||||
uint8_t counter = (uint8_t)(reg_value & 0xFFU);
|
||||
|
||||
// increment it
|
||||
counter++;
|
||||
|
||||
// clear existing value from register
|
||||
reg_value &= 0xFFFFFF00U;
|
||||
|
||||
// add incremented counter value
|
||||
reg_value |= counter;
|
||||
|
||||
backup_reg_unclock();
|
||||
|
||||
REGISTER_RESET_CHECK_FAIL = reg_value;
|
||||
|
||||
backup_reg_lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void backup_reg_increment_weather_measurements_check_reset(void) {
|
||||
#ifdef PARAMETEO
|
||||
// REGISTER_RESET_CHECK_FAIL
|
||||
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
|
||||
|
||||
// get existing value
|
||||
uint8_t counter = (uint8_t)((reg_value & 0xFF00U) >> 8U);
|
||||
|
||||
// increment it
|
||||
counter++;
|
||||
|
||||
// clear existing value from register
|
||||
reg_value &= 0xFFFF00FFU;
|
||||
|
||||
// add incremented counter value
|
||||
reg_value |= ((uint32_t)counter << 8U);
|
||||
|
||||
backup_reg_unclock();
|
||||
|
||||
REGISTER_RESET_CHECK_FAIL = reg_value;
|
||||
|
||||
backup_reg_lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void backup_reg_increment_dallas_degraded_reset(void) {
|
||||
#ifdef PARAMETEO
|
||||
// REGISTER_RESET_CHECK_FAIL
|
||||
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
|
||||
|
||||
// get existing value
|
||||
uint8_t counter = (uint8_t)((reg_value & 0xFF0000U) >> 16U);
|
||||
|
||||
// increment it
|
||||
counter++;
|
||||
|
||||
// clear existing value from register
|
||||
reg_value &= 0xFF00FFFFU;
|
||||
|
||||
// add incremented counter value
|
||||
reg_value |= ((uint32_t)counter << 16U);
|
||||
|
||||
backup_reg_unclock();
|
||||
|
||||
REGISTER_RESET_CHECK_FAIL = reg_value;
|
||||
|
||||
backup_reg_lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void backup_reg_increment_is_rtc_ok_check_reset(void) {
|
||||
#ifdef PARAMETEO
|
||||
// REGISTER_RESET_CHECK_FAIL
|
||||
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
|
||||
|
||||
// get existing value
|
||||
uint8_t counter = (uint8_t)((reg_value & 0xFF000000U) >> 24U);
|
||||
|
||||
// increment it
|
||||
counter++;
|
||||
|
||||
// clear existing value from register
|
||||
reg_value &= 0x00FFFFFFU;
|
||||
|
||||
// add incremented counter value
|
||||
reg_value |= ((uint32_t)counter << 24U);
|
||||
|
||||
backup_reg_unclock();
|
||||
|
||||
REGISTER_RESET_CHECK_FAIL = reg_value;
|
||||
|
||||
backup_reg_lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void backup_assert(uint32_t assert) {
|
||||
#ifdef PARAMETEO
|
||||
backup_reg_unclock();
|
||||
|
||||
REGISTER_ASSERT |= assert;
|
||||
|
||||
backup_reg_lock();
|
||||
|
||||
NVIC_SystemReset();
|
||||
#endif
|
||||
}
|
||||
|
|
2
src/io.c
2
src/io.c
|
@ -525,7 +525,7 @@ void io_vbat_meas_enable(void) {
|
|||
void io_pool_vbat_r(int16_t minutes_to_wx) {
|
||||
|
||||
// check how many minutes reamins to weather packet
|
||||
if (minutes_to_wx == 2) {
|
||||
if (minutes_to_wx == 1) {
|
||||
// hardcoded to 2 minutes
|
||||
|
||||
switch(io_vbat_r_state) {
|
||||
|
|
|
@ -124,9 +124,9 @@ int32_t kiss_callback_get_version_id(uint8_t* input_frame_from_host, uint16_t in
|
|||
uint8_t config_payload_size = 0;
|
||||
|
||||
#ifdef PARAMETEO
|
||||
config_payload_size = snprintf((char *)response_buffer + 3, buffer_size, "METEO-%s-%s", SW_VER, SW_KISS_PROTO);
|
||||
config_payload_size = snprintf((char *)response_buffer + 4, buffer_size, "METEO-%s-%s", SW_VER, SW_KISS_PROTO);
|
||||
#else
|
||||
config_payload_size = snprintf((char *)response_buffer + 3, buffer_size, "TNC-%s-%s", SW_VER, SW_KISS_PROTO);
|
||||
config_payload_size = snprintf((char *)response_buffer + 4, buffer_size, "TNC-%s-%s", SW_VER, SW_KISS_PROTO);
|
||||
#endif
|
||||
|
||||
// construct a response
|
||||
|
@ -229,6 +229,8 @@ int32_t kiss_callback_read_did(uint8_t* input_frame_from_host, uint16_t input_le
|
|||
|
||||
int32_t out = 0;
|
||||
|
||||
memset(response_buffer, 0x00, buffer_size);
|
||||
|
||||
// identifier
|
||||
uint16_t did = *(input_frame_from_host + 2) | (*(input_frame_from_host + 3) << 8);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <stored_configuration_nvm/config_data_externs.h>
|
||||
#include <stored_configuration_nvm/configuration_handler.h>
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
extern unsigned short tx10m;
|
||||
|
||||
/**
|
||||
|
@ -112,7 +114,7 @@ int32_t kiss_parse_received(uint8_t* input_frame_from_host, uint16_t input_len,
|
|||
|
||||
int32_t output = 0;
|
||||
|
||||
if (input_frame_from_host == 0x00 || ax25 == 0x00 || a == 0x00) {
|
||||
if (variant_validate_is_within_ram(input_frame_from_host) == 0x00) {
|
||||
output = -2;
|
||||
}
|
||||
else if (input_len >= OWN_APRS_MSG_LN) {
|
||||
|
@ -132,33 +134,35 @@ int32_t kiss_parse_received(uint8_t* input_frame_from_host, uint16_t input_len,
|
|||
switch (frame_type) {
|
||||
|
||||
case KISS_DATA: {
|
||||
memset(FrameBuff, 0x00, OWN_APRS_MSG_LN);
|
||||
if (variant_validate_is_within_ram(ax25) && variant_validate_is_within_ram(a)) {
|
||||
memset(FrameBuff, 0x00, OWN_APRS_MSG_LN);
|
||||
|
||||
// if this is data frame
|
||||
for (i=2, j=0; (i<input_len && *(input_frame_from_host+i) != FEND); i++, j++) {
|
||||
if (*(input_frame_from_host+i) == FESC) {
|
||||
if(*(input_frame_from_host+i+1) == TFEND)
|
||||
FrameBuff[j]=FEND;
|
||||
else if(*(input_frame_from_host+i+1) == TFESC)
|
||||
FrameBuff[j]=FESC;
|
||||
else {
|
||||
;
|
||||
// if this is data frame
|
||||
for (i=2, j=0; (i<input_len && *(input_frame_from_host+i) != FEND); i++, j++) {
|
||||
if (*(input_frame_from_host+i) == FESC) {
|
||||
if(*(input_frame_from_host+i+1) == TFEND)
|
||||
FrameBuff[j]=FEND;
|
||||
else if(*(input_frame_from_host+i+1) == TFESC)
|
||||
FrameBuff[j]=FESC;
|
||||
else {
|
||||
;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
else
|
||||
FrameBuff[j] = *(input_frame_from_host+i);
|
||||
}
|
||||
else
|
||||
FrameBuff[j] = *(input_frame_from_host+i);
|
||||
|
||||
tx10m++;
|
||||
|
||||
// keep this commented until reseting the DCD variable will be moved outside main for (;;) loop
|
||||
// while(ax25->dcd == true);
|
||||
while(a->sending == true);
|
||||
|
||||
|
||||
ax25_sendRaw(ax25,FrameBuff,j);
|
||||
afsk_txStart(a);
|
||||
}
|
||||
|
||||
tx10m++;
|
||||
|
||||
// keep this commented until reseting the DCD variable will be moved outside main for (;;) loop
|
||||
// while(ax25->dcd == true);
|
||||
while(a->sending == true);
|
||||
|
||||
|
||||
ax25_sendRaw(ax25,FrameBuff,j);
|
||||
afsk_txStart(a);
|
||||
} break;
|
||||
|
||||
case KISS_GET_RUNNING_CONFIG: {
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* kiss_communication_aprsmsg.c
|
||||
*
|
||||
* Created on: May 5, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
|
||||
#include "kiss_communication/kiss_communication_aprsmsg.h"
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_DEC_CURRENT_CHAR *(message_payload + payload_it)
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_DEC_NEXT_CHAR *(message_payload + payload_it + 1)
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_DEC_OUTPUT_IT ((payload_it - 1) / 2)
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_IS_DIGIT(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_ENC_OUTPUT_L_IT(i) (((i + 1) * 2) + 1)
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_ENC_OUTPUT_H_IT(i) ((i + 1) * 2)
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_GET_CHAR(b) kiss_communication_aprsmsg_tohexstr_lookup_table[b]
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_IS_HEXSTRING(s) ((*(s) == 'H') && (*(s + 1) == 'S'))
|
||||
|
||||
#define KISS_COMMUNICATION_APRSMSG_IS_ENCR_HEXSTRING(s) (*(s) == 'P')
|
||||
|
||||
static uint8_t kiss_communication_aprsmsg_lookup_table[] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
-1, -1, -1, -1, -1, -1, -1,
|
||||
10, 11, 12, 13, 14, 15,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1,
|
||||
10, 11, 12, 13, 14, 15};
|
||||
|
||||
static uint8_t kiss_communication_aprsmsg_tohexstr_lookup_table[] =
|
||||
{
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message_payload
|
||||
* @param message_payload_ln
|
||||
* @return
|
||||
*/
|
||||
kiss_communication_aprsmsg_transport_t kiss_communication_aprsmsg_check_type(uint8_t * message_payload, uint16_t message_payload_ln)
|
||||
{
|
||||
kiss_communication_aprsmsg_transport_t out = APRSMSG_TRANSPORT_UNINITIALIZED;
|
||||
|
||||
if (variant_validate_is_within_ram(message_payload) == 1 && message_payload_ln > 6 && message_payload_ln <= 67) {
|
||||
if (KISS_COMMUNICATION_APRSMSG_IS_HEXSTRING(message_payload)) {
|
||||
out = APRSMSG_TRANSPORT_HEXSTRING;
|
||||
}
|
||||
else if (KISS_COMMUNICATION_APRSMSG_IS_ENCR_HEXSTRING(message_payload)) {
|
||||
out = APRSMSG_TRANSPORT_ERROR_UNSUPPORTED;
|
||||
}
|
||||
else {
|
||||
out = APRSMSG_TRANSPORT_NOT_KISS;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message_payload pointer to characters buffer with APRS text message, containing encoded UDS diag request
|
||||
* @param message_payload_ln length of buffer pointed by message_payload. processing will be done until first non-hex character (non 0-9 / a-f) or this length
|
||||
* @param output_binary_buffer pointer to binary buffer where decoded data will be copied to.
|
||||
* @param output_ln
|
||||
* @return length of decoded UDS request or zero if message_payload doesn't contain valid hexstring with UDS request
|
||||
*/
|
||||
uint16_t kiss_communication_aprsmsg_decode_hexstring(uint8_t * message_payload, uint16_t message_payload_ln, uint8_t * output_binary_buffer, uint16_t output_ln)
|
||||
{
|
||||
uint8_t out = 0;
|
||||
|
||||
// iterator to go through 'message_payload' input buffer
|
||||
uint16_t payload_it = 0;
|
||||
|
||||
// high nibble
|
||||
uint8_t hn = 0;
|
||||
|
||||
// low nibble
|
||||
uint8_t ln = 0;
|
||||
|
||||
// checck if input string is located in legoit RAM memory
|
||||
if (variant_validate_is_within_ram(message_payload) == 1 && message_payload_ln > 0) {
|
||||
|
||||
// check second time of string begins with 'HS'
|
||||
if (KISS_COMMUNICATION_APRSMSG_DEC_CURRENT_CHAR == 'H' && KISS_COMMUNICATION_APRSMSG_DEC_NEXT_CHAR == 'S') {
|
||||
|
||||
// move iterator to begining of hex-characters
|
||||
payload_it += 2;
|
||||
|
||||
while (payload_it < message_payload_ln) {
|
||||
|
||||
// check if current char resembles hex base number
|
||||
if (KISS_COMMUNICATION_APRSMSG_IS_DIGIT(KISS_COMMUNICATION_APRSMSG_DEC_CURRENT_CHAR) == 0) {
|
||||
break; // if not break conversion
|
||||
}
|
||||
|
||||
if (KISS_COMMUNICATION_APRSMSG_DEC_OUTPUT_IT >= output_ln) {
|
||||
break; // no more room for output data
|
||||
}
|
||||
|
||||
hn = KISS_COMMUNICATION_APRSMSG_DEC_CURRENT_CHAR;
|
||||
ln = KISS_COMMUNICATION_APRSMSG_DEC_NEXT_CHAR;
|
||||
|
||||
// calculate index to lookup table basing on current character
|
||||
const uint8_t index_hn = hn - 0x30u;
|
||||
|
||||
// calculate index to lookup table basing on current character
|
||||
const uint8_t index_ln = ln - 0x30u;
|
||||
|
||||
// conveted byte
|
||||
const uint8_t converted_byte = (kiss_communication_aprsmsg_lookup_table[index_hn] * 0x10u) +
|
||||
kiss_communication_aprsmsg_lookup_table[index_ln];
|
||||
|
||||
// put converted byte into output array
|
||||
output_binary_buffer[KISS_COMMUNICATION_APRSMSG_DEC_OUTPUT_IT] = converted_byte;
|
||||
|
||||
payload_it += 2;
|
||||
}
|
||||
|
||||
// go through
|
||||
|
||||
out = KISS_COMMUNICATION_APRSMSG_DEC_OUTPUT_IT;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint16_t kiss_communication_aprsmsg_encode_hexstring(uint8_t * input_binary_buffer, uint16_t input_ln, uint8_t * output_message, uint16_t output_message_max_ln)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
|
||||
// iterator across input buffer
|
||||
uint16_t iterator = 0;
|
||||
|
||||
// expected lenght of output buffer. Prefix 'HS', then hex encoded binary data and null termimator at the end
|
||||
const uint16_t expected_output_ln = 2 + (input_ln * 2) + 1;
|
||||
|
||||
// if output buffer is big enought to fit
|
||||
if (output_message_max_ln > expected_output_ln) {
|
||||
|
||||
// make a room for output data
|
||||
memset(output_message, 0x00, expected_output_ln);
|
||||
|
||||
// put prefix
|
||||
*output_message = 'H';
|
||||
*(output_message + 1) = 'S';
|
||||
|
||||
while (iterator < input_ln) {
|
||||
|
||||
// extract high and low nibbled for processed byte
|
||||
const uint8_t low_nibble = input_binary_buffer[iterator] & 0xFu;
|
||||
const uint8_t high_nibble = (input_binary_buffer[iterator] & 0xF0u) >> 4;
|
||||
|
||||
output_message[KISS_COMMUNICATION_APRSMSG_ENC_OUTPUT_L_IT(iterator)] = KISS_COMMUNICATION_APRSMSG_GET_CHAR(low_nibble);
|
||||
output_message[KISS_COMMUNICATION_APRSMSG_ENC_OUTPUT_H_IT(iterator)] = KISS_COMMUNICATION_APRSMSG_GET_CHAR(high_nibble);
|
||||
|
||||
out = KISS_COMMUNICATION_APRSMSG_ENC_OUTPUT_L_IT(iterator) + 1;
|
||||
|
||||
iterator++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
|
@ -22,6 +22,10 @@
|
|||
#include <stm32l4xx.h>
|
||||
#endif
|
||||
|
||||
#define KISS_DID_SIZE_MAPPING_INT8 1
|
||||
#define KISS_DID_SIZE_MAPPING_INT16 2
|
||||
#define KISS_DID_SIZE_MAPPING_INT32 3
|
||||
|
||||
//!< Dummy variable used only as end of definition marker in tables
|
||||
char did_dummy_data;
|
||||
|
||||
|
@ -46,10 +50,10 @@ const static kiss_did_numeric_definition_t kiss_did_def[] = {
|
|||
//!< Mapping between a result of sizeof operator and a value of sizebyte
|
||||
const static uint8_t kiss_did_sizeof_to_sizebyte_mapping[5] = {
|
||||
0,// nothing
|
||||
1, // int8_t
|
||||
2, // int16_t
|
||||
KISS_DID_SIZE_MAPPING_INT8, // int8_t -> 1
|
||||
KISS_DID_SIZE_MAPPING_INT16, // int16_t -> 2
|
||||
0, // nothing
|
||||
3 // int32_t
|
||||
KISS_DID_SIZE_MAPPING_INT32 // int32_t -> 3
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -146,9 +150,9 @@ static int kiss_did_validate(kiss_did_numeric_definition_t * definition, uint8_t
|
|||
if (amount_of_data > 0) {
|
||||
|
||||
// check if DID data size an address is correct
|
||||
if ((definition->first_data_size == 0 ||
|
||||
definition->first_data_size == 1 ||
|
||||
definition->first_data_size == 4) &&
|
||||
if ((definition->first_data_size == sizeof(int8_t) ||
|
||||
definition->first_data_size == sizeof(int16_t) ||
|
||||
definition->first_data_size == sizeof(int32_t)) &&
|
||||
(uint32_t)definition->first_data > SRAM_BASE &&
|
||||
(uint32_t)definition->first_data < SRAM_BASE + SRAM1_SIZE_MAX) {
|
||||
|
||||
|
@ -158,9 +162,9 @@ static int kiss_did_validate(kiss_did_numeric_definition_t * definition, uint8_t
|
|||
// if second did is also defined
|
||||
if (amount_of_data > 1) {
|
||||
// check if DID data size is correct
|
||||
if ((definition->second_data_size == 0 ||
|
||||
definition->second_data_size == 1 ||
|
||||
definition->second_data_size == 4) &&
|
||||
if ((definition->first_data_size == sizeof(int8_t) ||
|
||||
definition->first_data_size == sizeof(int16_t) ||
|
||||
definition->first_data_size == sizeof(int32_t)) &&
|
||||
(uint32_t)definition->second_data > SRAM_BASE &&
|
||||
(uint32_t)definition->second_data < SRAM_BASE + SRAM1_SIZE_MAX) {
|
||||
|
||||
|
@ -171,9 +175,9 @@ static int kiss_did_validate(kiss_did_numeric_definition_t * definition, uint8_t
|
|||
if (amount_of_data > 2) {
|
||||
|
||||
// check third DID source data size
|
||||
if ((definition->third_data_size == 0 ||
|
||||
definition->third_data_size == 1 ||
|
||||
definition->third_data_size == 4) &&
|
||||
if ((definition->first_data_size == sizeof(int8_t) ||
|
||||
definition->first_data_size == sizeof(int16_t) ||
|
||||
definition->first_data_size == sizeof(int32_t)) &&
|
||||
(uint32_t)definition->third_data > SRAM_BASE &&
|
||||
(uint32_t)definition->third_data < SRAM_BASE + SRAM1_SIZE_MAX) {
|
||||
|
||||
|
@ -209,6 +213,13 @@ static int kiss_did_validate(kiss_did_numeric_definition_t * definition, uint8_t
|
|||
|
||||
}
|
||||
|
||||
// special case for float DIDs
|
||||
if (out == 0) {
|
||||
if (kiss_did_validate_is_float(definition) != 0) {
|
||||
out = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (amount != 0) {
|
||||
*amount = amount_of_data;
|
||||
}
|
||||
|
@ -245,7 +256,7 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
* 0y - If most significant bit is set to zero, size_byte will
|
||||
* signalize string DID as ASCII characters from basic ASIC
|
||||
* table are from range 0 to 127
|
||||
* 10 - If most significant bit is set to zero AND next significant
|
||||
* 10 - If most significant bit is set to one AND next significant
|
||||
* bit is set to zero this DID returns integer data. In such
|
||||
* case three groups of two bits controls a size of data according
|
||||
* to 'kiss_did_sizeof_to_sizebyte_mapping'. If a group of two bits
|
||||
|
@ -314,12 +325,19 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
// move after DID value and size_byte
|
||||
output_buffer += 3;
|
||||
|
||||
// room for size byte
|
||||
out++;
|
||||
|
||||
// and for DID value itself
|
||||
out += 2;
|
||||
|
||||
//append first data source
|
||||
memcpy(output_buffer, found.first_data, found.first_data_size);
|
||||
|
||||
//move forward a poiner to response buffer
|
||||
output_buffer += found.first_data_size;
|
||||
|
||||
// room for first value returned by DID
|
||||
out += found.first_data_size;
|
||||
|
||||
if (number_of_data_source > 1) {
|
||||
|
@ -342,12 +360,6 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
out += found.third_data_size;
|
||||
}
|
||||
|
||||
// also include size_byte in this calculation
|
||||
out++;
|
||||
|
||||
// include DID value itself
|
||||
out += 2;
|
||||
|
||||
}
|
||||
else if (found.identifier != 0xFFFFu && is_valid == 1 && is_float == 1) {
|
||||
|
||||
|
@ -365,13 +377,19 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
// move after DID value and size_byte
|
||||
output_buffer += 3;
|
||||
|
||||
// room for size byte stored in output buffer
|
||||
out++;
|
||||
|
||||
// room for DID number in output buffer
|
||||
out += 2;
|
||||
|
||||
//append first data source
|
||||
memcpy(output_buffer, found.first_data, sizeof(float));
|
||||
|
||||
//move forward a poiner to response buffer
|
||||
output_buffer += sizeof(float);
|
||||
|
||||
out += found.first_data_size;
|
||||
out += sizeof(float);
|
||||
|
||||
if (number_of_data_source > 1) {
|
||||
//append second data source
|
||||
|
@ -393,12 +411,6 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
out += sizeof(float);
|
||||
}
|
||||
|
||||
// also include size_byte in this calculation
|
||||
out++;
|
||||
|
||||
// include DID value itself
|
||||
out += 2;
|
||||
|
||||
}
|
||||
else if (found.identifier != 0xFFFFu && is_string == 1) {
|
||||
|
||||
|
@ -406,18 +418,33 @@ uint8_t kiss_did_response(uint16_t identifier, uint8_t * output_buffer, uint16_t
|
|||
output_buffer[0] = (identifier & 0xFF);
|
||||
output_buffer[1] = (identifier & 0xFF00) >> 8;
|
||||
|
||||
// if this is a string DID
|
||||
const char * str = (char *)found.first_data;
|
||||
// move after DID value and size_byte
|
||||
output_buffer += 2;
|
||||
|
||||
const size_t str_len = strlen(str);
|
||||
// if this is a string DID
|
||||
const void * str = (void *)found.first_data;
|
||||
|
||||
const size_t str_len = found.first_data_size;
|
||||
|
||||
memset(output_buffer, 0x00, buffer_ln - 2);
|
||||
|
||||
if (str_len - 2 > buffer_ln) {
|
||||
memcpy(output_buffer + 2, found.first_data, buffer_ln);
|
||||
memcpy(output_buffer, str, buffer_ln - 2);
|
||||
|
||||
out = buffer_ln - 2;
|
||||
}
|
||||
else {
|
||||
memcpy(output_buffer, found.first_data, str_len);
|
||||
memcpy(output_buffer, str, str_len);
|
||||
|
||||
out = str_len;
|
||||
}
|
||||
|
||||
// include DID number itself
|
||||
out += 2;
|
||||
|
||||
}
|
||||
else {
|
||||
out = 0;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
|
167
src/main.c
167
src/main.c
|
@ -94,8 +94,11 @@
|
|||
#include "drivers/dallas.h"
|
||||
|
||||
#include <kiss_communication/kiss_communication.h>
|
||||
#include <kiss_communication/kiss_communication_aprsmsg.h>
|
||||
#include <etc/kiss_configuation.h>
|
||||
|
||||
#include <etc/dallas_temperature_limits.h>
|
||||
|
||||
#define SOH 0x01
|
||||
|
||||
//#include "variant.h"
|
||||
|
@ -120,8 +123,8 @@
|
|||
// 3 -> controller configuration status
|
||||
// 4 -> wakeup events MSB, sleep events LSB
|
||||
// 5 -> monitor
|
||||
// 6 -> weather and telemetry timers & counters
|
||||
|
||||
// 6 -> last sleep time
|
||||
// 7 -> weather and telemetry timers & counters
|
||||
|
||||
#define CONFIG_FIRST_RESTORED (1)
|
||||
#define CONFIG_FIRST_FAIL_RESTORING (1 << 1)
|
||||
|
@ -188,28 +191,31 @@ int32_t main_two_second_pool_timer = 2000;
|
|||
//! ten second pool interval
|
||||
int32_t main_ten_second_pool_timer = 10000;
|
||||
|
||||
//! one hour interval incremented inside one minute
|
||||
int8_t main_one_hour_pool_timer = 60;
|
||||
|
||||
//! serial context for UART used to KISS
|
||||
srl_context_t main_kiss_srl_ctx;
|
||||
static srl_context_t main_kiss_srl_ctx;
|
||||
|
||||
//! serial context for UART used for comm with wx sensors
|
||||
srl_context_t main_wx_srl_ctx;
|
||||
static srl_context_t main_wx_srl_ctx;
|
||||
|
||||
#if defined(PARAMETEO)
|
||||
//! serial context for communication with GSM module
|
||||
srl_context_t main_gsm_srl_ctx;
|
||||
static srl_context_t main_gsm_srl_ctx;
|
||||
#endif
|
||||
|
||||
//! operation mode of USART1 (RS232 on RJ45 socket)
|
||||
main_usart_mode_t main_usart1_kiss_mode = USART_MODE_UNDEF;
|
||||
static main_usart_mode_t main_usart1_kiss_mode = USART_MODE_UNDEF;
|
||||
|
||||
//! operation mode of USART2 (RS485)
|
||||
main_usart_mode_t main_usart2_wx_mode = USART_MODE_UNDEF;
|
||||
static main_usart_mode_t main_usart2_wx_mode = USART_MODE_UNDEF;
|
||||
|
||||
//! function configuration for left button on ParaMETEO
|
||||
configuration_button_function_t main_button_one_left;
|
||||
static configuration_button_function_t main_button_one_left;
|
||||
|
||||
//! function configuration for right button on ParaMETEO
|
||||
configuration_button_function_t main_button_two_right;
|
||||
static configuration_button_function_t main_button_two_right;
|
||||
|
||||
//! a pointer to KISS context
|
||||
srl_context_t* main_kiss_srl_ctx_ptr;
|
||||
|
@ -251,6 +257,21 @@ char main_string_longitude[9];
|
|||
char main_callsign_with_ssid[10];
|
||||
|
||||
uint8_t main_small_buffer[KISS_CONFIG_DIAGNOSTIC_BUFFER_LN];
|
||||
#if defined(PARAMETEO)
|
||||
|
||||
//! Lenght of a buffer for KISS diagnostic request
|
||||
#define MAIN_KISS_FROM_MESSAGE_LEN 33
|
||||
|
||||
//! KISS (diagnostic) request decoded from APRS message
|
||||
static uint8_t main_kiss_from_message[MAIN_KISS_FROM_MESSAGE_LEN];
|
||||
|
||||
static uint8_t main_kiss_from_message_ln = 0;
|
||||
|
||||
//! binary response to DID request from APRS message
|
||||
static uint8_t main_kiss_response_message[32];
|
||||
|
||||
static uint8_t main_kiss_response_message_ln = 0;
|
||||
#endif
|
||||
|
||||
char main_symbol_f = '/';
|
||||
char main_symbol_s = '#';
|
||||
|
@ -287,6 +308,10 @@ telemetry_description_t main_telemetry_description = TELEMETRY_NOTHING;
|
|||
|
||||
char after_tx_lock;
|
||||
|
||||
const float main_test_float = 123.4f;
|
||||
|
||||
const char main_test_string[11] = "1234556aaa\0";
|
||||
|
||||
unsigned short rx10m = 0, tx10m = 0, digi10m = 0, digidrop10m = 0, kiss10m = 0;
|
||||
|
||||
static void message_callback(struct AX25Msg *msg) {
|
||||
|
@ -1237,25 +1262,78 @@ int main(int argc, char* argv[]){
|
|||
|
||||
// receive callback for communicatio with the modem
|
||||
gsm_sim800_rx_done_event_handler(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||
|
||||
//srl_reset(main_gsm_srl_ctx_ptr);
|
||||
}
|
||||
|
||||
if (main_gsm_srl_ctx_ptr->srl_tx_state == SRL_TX_IDLE) {
|
||||
gsm_sim800_tx_done_event_handler(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||
}
|
||||
|
||||
if (rte_main_trigger_gsm_status_gsm == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
|
||||
rte_main_trigger_gsm_status_gsm = 0;
|
||||
// if message ACK has been scheduled
|
||||
if (rte_main_trigger_message_ack == 1) {
|
||||
// if TCP/IP connection is not busy and received message comes from APRS-IS
|
||||
if ((rte_main_received_message.source == MESSAGE_SOURCE_APRSIS || rte_main_received_message.source == MESSAGE_SOURCE_APRSIS_HEXCNTR)
|
||||
&& gsm_sim800_tcpip_tx_busy() == 0) {
|
||||
|
||||
aprsis_send_gpsstatus((const char *)&main_callsign_with_ssid);
|
||||
// clear ACK request
|
||||
rte_main_trigger_message_ack = 0;
|
||||
|
||||
// create and send ACK for this message
|
||||
aprsis_send_ack_for_message(&rte_main_received_message);
|
||||
|
||||
rte_main_received_message.source = MESSAGE_SOURCE_UNINITIALIZED;
|
||||
|
||||
// decode message, do it after ACK is scheduled to be sure about right sequence
|
||||
const kiss_communication_aprsmsg_transport_t type = kiss_communication_aprsmsg_check_type(rte_main_received_message.content, MESSAGE_MAX_LENGHT);
|
||||
|
||||
// decode HEXSTRING
|
||||
if (type == APRSMSG_TRANSPORT_HEXSTRING) {
|
||||
main_kiss_from_message_ln = kiss_communication_aprsmsg_decode_hexstring(rte_main_received_message.content, rte_main_received_message.content_ln, main_kiss_from_message + 1, MAIN_KISS_FROM_MESSAGE_LEN - 1);
|
||||
}
|
||||
else {
|
||||
// zero message lenght if message cannot be decoded for some reason
|
||||
main_kiss_from_message_ln = 0;
|
||||
}
|
||||
|
||||
// if KISS request has been parsed from APRS message
|
||||
if (main_kiss_from_message_ln != 0) {
|
||||
// put artificial FEND at the begining of a buffer to make it compatible with 'kiss_parse_received'
|
||||
*(main_kiss_from_message) = FEND;
|
||||
|
||||
// parse KISS request
|
||||
const uint8_t kiss_response_message_ln = kiss_parse_received(main_kiss_from_message, main_kiss_from_message_ln, NULL, NULL, main_kiss_response_message, MAIN_KISS_FROM_MESSAGE_LEN);
|
||||
|
||||
// if a response was generated
|
||||
if (kiss_response_message_ln > 0) {
|
||||
// check if a beginning and an end of generated response contains FEND.
|
||||
if ((*(main_kiss_response_message) == FEND) && (*(main_kiss_response_message + kiss_response_message_ln - 1) == FEND)) {
|
||||
// if yes encode the response w/o them
|
||||
rte_main_message_for_transmitting.content_ln = kiss_communication_aprsmsg_encode_hexstring(main_kiss_response_message + 1, kiss_response_message_ln - 2, rte_main_message_for_transmitting.content, MESSAGE_MAX_LENGHT);
|
||||
}
|
||||
else {
|
||||
rte_main_message_for_transmitting.content_ln = kiss_communication_aprsmsg_encode_hexstring(main_kiss_response_message, kiss_response_message_ln, rte_main_message_for_transmitting.content, MESSAGE_MAX_LENGHT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (rte_main_received_message.source == MESSAGE_SOURCE_RADIO) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (rte_main_trigger_gsm_status == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
|
||||
rte_main_trigger_gsm_status = 0;
|
||||
|
||||
aprsis_send_gsm_status((const char *)&main_callsign_with_ssid);
|
||||
}
|
||||
|
||||
// if GSM status message is triggered and GSM module is not busy transmitting something else
|
||||
if (rte_main_trigger_gsm_status_packet == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
|
||||
rte_main_trigger_gsm_status_packet = 0;
|
||||
if (rte_main_trigger_gsm_aprsis_counters_packet == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
|
||||
rte_main_trigger_gsm_aprsis_counters_packet = 0;
|
||||
|
||||
aprsis_send_server_conn_status((const char *)&main_callsign_with_ssid);
|
||||
aprsis_send_server_comm_counters((const char *)&main_callsign_with_ssid);
|
||||
}
|
||||
|
||||
// if loginstring packet (APRS status packet with loginstring received from a server)
|
||||
|
@ -1444,19 +1522,6 @@ int main(int argc, char* argv[]){
|
|||
wx_get_all_measurements(main_config_data_wx_sources, main_config_data_mode, main_config_data_umb, main_config_data_rtu);
|
||||
}
|
||||
|
||||
// check if there is a request to send ModbusRTU error status message
|
||||
if (rte_main_trigger_modbus_status == 1 && main_modbus_rtu_master_enabled == 1) {
|
||||
rtu_serial_get_status_string(&rte_rtu_pool_queue, main_wx_srl_ctx_ptr, main_own_aprs_msg, OWN_APRS_MSG_LN, &main_own_aprs_msg_len);
|
||||
|
||||
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len);
|
||||
|
||||
afsk_txStart(&main_afsk);
|
||||
|
||||
rte_main_trigger_modbus_status = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
backup_reg_set_monitor(3);
|
||||
|
||||
main_wx_sensors_pool_timer = 65500;
|
||||
|
@ -1486,18 +1551,58 @@ int main(int argc, char* argv[]){
|
|||
|
||||
}
|
||||
|
||||
if (main_config_data_gsm->aprsis_enable != 0) {
|
||||
if ((main_config_data_gsm->aprsis_enable != 0) && (main_config_data_mode->gsm == 1)) {
|
||||
|
||||
if (pwr_save_is_currently_cutoff() == 0) {
|
||||
// this checks when APRS-IS was alive last time and when any packet
|
||||
// has been sent to the server.
|
||||
const int i_am_ok_with_aprsis = aprsis_check_connection_attempt_alive();
|
||||
|
||||
if (i_am_ok_with_aprsis != 0) {
|
||||
|
||||
// increase counter stored in RTC backup register
|
||||
backup_reg_increment_aprsis_check_reset();
|
||||
|
||||
// trigger a restart
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rte_wx_check_weather_measurements() == 0) {
|
||||
backup_reg_increment_weather_measurements_check_reset();
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
if (rte_wx_dallas_degraded_counter > DALLAS_MAX_LIMIT_OF_DEGRADED) {
|
||||
backup_reg_increment_dallas_degraded_reset();
|
||||
|
||||
rte_main_reboot_req = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ONE HOUR POOLING
|
||||
*/
|
||||
if (--main_one_hour_pool_timer < 0) {
|
||||
main_one_hour_pool_timer = 60;
|
||||
|
||||
// check if RTC is working correctly
|
||||
if (system_is_rtc_ok() == 0) {
|
||||
|
||||
backup_reg_increment_is_rtc_ok_check_reset();
|
||||
|
||||
rte_main_reboot_req = 1;
|
||||
}
|
||||
|
||||
if ((main_config_data_gsm->aprsis_enable != 0) && (main_config_data_mode->gsm == 1)) {
|
||||
rte_main_trigger_gsm_aprsis_counters_packet = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
main_one_minute_pool_timer = 60000;
|
||||
}
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
|||
|
||||
// ASSEMBLY QUALITY FACTORS
|
||||
|
||||
// if there weren't any erros related to the communication with DS12B20 from previous function call
|
||||
// if there weren't any errors related to the communication with DS12B20 from previous function call
|
||||
if (rte_wx_error_dallas_qf == DALLAS_QF_UNKNOWN) {
|
||||
dallas_qf = rte_wx_current_dallas_qf; // it might be DEGRADATED so we need to copy a value directly
|
||||
|
||||
|
@ -579,10 +579,6 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
|||
else {
|
||||
packet_tx_trigger_tcp = 0;
|
||||
}
|
||||
|
||||
if (system_is_rtc_ok() == 0) {
|
||||
rte_main_reboot_req = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
packet_tx_telemetry_descr_counter = 0;
|
||||
|
|
|
@ -14,12 +14,20 @@ uint8_t rte_main_reboot_req = 0;
|
|||
uint8_t rte_main_boot_cycles = 0, rte_main_hard_faults = 0;
|
||||
|
||||
uint8_t rte_main_trigger_status = 0;
|
||||
uint8_t rte_main_trigger_modbus_status = 0;
|
||||
|
||||
uint8_t rte_main_trigger_wx_packet = 0;
|
||||
|
||||
//!< message received from APRS-IS or RF radio network
|
||||
message_t rte_main_received_message;
|
||||
|
||||
//!< message to be send via APRS-IS or RF radio network
|
||||
message_t rte_main_message_for_transmitting;
|
||||
|
||||
#ifdef PARAMETEO
|
||||
uint8_t rte_main_trigger_gsm_status_packet = 0;
|
||||
//!< Trigger preparing and sending ACK
|
||||
uint8_t rte_main_trigger_message_ack = 0;
|
||||
|
||||
uint8_t rte_main_trigger_gsm_aprsis_counters_packet = 0;
|
||||
|
||||
//!< Trigger sending status packet with received APRS is login string
|
||||
uint8_t rte_main_trigger_gsm_loginstring_packet = 0;
|
||||
|
@ -31,7 +39,7 @@ uint8_t rte_main_trigger_gsm_telemetry_values = 0;
|
|||
uint8_t rte_main_trigger_gsm_telemetry_descriptions = 0;
|
||||
|
||||
//!<
|
||||
uint8_t rte_main_trigger_gsm_status_gsm = 0;
|
||||
uint8_t rte_main_trigger_gsm_status = 0;
|
||||
|
||||
//!< Trigger some reinitialization after waking up from deep sleep
|
||||
uint8_t rte_main_woken_up = 0;
|
||||
|
|
85
src/rte_wx.c
85
src/rte_wx.c
|
@ -9,6 +9,11 @@
|
|||
#include <rte_wx.h>
|
||||
#include <wx_handler.h>
|
||||
#include "main.h"
|
||||
#include "misc_config.h"
|
||||
|
||||
#ifndef RTE_WX_PROBLEMS_MAX_THRESHOLD
|
||||
#define RTE_WX_PROBLEMS_MAX_THRESHOLD 20
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A little word of explanataion:
|
||||
|
@ -66,6 +71,7 @@ ms5611_qf_t rte_wx_ms5611_qf = MS5611_QF_UNKNOWN;
|
|||
bme280_qf_t rte_wx_bme280_qf = BME280_QF_UKNOWN;
|
||||
analog_wind_qf_t rte_wx_wind_qf = AN_WIND_QF_UNKNOWN;
|
||||
uint8_t rte_wx_humidity_available = 0;
|
||||
uint8_t rte_wx_dallas_degraded_counter = 0;
|
||||
|
||||
|
||||
umb_frame_t rte_wx_umb;
|
||||
|
@ -79,9 +85,15 @@ uint8_t rte_wx_davis_station_avaliable = 0;
|
|||
uint8_t rte_wx_davis_loop_packet_avaliable = 0;
|
||||
davis_loop_t rte_wx_davis_loop_content;
|
||||
|
||||
uint8_t rte_wx_problems_wind_buffers = 0; //!< Problems detected with buffers content
|
||||
uint8_t rte_wx_problems_wind_values = 0; //!< Problems with values calculated from buffers content
|
||||
|
||||
void rte_wx_init(void) {
|
||||
int i = 0;
|
||||
|
||||
rte_wx_problems_wind_buffers = 0;
|
||||
rte_wx_problems_wind_values = 0;
|
||||
|
||||
for (; i < WIND_AVERAGE_LEN; i++) {
|
||||
rte_wx_windspeed[i] = 0;
|
||||
rte_wx_winddirection[i] = 0;
|
||||
|
@ -114,3 +126,76 @@ void rte_wx_reset_last_measuremenet_timers(uint16_t parameter_type) {
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if weather measurements looks to be valid and if they
|
||||
* are changing over time. The function shall be called in one minute interval.
|
||||
* @return
|
||||
*/
|
||||
int8_t rte_wx_check_weather_measurements(void) {
|
||||
int8_t looks_good = 1;
|
||||
|
||||
uint8_t i = 0; // loop iterator
|
||||
|
||||
// go through wind direction buffer and checks if it contains the same value
|
||||
for (i = 0; i < WIND_AVERAGE_LEN - 1; i++) {
|
||||
if (rte_wx_winddirection[i] != rte_wx_winddirection[i + 1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if an end of the buffer has been reached
|
||||
if (i >= WIND_AVERAGE_LEN - 1) {
|
||||
rte_wx_problems_wind_buffers++;
|
||||
}
|
||||
|
||||
// go through wind speed buffer and checks if it contains the same value
|
||||
for (i = 0; i < WIND_AVERAGE_LEN - 1; i++) {
|
||||
if (rte_wx_windspeed[i] != rte_wx_windspeed[i + 1]) {
|
||||
break;
|
||||
}
|
||||
|
||||
// break the loop if the windspeed is zero anywhere, not to reset
|
||||
// periodically if wind sensor is not connected.
|
||||
if (rte_wx_windspeed[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if an end of the buffer has been reached
|
||||
if (i >= WIND_AVERAGE_LEN - 1) {
|
||||
rte_wx_problems_wind_buffers++;
|
||||
}
|
||||
|
||||
// check if average wind speed is different from zero and the same than gusts
|
||||
if (rte_wx_average_windspeed != 0 &&
|
||||
(rte_wx_average_windspeed == rte_wx_max_windspeed))
|
||||
{
|
||||
// if so a wind sensor had been blocked by icing very rapidly
|
||||
// before next DMA interrupt so rte_wx_windspeed is also
|
||||
// not updated at all
|
||||
rte_wx_problems_wind_values++;
|
||||
}
|
||||
|
||||
// check if wind direction equals exactly north (zero degrees)
|
||||
if (rte_wx_average_winddirection == 0) {
|
||||
// open wind direction input (anemometer disconnected) gives
|
||||
// a reading of about 6 do 8 degrees. If it is stuck on zero
|
||||
// the U->f converted or its reference clock generator
|
||||
// might not work at all
|
||||
rte_wx_problems_wind_values++;
|
||||
}
|
||||
else {
|
||||
rte_wx_problems_wind_values = 0;
|
||||
}
|
||||
|
||||
if (rte_wx_problems_wind_values > RTE_WX_PROBLEMS_MAX_THRESHOLD) {
|
||||
looks_good = 0;
|
||||
}
|
||||
|
||||
if (rte_wx_problems_wind_buffers > RTE_WX_PROBLEMS_MAX_THRESHOLD * 3) {
|
||||
looks_good = 0;
|
||||
}
|
||||
|
||||
return looks_good;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <stm32l4xx_ll_crc.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
/** EBxx
|
||||
* STM32L476RE, 512KB flash mem, last flash memory page
|
||||
* 0x0807F800 - 0x0807FFFF; 2 K; Page 383
|
||||
*
|
||||
|
@ -36,9 +36,20 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define CONFIG_SECTION_FIRST_START 0x0801E800
|
||||
#define CONFIG_SECTION_SECOND_START 0x0801F000
|
||||
#define CONFIG_SECTION_DEFAULT_START 0x0801E000
|
||||
/** ECxx
|
||||
* STM32L476RE, 512KB flash mem, last flash memory page
|
||||
* 0x0807F800 - 0x0807FFFF; 2 K; Page 383
|
||||
*
|
||||
* __config_section_default_start = 0x08030000;
|
||||
__config_section_first_start = 0x08030800;
|
||||
__config_section_second_start = 0x08031000;
|
||||
__config_section_third_start = 0x0801F800;
|
||||
*
|
||||
*/
|
||||
|
||||
#define CONFIG_SECTION_FIRST_START 0x08030800 //0x0801E800
|
||||
#define CONFIG_SECTION_SECOND_START 0x08031000 //0x0801F000
|
||||
#define CONFIG_SECTION_DEFAULT_START 0x08030000 //0x0801E000
|
||||
|
||||
#define CONFIG_MODE_PGM_CNTR 0x0
|
||||
#define CONFIG_MODE_OFSET 0x20 // Current size: 0x14, free: 0x0C
|
||||
|
@ -56,6 +67,9 @@ const uint32_t * const config_section_first_start = (const uint32_t *)CONFIG_S
|
|||
const uint32_t * const config_section_second_start = (const uint32_t *)CONFIG_SECTION_SECOND_START;
|
||||
const uint32_t * const config_section_default_start = (const uint32_t *)CONFIG_SECTION_DEFAULT_START;
|
||||
|
||||
uint8_t config_engineering_1 = 0xFFU;
|
||||
uint8_t config_engineering_2 = 0xFFU;
|
||||
|
||||
#ifdef PARAMETEO
|
||||
#define STRUCT_COUNT 6
|
||||
#endif
|
||||
|
@ -638,6 +652,9 @@ void configuration_handler_load_configuration(configuration_handler_region_t reg
|
|||
|
||||
configuration_handler_loaded = region;
|
||||
|
||||
config_engineering_1 = main_config_data_basic->engineering1;
|
||||
config_engineering_2 = main_config_data_basic->engineering2;
|
||||
|
||||
}
|
||||
|
||||
kiss_communication_nrc_t configuration_handler_erase_startup(void) {
|
||||
|
|
|
@ -7,8 +7,28 @@
|
|||
|
||||
#include "variant.h"
|
||||
|
||||
int variant_validate_is_within_ram(uint32_t address) {
|
||||
if (address != 0x00) {
|
||||
#ifdef STM32L471xx
|
||||
#include <stm32l4xx.h>
|
||||
#endif
|
||||
|
||||
int variant_validate_is_within_ram(void * address) {
|
||||
|
||||
uint32_t addr_value = (uint32_t)address;
|
||||
|
||||
if (addr_value > SRAM_BASE &&
|
||||
addr_value < SRAM_BASE + SRAM1_SIZE_MAX) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int variant_validate_is_within_flash(void * address) {
|
||||
uint32_t addr_value = (uint32_t)address;
|
||||
|
||||
if (addr_value > FLASH_BASE &&
|
||||
addr_value < FLASH_BANK1_END) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -180,7 +180,7 @@ void wx_pool_anemometer(const config_data_wx_sources_t * const config_sources, c
|
|||
short i = 0;
|
||||
uint8_t average_ln;
|
||||
|
||||
int32_t modbus_retval;
|
||||
int32_t modbus_retval = MODBUS_RET_UNINITIALIZED;
|
||||
uint16_t scaled_windspeed = 0;
|
||||
|
||||
//#ifdef STM32L471xx
|
||||
|
|
|
@ -19,8 +19,43 @@
|
|||
#include <modbus_rtu/rtu_getters.h>
|
||||
#include <modbus_rtu/rtu_return_values.h>
|
||||
|
||||
#include <etc/dallas_temperature_limits.h>
|
||||
|
||||
#define WX_MAX_TEMPERATURE_SLEW_RATE 4.0f
|
||||
|
||||
inline static int8_t wx_handler_temperature_check_slew(const float last, const float_average_t* average) {
|
||||
|
||||
// 0 -> OK
|
||||
int8_t result = 0;
|
||||
|
||||
float avg = 0.0f;
|
||||
|
||||
// continue only if average circular buffer is completely full
|
||||
if (float_get_nonfull(average) == 0) {
|
||||
|
||||
// get current average
|
||||
avg = float_get_average(average);
|
||||
|
||||
// get difference
|
||||
avg = avg - last;
|
||||
|
||||
// resuse result variable to save stack space
|
||||
result = (int8_t)avg;
|
||||
|
||||
if (result < DALLAS_TEMPERATURE_NEG_SLEW) {
|
||||
result = 1;
|
||||
}
|
||||
else if (result > DALLAS_TEMPERATURE_POS_SLEW) {
|
||||
result = 1;
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const config_sources, const config_data_mode_t * const config_mode, const config_data_umb_t * const config_umb, const config_data_rtu_t * const config_rtu, float * output) {
|
||||
|
||||
|
||||
|
@ -31,6 +66,8 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co
|
|||
|
||||
float temperature = 0.0f;
|
||||
|
||||
float dallas_temperature = 0.0f;
|
||||
|
||||
// choose main temperature source from the configuration. main sensor is something which is used to send data though aprs
|
||||
switch(config_sources->temperature) {
|
||||
// controller measures two temperatures
|
||||
|
@ -69,7 +106,14 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co
|
|||
// this function has blockin I/O which also adds a delay required by MS5611
|
||||
// sensor to finish data acquisition after the pressure measurement
|
||||
// is triggered.
|
||||
wx_get_temperature_dallas();
|
||||
dallas_temperature = dallas_query(&rte_wx_current_dallas_qf);
|
||||
|
||||
// check against excessive slew rate
|
||||
const uint8_t dallas_slew_exceeded = wx_handler_temperature_check_slew(dallas_temperature, &rte_wx_dallas_average);
|
||||
|
||||
if (dallas_slew_exceeded > 0) {
|
||||
rte_wx_current_dallas_qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
}
|
||||
|
||||
#ifdef STM32L471xx
|
||||
// measure temperature from PT100 sensor if it is selected as main temperature sensor
|
||||
|
@ -81,11 +125,32 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co
|
|||
}
|
||||
#endif
|
||||
|
||||
if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf != DALLAS_QF_NOT_AVALIABLE) {
|
||||
if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_FULL) {
|
||||
// updating last good measurement time
|
||||
wx_last_good_temperature_time = master_time;
|
||||
|
||||
// include current temperature into the average
|
||||
float_average(dallas_temperature, &rte_wx_dallas_average);
|
||||
|
||||
temperature = float_get_average(&rte_wx_dallas_average);
|
||||
|
||||
#if defined(STM32L471xx)
|
||||
rte_wx_temperature_average_dallas = (int16_t)(temperature * 10.0f);
|
||||
#endif
|
||||
|
||||
parameter_result = parameter_result | WX_HANDLER_PARAMETER_RESULT_TEMPERATURE;
|
||||
}
|
||||
else if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_DEGRADATED) {
|
||||
// if there were a communication error set the error to unavaliable
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
|
||||
// increase degraded quality factor counter
|
||||
rte_wx_dallas_degraded_counter++;
|
||||
}
|
||||
else if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_NOT_AVALIABLE) {
|
||||
// if there were a communication error set the error to unavaliable
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -135,60 +200,9 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co
|
|||
*output = temperature;
|
||||
}
|
||||
|
||||
//#if defined(STM32L471xx)
|
||||
// // get modbus temperature reading regardless if it has been chosen as main
|
||||
// if (config_mode->wx_modbus == 1) {
|
||||
// rtu_get_temperature(&rte_wx_temperature_average_modbus, config_rtu);
|
||||
// }
|
||||
//
|
||||
// // get temperature from dallas sensor if this isn't a sensor of choice
|
||||
// if (config_sources->temperature != WX_SOURCE_INTERNAL) {
|
||||
// wx_get_temperature_dallas();
|
||||
// }
|
||||
//
|
||||
// rte_wx_temperature_average_internal = (int16_t)(rte_wx_temperature_internal * 10.0f);
|
||||
//#endif
|
||||
|
||||
return parameter_result;
|
||||
}
|
||||
|
||||
int32_t wx_get_temperature_dallas() {
|
||||
|
||||
int32_t output = 0;
|
||||
|
||||
float temperature = 0.0f;
|
||||
|
||||
// get the value from dallas one-wire sensor
|
||||
temperature = dallas_query(&rte_wx_current_dallas_qf);
|
||||
|
||||
// checking if communication was successfull
|
||||
if (temperature != -128.0f) {
|
||||
|
||||
// include current temperature into the average
|
||||
float_average(temperature, &rte_wx_dallas_average);
|
||||
|
||||
// update the current temperature with current average
|
||||
// rte_wx_temperature_average_external_valid = float_get_average(&rte_wx_dallas_average);
|
||||
|
||||
// updating last good measurement time
|
||||
wx_last_good_temperature_time = master_time;
|
||||
|
||||
#if defined(STM32L471xx)
|
||||
rte_wx_temperature_average_dallas = (int16_t)(rte_wx_temperature_average_external_valid * 10.0f);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
// if there were a communication error set the error to unavaliable
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
|
||||
// set the output value
|
||||
output = -1;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int32_t wx_get_temperature_ms5611(float * const temperature) {
|
||||
int32_t return_value = 0;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "main_master_time.h"
|
||||
|
||||
#include "ax25_t.h"
|
||||
#include "cfifo.h"
|
||||
#include "afsk.h"
|
||||
|
||||
|
@ -50,15 +51,15 @@
|
|||
|
||||
struct AX25Msg; // fwd declaration
|
||||
|
||||
/**
|
||||
* Type for AX25 messages callback.
|
||||
*/
|
||||
typedef void (*ax25_callback_t)(struct AX25Msg *ax25_rxed_frame);
|
||||
|
||||
/**
|
||||
* Type for channel free wait timeout callback
|
||||
* Create an AX25Call structure on the fly.
|
||||
* \param str callsign, can be 6 characters or shorter.
|
||||
* \param id ssid associated with the callsign.
|
||||
*/
|
||||
typedef void (*ax25_ch_free_timeout_callback_t)(void);
|
||||
#define AX25_CALL(str, id) {.call = (str), .ssid = (id) }
|
||||
#define AX25_PATH(dst, src, ...) { dst, src, ## __VA_ARGS__ }
|
||||
|
||||
|
||||
typedef struct AX25Ctx
|
||||
{
|
||||
|
@ -81,54 +82,6 @@ typedef struct AX25Ctx
|
|||
|
||||
} AX25Ctx;
|
||||
|
||||
|
||||
/**
|
||||
* AX25 Call sign.
|
||||
*/
|
||||
typedef struct AX25Call
|
||||
{
|
||||
char call[6]; ///< Call string, max 6 character
|
||||
uint8_t ssid; ///< SSID (secondary station ID) for the call
|
||||
} AX25Call;
|
||||
|
||||
|
||||
/**
|
||||
* Create an AX25Call structure on the fly.
|
||||
* \param str callsign, can be 6 characters or shorter.
|
||||
* \param id ssid associated with the callsign.
|
||||
*/
|
||||
#define AX25_CALL(str, id) {.call = (str), .ssid = (id) }
|
||||
#define AX25_PATH(dst, src, ...) { dst, src, ## __VA_ARGS__ }
|
||||
|
||||
|
||||
/**
|
||||
* Maximum number of Repeaters in a AX25 message.
|
||||
*/
|
||||
#define AX25_MAX_RPT 8
|
||||
|
||||
|
||||
/**
|
||||
* AX25 Message.
|
||||
* Used to handle AX25 sent/received messages.
|
||||
*/
|
||||
typedef struct AX25Msg
|
||||
{
|
||||
|
||||
AX25Call src; ///< Source adress
|
||||
AX25Call dst; ///< Destination address
|
||||
AX25Call rpt_lst[AX25_MAX_RPT]; ///< List of repeaters
|
||||
uint8_t rpt_cnt; ///< Number of repeaters in this message
|
||||
uint8_t rpt_flags; ///< Has-been-repeated flags for each repeater (bit-mapped)
|
||||
#define AX25_REPEATED(msg, idx) ((msg)->rpt_flags & BV(idx))
|
||||
uint16_t ctrl; ///< AX25 control field
|
||||
uint8_t pid; ///< AX25 PID field
|
||||
const uint8_t *info; ///< Pointer to the info field (payload) of the message
|
||||
uint16_t len; ///< Payload length
|
||||
uint8_t raw_data[CONFIG_AX25_FRAME_BUF_LEN]; /// Surowa zawarto<74><6F> ramki przekopiowana z Ctx->buff
|
||||
short int raw_msg_len; // wielkosc surowej ramki
|
||||
|
||||
} AX25Msg;
|
||||
|
||||
extern AX25Msg ax25_rxed_frame;
|
||||
extern char ax25_new_msg_rx_flag;
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* ax25_t.h
|
||||
*
|
||||
* Created on: Apr 20, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_APRS_AX25_T_H_
|
||||
#define INCLUDE_APRS_AX25_T_H_
|
||||
|
||||
#include "stdint.h"
|
||||
#include "ax25_config.h"
|
||||
|
||||
/**
|
||||
* Maximum number of Repeaters in a AX25 message.
|
||||
*/
|
||||
#define AX25_MAX_RPT 8
|
||||
|
||||
/**
|
||||
* AX25 Call sign.
|
||||
*/
|
||||
typedef struct AX25Call
|
||||
{
|
||||
char call[6]; ///< Call string, max 6 character
|
||||
uint8_t ssid; ///< SSID (secondary station ID) for the call
|
||||
} AX25Call;
|
||||
|
||||
/**
|
||||
* AX25 Message.
|
||||
* Used to handle AX25 sent/received messages.
|
||||
*/
|
||||
typedef struct AX25Msg
|
||||
{
|
||||
|
||||
AX25Call src; ///< Source adress
|
||||
AX25Call dst; ///< Destination address
|
||||
AX25Call rpt_lst[AX25_MAX_RPT]; ///< List of repeaters
|
||||
uint8_t rpt_cnt; ///< Number of repeaters in this message
|
||||
uint8_t rpt_flags; ///< Has-been-repeated flags for each repeater (bit-mapped)
|
||||
#define AX25_REPEATED(msg, idx) ((msg)->rpt_flags & BV(idx))
|
||||
uint16_t ctrl; ///< AX25 control field
|
||||
uint8_t pid; ///< AX25 PID field
|
||||
const uint8_t *info; ///< Pointer to the info field (payload) of the message
|
||||
uint16_t len; ///< Payload length
|
||||
uint8_t raw_data[CONFIG_AX25_FRAME_BUF_LEN]; /// Surowa zawarto<74><6F> ramki przekopiowana z Ctx->buff
|
||||
short int raw_msg_len; // wielkosc surowej ramki
|
||||
|
||||
} AX25Msg;
|
||||
|
||||
/**
|
||||
* Type for AX25 messages callback.
|
||||
*/
|
||||
typedef void (*ax25_callback_t)(struct AX25Msg *ax25_rxed_frame);
|
||||
|
||||
/**
|
||||
* Type for channel free wait timeout callback
|
||||
*/
|
||||
typedef void (*ax25_ch_free_timeout_callback_t)(void);
|
||||
|
||||
|
||||
#endif /* INCLUDE_APRS_AX25_T_H_ */
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* message.h
|
||||
*
|
||||
* Created on: Apr 20, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_APRS_MESSAGE_H_
|
||||
#define INCLUDE_APRS_MESSAGE_H_
|
||||
|
||||
#include "ax25_t.h"
|
||||
#include "stdint.h"
|
||||
#include "./stored_configuration_nvm/config_data.h"
|
||||
|
||||
#define MESSAGE_MAX_LENGHT 67
|
||||
|
||||
#define MESSAGE_NUMBER_STRING_BUFFER 5 ///!< include room of null terminator
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef enum message_source_t {
|
||||
MESSAGE_SOURCE_UNINITIALIZED = 0x0,
|
||||
MESSAGE_SOURCE_APRSIS = 0x1,
|
||||
MESSAGE_SOURCE_APRSIS_HEXCNTR = 0x2,
|
||||
MESSAGE_SOURCE_RADIO = 0x11,
|
||||
MESSAGE_SOURCE_RADIO_HEXCNTR = 0x12
|
||||
}message_source_t;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef struct message_t {
|
||||
AX25Call from;
|
||||
AX25Call to;
|
||||
uint8_t content[MESSAGE_MAX_LENGHT];
|
||||
uint8_t content_ln;
|
||||
uint8_t number;
|
||||
uint8_t number_str[MESSAGE_NUMBER_STRING_BUFFER]; //!< Message sequence number but stored as string not decoded to integer
|
||||
message_source_t source;
|
||||
}message_t;
|
||||
|
||||
/**
|
||||
* Decode received data to look for an APRS message and put it into a structure
|
||||
* @param message pointer to data received from APRS-IS
|
||||
* @param message_ln lenght of a buffer content
|
||||
* @param content_position optional position of an APRS message content (recipient callsign). if set to zero function will look for it
|
||||
* @param src
|
||||
* @param output parsed APRS message content
|
||||
* @return zero if message has been found and decoded, non zero if parsing failed
|
||||
*/
|
||||
uint8_t message_decode(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param config_data
|
||||
* @param message
|
||||
* @return zero if this is a message to us, non zero otherwise
|
||||
*/
|
||||
uint8_t message_is_for_me(const char * const callsign, const uint8_t ssid, const message_t * const message);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param out_buffer
|
||||
* @param out_buffer_ln
|
||||
* @param message
|
||||
*/
|
||||
int message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message);
|
||||
|
||||
#endif /* INCLUDE_APRS_MESSAGE_H_ */
|
|
@ -21,5 +21,6 @@ void float_average(float in, float_average_t* average);
|
|||
float float_get_average(const float_average_t* average);
|
||||
float float_get_min(const float_average_t* average);
|
||||
float float_get_max(const float_average_t* average);
|
||||
char float_get_nonfull(const float_average_t* average);
|
||||
|
||||
#endif /* INCLUDE_FLOAT_AVERAGE_H_ */
|
||||
|
|
|
@ -25,5 +25,6 @@ int32_t int_get_average(const int_average_t* average);
|
|||
int32_t int_get_min(const int_average_t* average);
|
||||
int32_t int_get_max(const int_average_t* average);
|
||||
int32_t int_get_last(const int_average_t* average);
|
||||
int32_t int_get_nonfull(const int_average_t* average);
|
||||
|
||||
#endif /* INCLUDE_INT_AVERAGE_H_ */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#ifndef VE_DIRECT_PROTOCOL_AVERAGE_STRUCT_H_
|
||||
#define VE_DIRECT_PROTOCOL_AVERAGE_STRUCT_H_
|
||||
|
||||
#define VE_DIRECT_AVERAGE_LEN 24
|
||||
#define VE_DIRECT_AVERAGE_LEN 12
|
||||
|
||||
typedef __attribute__ ((aligned(1))) struct ve_direct_average_struct {
|
||||
|
||||
|
|
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* message.c
|
||||
*
|
||||
* Created on: Apr 20, 2024
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#include "message.h"
|
||||
#include "variant.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#define STATIC
|
||||
#else
|
||||
#define STATIC static
|
||||
#endif
|
||||
|
||||
#define MESSAGE_RECIPIENT_FIELD_SIZE 9
|
||||
|
||||
#define MESSAGE_SSID_CHARS_LN 2
|
||||
|
||||
#define MESSAGE_SENDER_CALL_SSID_MAXLEN 9
|
||||
|
||||
#define MESSAGE_CURRENT_CHAR *(message + content_position + i)
|
||||
|
||||
#define MESSAGE_CURRENT_SENDER_CHAR *(message + i)
|
||||
|
||||
#define MESSAGE_IS_HEX_DIGIT(c) ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
|
||||
|
||||
#define MESSAGE_IS_DIGIT(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
|
||||
|
||||
#define MESSAGE_IS_DIGIT_OR_LETTER(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
||||
|
||||
#define MESSAGE_ACK_REMAINING_BUF (out_buffer_ln - current_pos)
|
||||
|
||||
#define MESSAGE_ACK_CURRENT_POS (char*)(out_buffer + current_pos)
|
||||
|
||||
/**
|
||||
* Lookup table used to string-to-int conversion for HEX strings. Value of 0x30 should be
|
||||
* subtracted from ASCII scancode and this value should be used to intex this table
|
||||
*/
|
||||
static const int8_t message_atoi_lookup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
-1, -1, -1, -1, -1, -1, -1,
|
||||
10, 11, 12, 13, 14, 15,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1,
|
||||
10, 11, 12, 13, 14, 15};
|
||||
|
||||
|
||||
/**
|
||||
* Convert string with message number to integer, with automatic detection of decimal or hex base. It operates
|
||||
* only on positive integers up to 32 bit wide.
|
||||
* @param string
|
||||
* @param string_ln
|
||||
* @param output optional pointer to message structure when output will be also put
|
||||
* @return unsigned integer with decoded number
|
||||
*/
|
||||
STATIC uint32_t message_atoi_message_counter(const uint8_t const * string, uint8_t string_ln, message_t * output) {
|
||||
|
||||
// sum to be returned
|
||||
uint32_t sum = 0u;
|
||||
|
||||
// temporary buffer
|
||||
int8_t conversion_table[6];
|
||||
|
||||
// set to non zero if any digit from A fo F was found in input string
|
||||
int8_t is_hex = 0;
|
||||
|
||||
// checck if input string is located in legit RAM memory
|
||||
if (variant_validate_is_within_ram(string) == 1 && string_ln <= 6) {
|
||||
|
||||
// clear intermediate convertion buffer
|
||||
memset(conversion_table, 0x00, 6);
|
||||
|
||||
// iterator over conversion_table array
|
||||
int8_t conversion_it = string_ln;
|
||||
|
||||
// iterate from the end of a string
|
||||
for (int8_t string_it = string_ln; string_it >= 0; string_it--) {
|
||||
|
||||
// currently processed character
|
||||
const uint8_t current_char = *(string + string_it - 1);
|
||||
|
||||
// check if current character is hex or dec base digit
|
||||
if (MESSAGE_IS_DIGIT(current_char)) {
|
||||
|
||||
// calculate index to lookup table basing on current character
|
||||
const uint8_t index = current_char - 0x30u;
|
||||
|
||||
// check lookup table for converting character with a digit to a number
|
||||
conversion_table[string_ln - conversion_it] = message_atoi_lookup[index];
|
||||
|
||||
// decrement an interator
|
||||
conversion_it--;
|
||||
|
||||
if (MESSAGE_IS_HEX_DIGIT(current_char)) {
|
||||
is_hex = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hex == 1) {
|
||||
sum = (conversion_table[0]);
|
||||
sum += (conversion_table[1] * 0x10);
|
||||
sum += (conversion_table[2] * 0x100);
|
||||
sum += (conversion_table[3] * 0x1000);
|
||||
sum += (conversion_table[4] * 0x10000);
|
||||
sum += (conversion_table[5] * 0x100000);
|
||||
}
|
||||
else {
|
||||
sum = (conversion_table[0]);
|
||||
sum += (conversion_table[1] * 10);
|
||||
sum += (conversion_table[2] * 100);
|
||||
sum += (conversion_table[3] * 1000);
|
||||
sum += (conversion_table[4] * 10000);
|
||||
sum += (conversion_table[5] * 100000);
|
||||
}
|
||||
}
|
||||
|
||||
if (variant_validate_is_within_ram(output) == 1) {
|
||||
output->number = sum & 0xFFu;
|
||||
|
||||
if (is_hex == 1) {
|
||||
if (output->source == MESSAGE_SOURCE_APRSIS) {
|
||||
output->source = MESSAGE_SOURCE_APRSIS_HEXCNTR;
|
||||
}
|
||||
else if (output->source == MESSAGE_SOURCE_RADIO) {
|
||||
output->source = MESSAGE_SOURCE_RADIO_HEXCNTR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode received data to look for an APRS message and put it into a structure
|
||||
* @param message pointer to data received from APRS-IS
|
||||
* @param message_ln lenght of a buffer content
|
||||
* @param content_position optional position of an APRS message content (recipient callsign). if set to zero function will look for it
|
||||
* @param output parsed APRS message content
|
||||
* @return zero if message has been found and decoded, non zero if parsing failed
|
||||
*/
|
||||
uint8_t message_decode(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output) {
|
||||
|
||||
// example message:: SP8EBC>APX216,TCPIP*,qAC,NINTH::SR9WXZ :tedt{0s}\r\n
|
||||
|
||||
// result returned by the function, although shamesly it is also used as local aux variable
|
||||
// in few places of this function :( this is what You sometimes do to save some stack.
|
||||
uint8_t result = 0xFF;
|
||||
|
||||
uint16_t i = 0;
|
||||
|
||||
if (output == 0x00) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (message_ln < (MESSAGE_SENDER_CALL_SSID_MAXLEN + MESSAGE_RECIPIENT_FIELD_SIZE)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
memset(output->number_str, 0x00, MESSAGE_NUMBER_STRING_BUFFER);
|
||||
|
||||
// if start position of APRS message (position of recipient callsign) has not been provided
|
||||
if ((src == MESSAGE_SOURCE_APRSIS) && (content_position == 0)) {
|
||||
|
||||
// look for it
|
||||
for (i = 0; i < message_ln; i++) {
|
||||
const uint8_t * this_character = message + i;
|
||||
|
||||
const uint8_t * next_character = message + i + 1;
|
||||
|
||||
// break on an end of input string
|
||||
if (*this_character == 0x00) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check if double semicolon has been found
|
||||
if ((*this_character == ':') && (*next_character == ':')) {
|
||||
// APRS message starts after second semicolong
|
||||
content_position = i + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear the iterator, it will be used across this function
|
||||
i = 0;
|
||||
|
||||
// check content position one more time to verify
|
||||
// if input data contains APRS message at all
|
||||
if (
|
||||
((src == MESSAGE_SOURCE_APRSIS) && (content_position != 0)) ||
|
||||
(src == MESSAGE_SOURCE_RADIO)
|
||||
) {
|
||||
|
||||
// set this variable to zero as now it will be used as a local
|
||||
result = 0;
|
||||
|
||||
// clear output structure to make room for new data
|
||||
memset(output, 0x00, sizeof(message_t));
|
||||
|
||||
//extract sender call and SSID only if this message has been received from APRS-IS in pure text form
|
||||
if (src == MESSAGE_SOURCE_APRSIS) {
|
||||
// fast forward any potential whitespace at the begining
|
||||
while (MESSAGE_CURRENT_SENDER_CHAR == ' ') {
|
||||
i++;
|
||||
|
||||
if (i >= message_ln) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// extract sender callsign
|
||||
for (; i < MESSAGE_SENDER_CALL_SSID_MAXLEN; i++) {
|
||||
|
||||
// if SSID separator or sender end character ('>') has been reached
|
||||
if (MESSAGE_CURRENT_SENDER_CHAR == '-' || MESSAGE_CURRENT_SENDER_CHAR == '>') {
|
||||
break;
|
||||
}
|
||||
|
||||
output->from.call[result++] = MESSAGE_CURRENT_SENDER_CHAR;
|
||||
}
|
||||
|
||||
// check if sender has SSID
|
||||
if (MESSAGE_CURRENT_SENDER_CHAR == '-') {
|
||||
// jumps to next character. otherwise separating '-'
|
||||
// will be interpreted as a minus/negitive sign
|
||||
i++;
|
||||
|
||||
result = 0; // here used as a local iterator
|
||||
|
||||
// extract SSID
|
||||
for (; i < MESSAGE_RECIPIENT_FIELD_SIZE; i++) {
|
||||
// copy characters to aux buffer
|
||||
output->number_str[result++] = MESSAGE_CURRENT_SENDER_CHAR;
|
||||
|
||||
// check if there isn't enough characters
|
||||
if (result == MESSAGE_NUMBER_STRING_BUFFER) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert SSID to int
|
||||
output->from.ssid = atoi(output->number_str);
|
||||
}
|
||||
|
||||
// clear the iterator, it will be used across this function
|
||||
i = 0;
|
||||
}
|
||||
else {
|
||||
// clear content_position iterator
|
||||
content_position = 0;
|
||||
|
||||
// find a begining of the message in data from radio channel
|
||||
while (MESSAGE_CURRENT_CHAR != ':') {
|
||||
content_position++;
|
||||
|
||||
if (content_position >= message_ln) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// jump over ':'
|
||||
content_position++;
|
||||
}
|
||||
|
||||
// extract recipient
|
||||
for (; i < MESSAGE_RECIPIENT_FIELD_SIZE; i++) {
|
||||
|
||||
// look if end of callsign or separating '-' has been found
|
||||
if (MESSAGE_CURRENT_CHAR == ' ' || MESSAGE_CURRENT_CHAR == '-') {
|
||||
break; // and go for SSID reading
|
||||
}
|
||||
|
||||
// copy recipient callsign character per character
|
||||
output->to.call[i] = MESSAGE_CURRENT_CHAR;
|
||||
}
|
||||
|
||||
// check if callsign has SSID set
|
||||
if (MESSAGE_CURRENT_CHAR == '-') {
|
||||
// jumps to next character. otherwise separating '-'
|
||||
// will be interpreted as a minus/negitive sign
|
||||
i++;
|
||||
|
||||
result = 0; // here used as a local iterator
|
||||
|
||||
// extract SSID
|
||||
for (; i < MESSAGE_RECIPIENT_FIELD_SIZE; i++) {
|
||||
// copy characters to aux buffer
|
||||
output->number_str[result++] = MESSAGE_CURRENT_CHAR;
|
||||
|
||||
// check if there isn't enough characters
|
||||
if (result == MESSAGE_NUMBER_STRING_BUFFER) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert SSID to int
|
||||
output->to.ssid = atoi(output->number_str);
|
||||
}
|
||||
|
||||
if (result != MESSAGE_NUMBER_STRING_BUFFER && /* if SSID extraction was OK and end of a buffer hasn't been reached */
|
||||
(
|
||||
(i < MESSAGE_RECIPIENT_FIELD_SIZE) || /* if recipient and callsign has been read before ':' separating from message content */
|
||||
((i == MESSAGE_RECIPIENT_FIELD_SIZE) && (MESSAGE_CURRENT_CHAR == ':')) /* if a position of separating ':' was reached and ':' is there */
|
||||
)
|
||||
) {
|
||||
|
||||
// reinitialize buffer before next usage
|
||||
memset(output->number_str, 0x00, MESSAGE_NUMBER_STRING_BUFFER);
|
||||
|
||||
// check if the iterator is set now to position of ':' separating
|
||||
// recipient an the message itself
|
||||
while(MESSAGE_CURRENT_CHAR != ':' && i <= MESSAGE_RECIPIENT_FIELD_SIZE) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// one more incrementation to jump over ':' and land on the first character of the message
|
||||
i++;
|
||||
|
||||
result = 0;
|
||||
|
||||
output->content_ln = 0;
|
||||
|
||||
// then copy message, which ends on a counter, something like '{1'
|
||||
while(MESSAGE_CURRENT_CHAR != ':' && i + content_position < message_ln) {
|
||||
output->content[result++] = MESSAGE_CURRENT_CHAR;
|
||||
output->content_ln++;
|
||||
i++;
|
||||
|
||||
// break on message counter separator
|
||||
if (MESSAGE_CURRENT_CHAR == '{') {
|
||||
i++; // move to first digit of a counter
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check which condition has ended previous 'while' loop and if an end of the buffer has been reached
|
||||
if (i + content_position < message_ln) {
|
||||
result = 0;
|
||||
|
||||
// now iterator is set (should be set) on a first digit of message counter
|
||||
// copy everything until first non digit character is found
|
||||
while (MESSAGE_IS_DIGIT_OR_LETTER(MESSAGE_CURRENT_CHAR)) {
|
||||
output->number_str[result++] = MESSAGE_CURRENT_CHAR;
|
||||
|
||||
i++;
|
||||
|
||||
// check if there isn't enough characters
|
||||
if (result == MESSAGE_NUMBER_STRING_BUFFER) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output->source = src;
|
||||
|
||||
// convert message counter from string to int
|
||||
message_atoi_message_counter(output->number_str, result, output);
|
||||
|
||||
if (result < MESSAGE_NUMBER_STRING_BUFFER) {
|
||||
// new we are done (??)
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = 0xFF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param config_data
|
||||
* @param message
|
||||
* @return zero if this is a message to us, non zero otherwise
|
||||
*/
|
||||
uint8_t message_is_for_me(const char * const callsign, const uint8_t ssid, const message_t * const message)
|
||||
{
|
||||
const int _callsign = strncmp(callsign, message->to.call, 6);
|
||||
|
||||
if (_callsign == 0 && (ssid == message->to.ssid)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param out_buffer
|
||||
* @param out_buffer_ln
|
||||
* @param message
|
||||
* @param src how this message has been received
|
||||
*/
|
||||
int message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message)
|
||||
{
|
||||
int current_pos = 0;
|
||||
|
||||
uint8_t call_position = 0;
|
||||
|
||||
const message_source_t src = message->source;
|
||||
|
||||
// clear output buffer
|
||||
memset(out_buffer, 0x00, out_buffer_ln);
|
||||
|
||||
if (src == MESSAGE_SOURCE_APRSIS || src == MESSAGE_SOURCE_APRSIS_HEXCNTR) {
|
||||
|
||||
// put my callsign
|
||||
for (; call_position < 6; call_position++) {
|
||||
// break on null character
|
||||
if (message->to.call[call_position] == 0x00) {
|
||||
break;
|
||||
}
|
||||
|
||||
// copy callsign data
|
||||
out_buffer[current_pos + call_position] = message->to.call[call_position];
|
||||
}
|
||||
|
||||
current_pos += call_position;
|
||||
|
||||
call_position = 0;
|
||||
|
||||
// check if I have a SSID
|
||||
if (message->to.ssid != 0) {
|
||||
current_pos += snprintf(MESSAGE_ACK_CURRENT_POS, MESSAGE_ACK_REMAINING_BUF, "-%d", message->to.ssid);
|
||||
}
|
||||
|
||||
// constant part
|
||||
current_pos += snprintf(MESSAGE_ACK_CURRENT_POS, MESSAGE_ACK_REMAINING_BUF, ">AKLPRZ::");
|
||||
|
||||
// put sender callsign, station I received this message from
|
||||
for (; call_position < 6; call_position++) {
|
||||
// break on null character
|
||||
if (message->from.call[call_position] == 0x00) {
|
||||
break;
|
||||
}
|
||||
|
||||
// copy callsign data
|
||||
out_buffer[current_pos + call_position] = message->from.call[call_position];
|
||||
}
|
||||
|
||||
// put sender SSID, station I received this message from
|
||||
if (message->from.ssid != 0) {
|
||||
call_position += snprintf(MESSAGE_ACK_CURRENT_POS + call_position, MESSAGE_ACK_REMAINING_BUF, "-%d", message->from.ssid);
|
||||
}
|
||||
|
||||
// check if callsign was shorter than 6 characters
|
||||
while (call_position < 9) {
|
||||
// copy callsign data
|
||||
out_buffer[current_pos + call_position] = ' ';
|
||||
|
||||
call_position++;
|
||||
}
|
||||
|
||||
// callsign + ssid + padding must be exactly 9 characters long
|
||||
current_pos += 9;
|
||||
|
||||
// then put 'ackXX' where X is message number
|
||||
current_pos += snprintf(MESSAGE_ACK_CURRENT_POS, MESSAGE_ACK_REMAINING_BUF, ":ack%s\r\n", message->number_str);
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
return current_pos;
|
||||
}
|
|
@ -326,11 +326,13 @@ void telemetry_send_chns_description(const config_data_basic_t * const config_ba
|
|||
|
||||
uint8_t is_viscous = 1;
|
||||
|
||||
if (variant_validate_is_within_ram(config_basic) == 0) {
|
||||
if (variant_validate_is_within_ram(config_basic) == 0 &&
|
||||
variant_validate_is_within_flash(config_basic) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (variant_validate_is_within_ram(config_mode) == 0) {
|
||||
if (variant_validate_is_within_ram(config_basic) == 0 &&
|
||||
variant_validate_is_within_flash(config_basic) == 0) {
|
||||
is_viscous = 0;
|
||||
}
|
||||
else if (config_mode->digi_viscous == 0) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#endif
|
||||
|
||||
#include "drivers/dallas.h"
|
||||
#include "etc/dallas_temperature_limits.h"
|
||||
#include <string.h>
|
||||
|
||||
volatile int delay_5us = 0;
|
||||
|
@ -241,9 +242,7 @@ float __attribute__((optimize("O0"))) dallas_query(dallas_qf_t *qf) {
|
|||
return -128.0f;
|
||||
}
|
||||
|
||||
if (temperature < -50.0f || temperature > 120.0f)
|
||||
*qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
else if (temperature < -25.0f || temperature > 38.75f)
|
||||
if (temperature < DALLAS_TEMPERATURE_LIMITS_LOW || temperature > DALLAS_TEMPERATURE_LIMITS_HI)
|
||||
*qf = DALLAS_QF_DEGRADATED;
|
||||
else
|
||||
*qf = DALLAS_QF_FULL;
|
||||
|
|
|
@ -71,3 +71,13 @@ float dallas_get_max(const float_average_t* average) {
|
|||
return out;
|
||||
}
|
||||
|
||||
char float_get_nonfull(const float_average_t* average) {
|
||||
for (int i = 0; i < FLOAT_AVERAGE_LN; i++) {
|
||||
if (average->values[i] == FLOAT_INIT_VALUE) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,3 +97,13 @@ int32_t int_get_last(const int_average_t* average) {
|
|||
|
||||
return out;
|
||||
}
|
||||
|
||||
int32_t int_get_nonfull(const int_average_t* average) {
|
||||
for (int i = 0; i < INT_AVERAGE_LN; i++) {
|
||||
if (average->values[i] == INT_INIT_VALUE) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -72,13 +72,6 @@ uint8_t rtu_blocking_io = 0;
|
|||
*/
|
||||
uint32_t rtu_time_of_last_successfull_comm = 0;
|
||||
|
||||
/**
|
||||
* This variable latches the value of 'rtu_time_of_last_successfull_comm' across
|
||||
* consecutive messages with an error status. If the value is the same as during
|
||||
* previous transmission the controller is restarted
|
||||
*/
|
||||
uint32_t rtu_time_of_last_succ_comm_at_previous_error_status = 0;
|
||||
|
||||
/**
|
||||
* CRC value after the last call to rtu_serial_callback
|
||||
*/
|
||||
|
@ -217,8 +210,6 @@ int32_t rtu_serial_pool(void) {
|
|||
|
||||
// check how many serial I/O erros have been detected so far
|
||||
if ((rte_rtu_number_of_serial_io_errors % RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS) == 0) {
|
||||
// set the status trigger
|
||||
rte_main_trigger_modbus_status = 1;
|
||||
|
||||
// increment the error counter artificially to protect sending status in the loop
|
||||
rte_rtu_number_of_serial_io_errors++;
|
||||
|
@ -230,8 +221,6 @@ int32_t rtu_serial_pool(void) {
|
|||
// rte_main_reboot_req = 1;
|
||||
// }
|
||||
|
||||
// latch the current value of last successfull communication
|
||||
rtu_time_of_last_succ_comm_at_previous_error_status = rtu_time_of_last_successfull_comm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,26 +530,3 @@ int32_t rtu_serial_start(void) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
int32_t rtu_serial_get_status_string(rtu_pool_queue_t* queue, srl_context_t* srl_ctx, char* out, uint16_t out_buffer_ln, uint8_t* generated_string_ln) {
|
||||
|
||||
int32_t retval = MODBUS_RET_UNINITIALIZED;
|
||||
int string_ln = 0;
|
||||
|
||||
memset(out, 0x00, out_buffer_ln);
|
||||
//#ifdef _MODBUS_RTU
|
||||
|
||||
string_ln = snprintf(out, out_buffer_ln, ">[MT: %lX][LRET: %lX][LSCT: %lX][NSSC: %X][NSE: %X][RXB: %lX][RXI %X][TXB %lX]",
|
||||
main_get_master_time(),
|
||||
rte_rtu_last_modbus_rx_error_timestamp,
|
||||
rtu_time_of_last_successfull_comm,
|
||||
(int)rte_rtu_number_of_successfull_serial_comm,
|
||||
(int)rte_rtu_number_of_serial_io_errors,
|
||||
srl_ctx->total_rx_bytes,
|
||||
srl_ctx->total_idle_counter,
|
||||
srl_ctx->total_tx_bytes);
|
||||
|
||||
*generated_string_ln = (uint8_t) string_ln;
|
||||
//#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue