Skip to content

Commit

Permalink
Added template signals to YAMCAN
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshLafleur committed Jan 25, 2025
1 parent 566c8da commit a11a68e
Show file tree
Hide file tree
Showing 21 changed files with 105 additions and 104 deletions.
5 changes: 5 additions & 0 deletions components/bms_boss/include/CANIO_componentSpecific.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Sys.h"
#include "IMD.h"
#include "ENV.h"
#include "Module.h"

/******************************************************************************
* P R I V A T E F U N C T I O N P R O T O T Y P E S
Expand All @@ -48,5 +49,9 @@ CAN_prechargeContactorState_E CANIO_tx_getContactorState(void);
#define set_nlg513MaxChargeVoltage(m,b,n,s) set(m,b,n,s, BMS_CONFIGURED_PACK_MAX_VOLTAGE)
#define set_nlg513MaxChargeCurrent(m,b,n,s) set(m,b,n,s, BMS.pack_charge_limit)
#define transmit_BMSB_brusaChargeCommand (SYS_SFT_checkChargerTimeout() == false)
#define set_taskUsage1kHz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1kHz_TASK));
#define set_taskUsage100Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_100Hz_TASK));
#define set_taskUsage10Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_10Hz_TASK));
#define set_taskUsage1Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1Hz_TASK));

#include "TemporaryStubbing.h"
4 changes: 3 additions & 1 deletion components/bms_boss/include/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
******************************************************************************/

// System Includes
#include "FloatTypes.h"
#include "stdint.h"

// Other Includes
Expand Down Expand Up @@ -60,7 +61,8 @@ typedef struct
} Module_taskStats_S;

/******************************************************************************
* P R I V A T E F U N C T I O N P R O T O T Y P E S
* P U B L I C F U N C T I O N P R O T O T Y P E S
******************************************************************************/

float32_t Module_getTotalRuntimePercentage(Module_taskSpeeds_E task);
void Module_ApplicationIdleHook(void);
10 changes: 10 additions & 0 deletions components/bms_boss/src/Module.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,13 @@ void Module_1Hz_TSK(void)
void Module_ApplicationIdleHook()
{
}

/**
* @brief Returns the total cpu usage of a task in percentage
* @param task Task to get the total runtime percentage of
* @returns The total runtime percentage of the task
*/
float32_t Module_getTotalRuntimePercentage(Module_taskSpeeds_E task)
{
return stats[task].total_percentage;
}
18 changes: 18 additions & 0 deletions network/NetworkGen/NetworkGen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Dict, Iterator, Tuple
import pickle

from mako import template
from mako.lookup import TemplateLookup
from oyaml import safe_load

Expand All @@ -25,6 +26,7 @@
can_bus_defs = {}
can_nodes = {}
discrete_values = {}
templates = {}

# if this gets set during the build, we will fail at the end
ERROR = False
Expand All @@ -47,6 +49,13 @@ def generate_discrete_values(data_dir: Path) -> None:
print(e)
ERROR = True

def generate_templates(data_dir: Path) -> None:
"""Load discrete values from signals.yaml"""
global ERROR
global templates

with open(data_dir.joinpath("signals.yaml"), "r") as fd:
templates["signals"] = safe_load(fd)["signals"]

def generate_can_buses(data_dir: Path) -> None:
"""Generate CAN buses based on yaml files"""
Expand Down Expand Up @@ -132,6 +141,7 @@ def generate_can_nodes(data_dir: Path) -> None:
def process_node(node: CanNode):
"""Process the signals and messages associated with a given CAN node"""
global ERROR
global templates

sig_file = SIG_FILE.format(name=node.name)
msg_file = MESSAGE_FILE.format(name=node.name)
Expand Down Expand Up @@ -192,6 +202,10 @@ def process_node(node: CanNode):

