Pcan operations skill
Use when operating PEAK-System PCAN interfaces or PCANBasic-compatible hardware through PCANBasic or python-can. Covers discovery, Classic CAN and CAN-FD initialization, exact bit timing, safe read/write, status handling, filters, timestamps, cleanup, and bounded recovery.From its SKILL.md
npx -y skills add InitusNovus/pcan-operations-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.3 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it
PCAN Operations
Overview
Operate PCAN interfaces predictably through the native PCANBasic API or the python-can PCAN backend. The workflow is conservative: discover first, use explicit timing, keep ownership unambiguous, classify status/error records before data matching, and always prove recovery with a known-good frame.
When to Use
Use this skill when:
- Enumerating PCAN channels or inspecting capabilities and firmware
- Opening Classic CAN or ISO CAN-FD channels
- Calculating or applying PCANBasic FD timing strings
- Sending and receiving with PCANBasic or
python-can - Configuring acceptance filters, listen-only mode, or status/error records
- Diagnosing
ILLPARAMVAL,HWINUSE, queue errors, bus warning, passive, or bus-off - Building robust reopen/retry behavior
Do not use this skill for generic SocketCAN setup or electrical compliance measurements without PCAN hardware.
Safety Boundary
- Do not run active tests on a vehicle or production network without an approved test plan.
- Do not use vendor firmware update tools on hardware whose provenance and firmware compatibility are uncertain.
- Do not leave
PCAN_BUSOFF_AUTORESETenabled during diagnostics; it can hide the original fault. - A successful
Write/send()means the driver accepted the frame, not that another node ACKed or received it. - Bitrate mismatch can cause hardware auto-retransmission and an error storm. Bound mismatch tests tightly.
1. Establish the Runtime
PCANBasic is a native host API. On Windows, run the Python process on Windows even if orchestration starts in WSL:
py -3.11 -m pip install python-can==4.6.1
py -3.11 your_script.py
From WSL:
py.exe -3.11 C:\path\to\your_script.py
Completion criteria:
PCANBasic.dllloads without exception.PCAN_ATTACHED_CHANNELS_COUNTis nonzero.- The intended channel handles are available.
2. Discover Before Opening
Query these parameters before assuming channel numbers:
PCAN_API_VERSIONPCAN_ATTACHED_CHANNELS_COUNTPCAN_ATTACHED_CHANNELSPCAN_CHANNEL_CONDITIONPCAN_CHANNEL_FEATURESPCAN_HARDWARE_NAMEPCAN_FIRMWARE_VERSIONPCAN_CONTROLLER_NUMBERPCAN_DEVICE_ID
Treat device ID as one signal, not a globally unique identity. For multiple devices, combine handle, controller number, hardware name, and USB topology.
Completion criteria: each selected channel reports an available condition and a stable controller number.
3. Classic CAN Initialization
With python-can:
import can
bus = can.Bus(
interface="pcan",
channel="PCAN_USBBUS1",
bitrate=500_000,
auto_reset=False,
)
With PCANBasic:
from can.interfaces.pcan.basic import PCANBasic, PCAN_USBBUS1, PCAN_BAUD_500K
api = PCANBasic()
result = api.Initialize(PCAN_USBBUS1, PCAN_BAUD_500K)
Check result == PCAN_ERROR_OK; do not continue from a partial pair initialization.
4. CAN-FD Initialization
PCANBasic uses explicit timing values. A bitrate pair alone is insufficient.
Known exact 500 kbit/s nominal / 2 Mbit/s data timing:
FD_500K_2M = {
"fd": True,
"f_clock": 80_000_000,
"nom_brp": 1,
"nom_tseg1": 127,
"nom_tseg2": 32,
"nom_sjw": 32,
"data_brp": 1,
"data_tseg1": 31,
"data_tseg2": 8,
"data_sjw": 8,
}
Exact 500 kbit/s nominal / 12 Mbit/s data timing on hardware that supports a 60 MHz clock:
FD_500K_12M = {
"fd": True,
"f_clock": 60_000_000,
"nom_brp": 1,
"nom_tseg1": 95,
"nom_tseg2": 24,
"nom_sjw": 24,
"data_brp": 1,
"data_tseg1": 2,
"data_tseg2": 2,
"data_sjw": 2,
}
Verify the derived rate:
bitrate = f_clock / (brp × (1 + tseg1 + tseg2))
Do not approximate 12 Mbit/s from an 80 MHz clock. Reject any configuration whose derived rate is not exact.
See references/bit-timing.md for the timing workflow.
5. Read and Write Discipline
For every frame, distinguish:
- Generated by the application
- Accepted by the driver
- Received by the peer
- Matched by ID, frame type, DLC, flags, payload, sequence, and integrity code
A robust receiver must classify records before matching:
valid— expected current-phase framestale— valid frame from an earlier phasestatus—PCAN_MESSAGE_STATUSerror—PCAN_MESSAGE_ERRFRAMEunexpected— other ID/typebad— current-phase frame with invalid content
Only valid satisfies a transfer. A status or error record must never be silently accepted as payload.
6. PCAN Status Records
PCANBasic defines:
PCAN_MESSAGE_STATUS = 0x80
The python-can PCAN backend exposes Extended, RTR, FD, BRS, ESI, Echo, and Error flags, but may not surface the status bit as a dedicated can.Message attribute. A PCAN status record can therefore look like an ordinary frame, commonly:
ID 0x001, DLC 4, DATA 00 00 00 00
Inspect raw TPCANMsg.MSGTYPE or disable status records when they are not needed:
api.SetValue(channel, PCAN_ALLOW_STATUS_FRAMES, PCAN_PARAMETER_OFF)
Do not infer wire traffic from an API record until the raw message type has been checked.
7. Filters and Listen-Only
Filter tests must interleave:
- Allowed frame received
- Rejected frame not received
- Allowed frame received again
This prevents a dead receiver from masquerading as a successful filter.
For listen-only mode:
- Enable it only after initialization if the API requires that sequence.
- Do not transmit while passive.
- End the passive phase with uninitialize rather than assuming every implementation supports toggling it live.
8. Safe Cleanup and Bounded Retry
Use one owner per channel. If opening the second channel fails, close the first before retrying.
stop sender → stop receiver → shutdown both buses → uninitialize both handles
→ short backoff → reopen → status check → bidirectional canary
Recommended policy:
- 2–3 attempts
- 20–100 ms incremental backoff
- complete cleanup before each attempt
- retry count and original exception preserved
- success only after
GetStatus()==0and a known-good transfer
Use templates/safe_open.py as a starting point.
9. Timestamp Handling
Classic TPCANTimestamp total microseconds:
micros + 1000 × millis + 0x100000000 × 1000 × millis_overflow
For FD, TPCANTimestampFD.value is already in microseconds.
Use host perf_counter_ns() for intervals and API latency. Do not subtract a hardware timestamp from a host timestamp unless their clock domains and epoch mapping are known.
Common Pitfalls
- Passing only
bitrateanddata_bitrateto a PCAN FD channel that requires explicit timing. - Treating
send()success as proof of ACK or peer reception. - Mixing raw PCANBasic ownership with a live python-can bus on the same handle.
- Calling global uninitialize while another process owns a channel.
- Draining receive queues before accounting for stale, status, and error records.
- Retrying application frames automatically and hiding the original loss or creating duplicates.
- Leaving a partially initialized channel open after its peer fails.
- Treating a status record as an ordinary CAN frame.
- Using device ID alone to distinguish multiple interfaces.
- Applying firmware updates to unsupported hardware.
Verification Checklist
- Runtime is Windows-side and PCANBasic loads
- Intended channels are discovered and available
- Derived nominal/data bitrates are exact
- Both channels initialize or both are cleaned up
-
auto_reset=Falseduring diagnosis - Status and error records are classified explicitly
- Send success is followed by peer payload validation
- Shutdown exceptions do not prevent cleanup of the other channel
- Recovery ends with status zero and a bidirectional canary
- Logs preserve timing, channel, mode, retry count, and raw error code
What ships with it: 8 files
7.2 KB alongside SKILL.md, 1 of them executable
references/
- bit-timing.md949 B
- pcanbasic-api.md1.0 KB
- python-can-backend.md707 B
templates/
- safe_open.pyruns1.2 KB
- .gitignore41 B
- LICENSE1.0 KB
- README.md2.0 KB
- RELEASE_NOTES.md196 B
Gives 0 of the 12 instructions most operations skills give in ~2.0k tokens
Counted across 483 of the 484 authors here whose files we hold, read 2026-08-07
- Collect monitoring data throughout the simulationin 14 of 483, across 6 files
- Set the random seed for reproducibilityin 14 of 483, across 6 files
- Validate simulations against analytical solutionsin 12 of 483, across 4 files
- Clarify goals, constraints, and inputsin 11 of 483, across 2 files
- Implement contract tests for integration pointsin 11 of 483, across 2 files
- Implement strangler fig infrastructure with API gatewayin 11 of 483, across 2 files
- Audit modernized components for security vulnerabilitiesin 11 of 483, across 2 files
- Avoid Python blocking calls in processesin 10 of 483, across 3 files
- Use resource context managers for automatic cleanupin 9 of 483, across 2 files
- Maintain consistent time unitsin 9 of 483, across 2 files
- Validate outcomes against success criteriain 8 of 483, across 1 file
- Analyze the legacy codebase for technical debtin 8 of 483, across 1 file
Said here and by no other author read
- discover channel handles before opening
- query device parameters to identify hardware
- verify derived bitrates are exact
- reject approximate timing configurations
- set auto_reset false during diagnostics
- disable status frames when unneeded
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.