From 92fab1429dad8db4c99c9db79f1f70b5862cc3fe Mon Sep 17 00:00:00 2001 From: PhilippHaefele Date: Tue, 20 Jan 2026 16:56:31 +0100 Subject: [PATCH] Add FS-RTOS support FS-RTOS is very similar to uC/OS-II, so no need to create a own implementation for it. We simply need to convert the event type enumeration / values. --- CHANGELOG.md | 1 + src/rtos/rtos-ucosii.ts | 109 +++++++++++++++++++++++++++------------- 2 files changed, 75 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7d6215..97baa2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log - Read stackTop for current running task with function contributed by @malsyned also in uc/OS-II. +- Add FS-RTOS support. FS-RTOS is very similar to uC/OS-II, so no need to create a own implementation for it. ## 0.0.14-pre1 - Jan 14, 2026 diff --git a/src/rtos/rtos-ucosii.ts b/src/rtos/rtos-ucosii.ts index 4785de1..62f1065 100644 --- a/src/rtos/rtos-ucosii.ts +++ b/src/rtos/rtos-ucosii.ts @@ -371,8 +371,9 @@ export class RTOSUCOS2 extends RTOSCommon.RTOSBase { eventObject: RTOSCommon.RTOSStrToValueMap, _frameId: number ): Promise { - const eventInfo: EventInfo = { address, eventType: parseInt(eventObject['OSEventType']?.val) }; + const eventTypeConverted = convertFsEventType(parseInt(eventObject['OSEventType']?.val)); + const eventInfo: EventInfo = {address, eventType: eventTypeConverted }; if (eventObject['OSEventName']?.val) { const value = eventObject['OSEventName']?.val; const matchName = value.match(/"(.*)"$/); @@ -459,42 +460,45 @@ export class RTOSUCOS2 extends RTOSCommon.RTOSBase { if (flagGroupPtr.variablesReference > 0 && flagGroupPtr.evaluateName) { const osFlagGrp = await this.getVarChildrenObj(flagGroupPtr.variablesReference, flagGroupPtr.name); // Check if we are looking at an initialized flag group - if (osFlagGrp && parseInt(osFlagGrp['OSFlagType']?.val) === OsEventType.Flag) { - const groupAddr = parseInt( - (await this.getExprVal(`&(${flagGroupPtr.evaluateName})`, frameId)) || '' - ); - const flagGroup: FlagGroup = { address: groupAddr }; - const reprValue = osFlagGrp['OSFlagName']?.val; - if (reprValue) { - const matchName = reprValue.match(/"(.*)"$/); - flagGroup.name = matchName ? matchName[1] : reprValue; - } - - // Follow the linked list of flag group nodes. The cast is safe here because we checked OSFlagType before - let flagNode = await this.getExprValChildrenObj( - `(OS_FLAG_NODE *)(${osFlagGrp['OSFlagWaitList']?.exp})`, - frameId - ); - while (flagNode) { - const waitingTcbAddr = parseInt(flagNode['OSFlagNodeTCB']?.val || ''); - if (!waitingTcbAddr || waitingTcbAddr === 0) { - break; + if (osFlagGrp) { + const flagType = parseInt(osFlagGrp['OSFlagType']?.val); + if (flagType === OsEventType.Flag || flagType === OsEventTypeFS.Flag) { + const groupAddr = parseInt( + (await this.getExprVal(`&(${flagGroupPtr.evaluateName})`, frameId)) || '' + ); + const flagGroup: FlagGroup = { address: groupAddr }; + const reprValue = osFlagGrp['OSFlagName']?.val; + if (reprValue) { + const matchName = reprValue.match(/"(.*)"$/); + flagGroup.name = matchName ? matchName[1] : reprValue; } - if (!result.has(waitingTcbAddr)) { - result.set(waitingTcbAddr, []); - } - result.get(waitingTcbAddr)?.push(flagGroup); + // Follow the linked list of flag group nodes. The cast is safe here because we checked OSFlagType before + let flagNode = await this.getExprValChildrenObj( + `(OS_FLAG_NODE *)(${osFlagGrp['OSFlagWaitList']?.exp})`, + frameId + ); + while (flagNode) { + const waitingTcbAddr = parseInt(flagNode['OSFlagNodeTCB']?.val || ''); + if (!waitingTcbAddr || waitingTcbAddr === 0) { + break; + } - const nextFlagNodeAddr = parseInt(flagNode['OSFlagNodeNext']?.val); - if (nextFlagNodeAddr === 0) { - break; - } else { - // Need to cast here since the next pointer is declared as void * - flagNode = await this.getExprValChildrenObj( - `(OS_FLAG_NODE *) ${nextFlagNodeAddr}`, - frameId - ); + if (!result.has(waitingTcbAddr)) { + result.set(waitingTcbAddr, []); + } + result.get(waitingTcbAddr)?.push(flagGroup); + + const nextFlagNodeAddr = parseInt(flagNode['OSFlagNodeNext']?.val); + if (nextFlagNodeAddr === 0) { + break; + } else { + // Need to cast here since the next pointer is declared as void * + flagNode = await this.getExprValChildrenObj( + `(OS_FLAG_NODE *) ${nextFlagNodeAddr}`, + frameId + ); + } } } } @@ -641,12 +645,47 @@ const PendingTaskStates = [ OsTaskState.PEND_FLAGGROUP ] as const; +// Used as OS_EVENT->OSEventType & OS_FLAG_GRP->OSFlagType enum OsEventType { Mailbox = 1, Queue = 2, Semaphore = 3, Mutex = 4, - Flag = 5 + Flag = 5, + Unknown = 0xff +} + +// Used as OS_EVENT->OSEventType & OS_FLAG_GRP->OSFlagType in some special uC/OS-II adaptions +enum OsEventTypeFS { + Mailbox = 0x0f, + Queue = 0x33, + Semaphore = 0x66, + Mutex = 0x99, + Flag = 0xcc +} + +function convertFsEventType(fsType: number | undefined): OsEventType { + let eventTypeConverted = OsEventType.Unknown; + + switch (fsType) { + case OsEventTypeFS.Mailbox: + eventTypeConverted = OsEventType.Mailbox; + break; + case OsEventTypeFS.Queue: + eventTypeConverted = OsEventType.Queue; + break; + case OsEventTypeFS.Semaphore: + eventTypeConverted = OsEventType.Semaphore; + break; + case OsEventTypeFS.Mutex: + eventTypeConverted = OsEventType.Mutex; + break; + case OsEventTypeFS.Flag: + eventTypeConverted = OsEventType.Flag; + break; + } + + return eventTypeConverted; } function getEventTypeForTaskState(state: OsTaskState): OsEventType {