msg_obj.node_ref = node
for msg_signal in msg_obj.signals:
sig = msg_signal.split('_')[1]
if definition['signals'][sig] is not None and "template" in definition["signals"][sig]:
sig_obj = CanSignal(msg_signal, templates["signals"][definition['signals'][sig]['template']])
signals[msg_signal] = sig_obj
if msg_signal in signals:
if not signals[msg_signal].is_valid:
print(
Expand Down Expand Up @@ -414,6 +428,7 @@ def parse_args() -> Namespace:

def parseNetwork(args, lookup):
generate_discrete_values(args.data_dir)
generate_templates(args.data_dir.joinpath("data/templates"))
generate_can_buses(args.data_dir)
generate_can_nodes(args.data_dir)

Expand All @@ -434,6 +449,7 @@ def main():
global can_nodes
global can_bus_defs
global discrete_values
global templates

# parse arguments
args = parse_args()
Expand All @@ -449,11 +465,13 @@ def main():
pickle.dump(can_nodes, open(args.cache_dir.joinpath("CachedNodes.pickle"), "wb"))
pickle.dump(can_bus_defs, open(args.cache_dir.joinpath("CachedBusDefs.pickle"), "wb"))
pickle.dump(discrete_values, open(args.cache_dir.joinpath("CachedDiscreteValues.pickle"), "wb"))
pickle.dump(templates, open(args.cache_dir.joinpath("CachedTemplates.pickle"), "wb"))
elif args.cache_dir:
try:
can_nodes = pickle.load(open(args.cache_dir.joinpath("CachedNodes.pickle"), "rb"))
can_bus_defs = pickle.load(open(args.cache_dir.joinpath("CachedBusDefs.pickle"), "rb"))
discrete_values = pickle.load(open(args.cache_dir.joinpath("CachedDiscreteValues.pickle"), "rb"))
templates = pickle.load(open(args.cache_dir.joinpath("CachedTemplates.pickle"), "rb"))
except Exception as e:
print(f"Could not retreive cache files. Try building the network again...")
ERROR = True
Expand Down
20 changes: 11 additions & 9 deletions network/NetworkGen/classes/Can.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ def __init__(
self.continuous = Continuous(
get_if_exists(signal_def, "continuous", bool, Continuous.discrete)
)
self.cycle_time_ms = get_if_exists(signal_def, "cycleTimeMs", int, None)
self.description = get_if_exists(signal_def, "description", str, None)
self.discrete_values = getattr(
self.DISC, get_if_exists(signal_def, "discreteValues", str, ""), None
Expand Down Expand Up @@ -163,7 +162,6 @@ def __repr__(self):
return (
f"\nCAN Signal: {self.name}, "
f"Description: {self.description}, "
f"cycleTimeMs: {self.cycle_time_ms}, "
f"bitWidth: {self.native_representation.bit_width or 'TBD'}, "
f"offset: {self.offset}, "
f"scale: {self.scale}, "
Expand Down Expand Up @@ -322,7 +320,7 @@ class CanMessage(CanObject):

def __init__(self, node: "CanNode", name: str, msg_def: dict):
self.name = name
self.cycle_time_ms = 0
self.cycle_time_ms = get_if_exists(msg_def, "cycleTimeMs", int, None)
self.description = get_if_exists(msg_def, "description", str, "")
self.node_name = self.name.split("_")[0]
self.id = get_if_exists(msg_def, "id", int, None)
Expand All @@ -349,6 +347,10 @@ def __init__(self, node: "CanNode", name: str, msg_def: dict):
else:
self.source_buses = node.on_buses

if self.cycle_time_ms is None and not self.unscheduled:
raise Exception(
f"Message '{self.name}' has no specified cycle time"
)
# Assigned later
self.node_ref = None
self.is_valid = False
Expand All @@ -358,7 +360,10 @@ def __repr__(self):

def add_signal(self, msg_signal: dict, signal_obj: CanSignal):
"""Add the given signal to this message"""
signal_obj.start_bit = msg_signal["startBit"] if msg_signal else 0
try:
signal_obj.start_bit = msg_signal["startBit"]
except Exception:
signal_obj.start_bit = 0
if signal_obj.validation_role == ValidationRole.checksum:
self.checksum_sig = signal_obj
if signal_obj.validation_role == ValidationRole.counter:
Expand All @@ -376,12 +381,10 @@ def validate_msg(self):
# this works because dictionaries are ordered now
first_signal_loc = list(self.signal_objs.values())[0].start_bit
bit_count = first_signal_loc
self.cycle_time_ms = list(self.signal_objs.values())[0].cycle_time_ms

sig_objs = self.signal_objs.values()
first = True
for signal in sig_objs:
self.cycle_time_ms = min(self.cycle_time_ms, signal.cycle_time_ms)
if first:
signal.start_bit = bit_count
bit_count += signal.native_representation.bit_width
Expand Down Expand Up @@ -420,12 +423,11 @@ def validate_msg(self):
return

if self.length_bytes is None:
print(f"Message {self.name} is missing a lengthBytes")
valid = False
self.length_bytes = ceil(bit_count / 8)
else:
if ceil(bit_count / 8) > self.length_bytes:
print(
f"Message {self.name} has lengthBytes greater than the sum "
f"Message {self.name} has lengthBytes less than the sum "
"of the bitWidths of each of its signals"
)
valid = False
Expand Down
18 changes: 18 additions & 0 deletions network/definition/data/components/bmsb/bmsb-message.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
messages:
criticalData:
description: BMS Boss Critical Data
cycleTimeMs: 10
id: 0x99
lengthBytes: 8
sourceBuses: veh
Expand All @@ -12,6 +13,7 @@ messages:

information:
description: BMS Boss Information
cycleTimeMs: 100
id: 0x98
lengthBytes: 3
sourceBuses: veh
Expand All @@ -21,6 +23,7 @@ messages:

brusaChargeCommand:
description: Brusa Charge Command
cycleTimeMs: 100
id: 0x618
lengthBytes: 7
sourceBuses: veh
Expand All @@ -38,3 +41,18 @@ messages:
sourceBuses: veh
signals:
udsPayload:

rtosTaskInfo:
description: BMSB rtos task information
cycleTimeMs: 1000
id: 0x550
sourceBuses: veh
signals:
taskUsage1kHz:
template: percentage
taskUsage100Hz:
template: percentage
taskUsage10Hz:
template: percentage
taskUsage1Hz:
template: percentage
11 changes: 0 additions & 11 deletions network/definition/data/components/bmsb/bmsb-signals.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
signals:
nlg513ControlByte:
cycleTimeMs: 10
description: Brusa NLG513 Control Byte
nativeRepresentation:
bitWidth: 8

nlg513MaxMainsCurrent:
cycleTimeMs: 10
unit: 'A'
description: Brusa NLG513 Max Mains Current During Charging
nativeRepresentation:
Expand All @@ -19,7 +17,6 @@ signals:
continuous: true

nlg513MaxChargeVoltage:
cycleTimeMs: 10
unit: 'V'
description: Brusa NLG513 Max Battery Voltage During Charging
nativeRepresentation:
Expand All @@ -32,7 +29,6 @@ signals:
continuous: true

nlg513MaxChargeCurrent:
cycleTimeMs: 10
unit: 'A'
description: Brusa NLG513 Max Battery Voltage During Charging
nativeRepresentation:
Expand All @@ -45,14 +41,12 @@ signals:
continuous: true

criticalDataCounter:
cycleTimeMs: 10
description: BMS Boss Critical Message Counter
nativeRepresentation:
bitWidth: 8
validationRole: counter

packChargeLimit:
cycleTimeMs: 10
unit: 'A'
description: BMS Boss Pack Charge Limit
nativeRepresentation:
Expand All @@ -64,7 +58,6 @@ signals:
continuous: true

packDischargeLimit:
cycleTimeMs: 10
unit: 'A'
description: BMS Boss Pack Disharge Limit
nativeRepresentation:
Expand All @@ -76,7 +69,6 @@ signals:
continuous: true

packVoltage:
cycleTimeMs: 10
unit: 'V'
description: BMS Boss Pack Voltage
nativeRepresentation:
Expand All @@ -88,7 +80,6 @@ signals:
continuous: true

packCurrent:
cycleTimeMs: 100
unit: 'A'
description: BMS Boss Pack Current
nativeRepresentation:
Expand All @@ -99,12 +90,10 @@ signals:
continuous: true

packContactorState:
cycleTimeMs: 100
description: Pack Contactor Status
discreteValues: prechargeContactorState

udsPayload:
cycleTimeMs: 10
unit: ''
description: UDS payload data
nativeRepresentation:
Expand Down
Loading

0 comments on commit a11a68e

Please sign in to comment.