Hello,
I'm trying to develop a LIN Master that is implemented using the PLinApi with Python 3. I want the Master to
run a schedule table on the hardware (this part is working fine) and read the BUS from the same hardware.
What I see is as soon as I read from a parallel thread the timings from the schedule table will not process proper.
- So, is it possible using the API to run an schedule table and do reads (logging of the bus) on the same hardware?
- How can this be realized? I tried multible threads.
Thanks,
Volker Schilling
LIN Master - Schedule Table Processing and Read
-
- Posts: 2
- Joined: Tue 17. Mar 2020, 06:50
-
- Sales & Support
- Posts: 425
- Joined: Fri 20. Sep 2019, 13:31
Re: LIN Master - Schedule Table Processing and Read
Hello,
Can you please send us the necessary code (your sheduler implementation) , so we can assess the issue further?
Best Regards
Marvin
Can you please send us the necessary code (your sheduler implementation) , so we can assess the issue further?
Best Regards
Marvin
-
- Posts: 2
- Joined: Tue 17. Mar 2020, 06:50
Re: LIN Master - Schedule Table Processing and Read
Hello Marvin,
this is the code:
If I add the readThread part, then the timings (Interval ov the Frames) are not correct.
Whats wrong with this approach?
Thanks,
Volker
this is the code:
Code: Select all
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
from ctypes import *
import PLinApi
class LinFuzzer(object):
"""
"""
FRAME_FILTER_MASK = c_uint64(0xFFFFFFFFFFFFFFFF)
GLOBAL_FRAME_TABLE = {
0x00: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x01: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x02: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x03: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x04: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x05: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x06: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x07: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x08: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x09: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0A: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0B: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0C: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0D: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0E: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x0F: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x10: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x11: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x12: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x13: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x14: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x15: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x16: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x17: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x18: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x19: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1A: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1B: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1C: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1D: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1E: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x1F: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
# 0x20: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x20: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 2},
0x21: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x22: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x23: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x24: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x25: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x26: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x27: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x28: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x29: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
# 0x2A: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x2A: {"dir": PLinApi.TLIN_DIRECTION_SUBSCRIBER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
# 0x2B: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x2B: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x2C: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x2D: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x2E: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
0x2F: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
# 0x30: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x30: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
# 0x31: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x31: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 4},
# 0x32: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x32: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 1},
# 0x33: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x33: {"dir": PLinApi.TLIN_DIRECTION_SUBSCRIBER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 1},
0x34: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x35: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x36: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
# 0x37: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x37: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x38: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x39: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3A: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3B: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
# 0x3C: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3C: {"dir": PLinApi.TLIN_DIRECTION_PUBLISHER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
# 0x3D: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3D: {"dir": PLinApi.TLIN_DIRECTION_SUBSCRIBER, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3E: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
0x3F: {"dir": PLinApi.TLIN_DIRECTION_DISABLED, "cst": PLinApi.TLIN_CHECKSUMTYPE_CLASSIC, "len": 8},
}
SCHEDULE_TABLE = [
{"id": [0x37], "delay": 20, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x33], "delay": 10, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x32], "delay": 10, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x2A], "delay": 20, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x2B], "delay": 20, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x30], "delay": 15, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x31], "delay": 15, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x20], "delay": 10, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x2A], "delay": 20, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
{"id": [0x2B], "delay": 20, "type": PLinApi.TLIN_SLOTTYPE_UNCONDITIONAL},
]
def __init__(self):
"""
"""
self.m_objPLinApi = PLinApi.PLinApi()
self.m_hClient = PLinApi.HLINCLIENT(0)
self.m_hHw = PLinApi.HLINHW(0)
self.m_HwMode = PLinApi.TLIN_HARDWAREMODE_MASTER
self.m_HwBaudrate = c_ushort(9600)
self.m_lMask = self.FRAME_FILTER_MASK
if not self.m_objPLinApi.isLoaded():
raise Exception("PLin-API could not be loaded ! Exiting...")
def connect(self, name, device_number, channel_number):
"""
:param name:
:param device_number:
:param channel_number:
:return:
"""
if self.m_objPLinApi.RegisterClient(name, None, self.m_hClient) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
self.m_objPLinApi.ResetClient(self.m_hClient)
self.m_hHw = PLinApi.HLINHW(device_number)
if self.m_objPLinApi.ConnectClient(self.m_hClient, self.m_hHw) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
mode = c_int(0)
baudrate = c_int(0)
if self.m_objPLinApi.GetHardwareParam(
self.m_hHw, PLinApi.TLIN_HARDWAREPARAM_MODE, mode, 0) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
if self.m_objPLinApi.GetHardwareParam(
self.m_hHw, PLinApi.TLIN_HARDWAREPARAM_BAUDRATE, baudrate, 0) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
self.m_objPLinApi.ResetHardware(self.m_hClient, self.m_hHw)
if mode.value == PLinApi.TLIN_HARDWAREMODE_NONE.value or baudrate.value != self.m_HwBaudrate.value:
if self.m_objPLinApi.InitializeHardware(
self.m_hClient, self.m_hHw, self.m_HwMode, self.m_HwBaudrate) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
if self.m_objPLinApi.SetClientFilter(
self.m_hClient, self.m_hHw, self.m_lMask) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
def disconnect(self):
"""
:return:
"""
if self.m_objPLinApi.DisconnectClient(self.m_hClient, self.m_hHw) == PLinApi.TLIN_ERROR_OK:
self.m_hHw = PLinApi.HLINHW(0)
self.m_objPLinApi.RemoveClient(self.m_hClient)
def set_frame_entry(self, frameId, direction, cst, length):
"""
:param frameId:
:param direction:
:param cst:
:param length:
:return:
"""
frame_entry = PLinApi.TLINFrameEntry()
frame_entry.FrameId = c_ubyte(frameId)
frame_entry.ChecksumType = cst
frame_entry.Direction = direction
frame_entry.Length = c_ubyte(length)
frame_entry.Flags = PLinApi.FRAME_FLAG_RESPONSE_ENABLE
if self.m_objPLinApi.SetFrameEntry(self.m_hClient, self.m_hHw, frame_entry) == PLinApi.TLIN_ERROR_OK:
mask = c_uint64(1 << frameId)
self.m_lMask = c_uint64(self.m_lMask.value | mask.value)
if self.m_objPLinApi.SetClientFilter(self.m_hClient, self.m_hHw, self.m_lMask) != PLinApi.TLIN_ERROR_OK:
raise Exception("Connect Failed")
def set_global_frame_table(self):
"""
:return:
"""
for frame_id in self.GLOBAL_FRAME_TABLE:
entry = self.GLOBAL_FRAME_TABLE[frame_id]
self.set_frame_entry(
frameId=frame_id, direction=entry['dir'], cst=entry['cst'], length=entry['len'])
def get_global_frame_table(self):
"""
:return:
"""
table = {}
self.m_lMask = c_uint64(0x0)
mask = c_uint64(0x0)
for index in range(64):
frame_entry = PLinApi.TLINFrameEntry()
frame_entry.FrameId = c_ubyte(index)
frame_entry.ChecksumType = PLinApi.TLIN_CHECKSUMTYPE_AUTO
frame_entry.Direction = PLinApi.TLIN_DIRECTION_SUBSCRIBER_AUTOLENGTH
if (index >= 0x00) and (index <= 0x1F):
frame_entry.Length = c_ubyte(2)
elif (index >= 0x20) and (index <= 0x2F):
frame_entry.Length = c_ubyte(4)
elif (index >= 0x30) and (index <= 0x3F):
frame_entry.Length = c_ubyte(8)
if self.m_objPLinApi.GetFrameEntry(self.m_hHw, frame_entry) == PLinApi.TLIN_ERROR_OK:
table[frame_entry.FrameId] = {
"dir": frame_entry.Direction,
"cst": frame_entry.ChecksumType,
"len": frame_entry.Length
}
if frame_entry.Direction != PLinApi.TLIN_DIRECTION_DISABLED.value:
mask = c_uint64((1 << index) & self.FRAME_FILTER_MASK.value)
self.m_lMask = c_uint64(self.m_lMask.value | mask.value)
if (self.m_hClient.value != 0) and (self.m_hHw.value != 0):
self.m_objPLinApi.SetClientFilter(self.m_hClient, self.m_hHw, self.m_lMask)
return table
def set_schedule_table(self, tyble_id):
"""
:param tyble_id:
:return:
"""
schedule_slot_array = (PLinApi.TLINScheduleSlot * len(self.SCHEDULE_TABLE))
schedule_table = schedule_slot_array()
for index, entry in enumerate(self.SCHEDULE_TABLE):
schedule_entry = PLinApi.TLINScheduleSlot()
for pos, frameId in enumerate(entry["id"]):
schedule_entry.FrameId[pos] = c_ubyte(frameId)
schedule_entry.Type = entry["type"]
schedule_entry.Delay = c_ushort(entry["delay"])
schedule_entry.CountResolve = c_ubyte(0)
schedule_table[index] = schedule_entry
self.m_objPLinApi.SetSchedule(self.m_hClient, self.m_hHw, tyble_id, schedule_table, len(self.SCHEDULE_TABLE))
def get_schedule_table(self, tyble_id):
"""
:param tyble_id:
:return:
"""
schedule_slot_array = (PLinApi.TLINScheduleSlot * 256)
schedule_table = schedule_slot_array()
count = c_int(0)
self.m_objPLinApi.GetSchedule(self.m_hHw, tyble_id, schedule_table, c_int(256), count)
for index in range(count.value):
schedule_entry = schedule_table[index]
print(
schedule_entry.Type,
schedule_entry.Delay,
schedule_entry.FrameId[0],
schedule_entry.CountResolve,
schedule_entry.Handle
)
def delete_schedule_table(self, table_id):
"""
:param table_id:
:return:
"""
self.m_objPLinApi.DeleteSchedule(self.m_hClient, self.m_hHw, table_id)
def start_schedule_table(self, table_id):
"""
:param table_id:
:return:
"""
self.m_objPLinApi.StartSchedule(self.m_hClient, self.m_hHw, table_id)
def resume_schedule_table(self):
"""
:return:
"""
self.m_objPLinApi.ResumeSchedule(self.m_hClient, self.m_hHw)
def suspend_schedule_table(self):
"""
:return:
"""
self.m_objPLinApi.SuspendSchedule(self.m_hClient, self.m_hHw)
def update_schedule_data(self, frame_id, data=[]):
"""
:param frame_id:
:param data:
:return:
"""
raw_data = (c_ubyte * len(data))()
for index, byte in enumerate(data):
raw_data[index] = c_ubyte(byte)
self.m_objPLinApi.UpdateByteArray(self.m_hClient, self.m_hHw, c_ubyte(frame_id), 0, c_ubyte(len(data)), raw_data)
def write_frame(self, frame_id, data=[]):
"""
:param frame_id:
:param data:
:return:
"""
frame_entry = PLinApi.TLINFrameEntry()
frame_entry.FrameId = c_ubyte(frame_id)
self.m_objPLinApi.GetFrameEntry(self.m_hHw, frame_entry)
msg = PLinApi.TLINMsg()
msg.Direction = PLinApi.TLINDirection(frame_entry.Direction)
msg.ChecksumType = PLinApi.TLINChecksumType(frame_entry.ChecksumType)
msg.Length = c_ubyte(frame_entry.Length)
for index in range(frame_entry.Length):
msg.Data[index] = c_ubyte(data[index])
private_id = c_ubyte(frame_id)
self.m_objPLinApi.GetPID(private_id)
msg.FrameId = c_ubyte(private_id.value)
self.m_objPLinApi.CalculateChecksum(msg)
self.m_objPLinApi.Write(self.m_hClient, self.m_hHw, msg)
def read(self):
"""
:return:
"""
msg_buffer = {}
while True:
msg = PLinApi.TLINRcvMsg()
if self.m_objPLinApi.Read(self.m_hClient, msg) == PLinApi.TLIN_ERROR_OK:
delta = ((msg.TimeStamp - msg_buffer.setdefault(msg.FrameId, msg.TimeStamp)) / 1000.0)
msg_buffer[msg.FrameId] = msg.TimeStamp
if msg.Length == 1:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0], msg.ErrorFlags)
)
elif msg.Length == 2:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1], msg.ErrorFlags)
)
elif msg.Length == 3:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2], msg.ErrorFlags)
)
elif msg.Length == 4:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2],
msg.Data[3], msg.ErrorFlags)
)
elif msg.Length == 5:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2],
msg.Data[3],
msg.Data[4], msg.ErrorFlags)
)
elif msg.Length == 6:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2],
msg.Data[3],
msg.Data[4],
msg.Data[5], msg.ErrorFlags)
)
elif msg.Length == 7:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2],
msg.Data[3],
msg.Data[4],
msg.Data[5],
msg.Data[6], msg.ErrorFlags)
)
elif msg.Length == 8:
print("{} ({:>14}) : 0x{:02X} {} - {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} [{}]".format(
msg.TimeStamp, delta, msg.FrameId, msg.Length,
msg.Data[0],
msg.Data[1],
msg.Data[2],
msg.Data[3],
msg.Data[4],
msg.Data[5],
msg.Data[6],
msg.Data[7], msg.ErrorFlags)
)
time.sleep(0.000001)
if __name__ == '__main__':
import threading
fuzzer = LinFuzzer()
fuzzer.connect("Fuzzer", 1, 1)
fuzzer.set_global_frame_table()
fuzzer.delete_schedule_table(0)
fuzzer.set_schedule_table(0)
fuzzer.get_schedule_table(0)
fuzzer.update_schedule_data(0x32, [0x00])
fuzzer.update_schedule_data(0x2B, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
fuzzer.update_schedule_data(0x30, [0x00, 0x00, 0x00, 0x00])
fuzzer.update_schedule_data(0x31, [0x00, 0x00, 0x00, 0x00])
fuzzer.update_schedule_data(0x20, [0x00, 0x00])
fuzzer.update_schedule_data(0x37, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
[b] readThread = threading.Thread(target=fuzzer.read, args=(,))
readThread.start()[/b]
fuzzer.start_schedule_table(0)
time.sleep(5)
fuzzer.suspend_schedule_table()
[b] readThread.join()[/b]
fuzzer.delete_schedule_table(0)
fuzzer.disconnect()
Whats wrong with this approach?
Thanks,
Volker
Last edited by M.Heidemann on Wed 18. Mar 2020, 07:55, edited 1 time in total.
Reason: Used the "Code"-Tag on the code posted for improved readability, please use the code-tags when posting code-snippets.
Reason: Used the "Code"-Tag on the code posted for improved readability, please use the code-tags when posting code-snippets.
-
- Sales & Support
- Posts: 425
- Joined: Fri 20. Sep 2019, 13:31
Re: LIN Master - Schedule Table Processing and Read
Hello Volker,
To quote:
As an additional info:
Once the shedule-table is started, it runs independently on the hardware.
Best Regards
Marvin
To quote:
Do you mean the delays between the messages of the shedule table?If I add the readThread part, then the timings (Interval ov the Frames) are not correct.
As an additional info:
Once the shedule-table is started, it runs independently on the hardware.
Best Regards
Marvin