-
Notifications
You must be signed in to change notification settings - Fork 25
Add support for SMP on FreeRTOS #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I have close to 0 experience with pull requests on github, similar with VS code extension developement and typescript... so I'd be very gratefull if someone could help me with the process. |
|
@hwmland First of all thank you very much for your contribution. I did have a quick look look over the code and seems to be ok in general (no real world testing and FreeRTOS code check done). Still @haneefdm and my concerns that we should properly support SMP (multiple cores) are not addressed #14 (comment). I do need to check latest FreeRTOS code and see if anything general changed in the meanwhile (e.g. removal of old pxCurrentTCB) which maybe would admit an intermediate / incomplete adaption. What was the issue with #43? Which part of your changes fixed it? I personally can't see a relation in the changes. |
|
Just did check the code and when we do not have more than one core via So the extension/FreeRTOS part should build up multiple tables, one for each core. When there's only one core we should not have an issue regarding the general functionality (maybe other things have changed that result in problems like #43, which should be addressed in a separate PR). Also when using only one core with a core configuration of > 1, we maybe need to use the second instance in the array (haven't checked how cores are addressed in |
Ummm. With SMP there should still be one table. That is my thought. SMP means that the RTOS will schedule a thread to any available core (with possible affinity or binding). To me, that is what SMP means. Or, does FreeRTOS not work like how normal SMP works for CPUs and Desktop OSes If there is one instance of RTOS, there should be one table. That is another thought. This is why I was having trouble tackling this. I need to understand how this actually works. I didn't want to guess. I don't have a test case and the right HW was also another problem. |
|
Hello, I'll try to answe to all remarks:)
I think I did so. I show proper status of all threads, for running threads I show on which core it runs
Generally port defines
Exactly this way it works. There are still 'common' lists of threads (blocked, ready, ...) for both cores, scheduler is just able to schedule them on multiple cores, so there could be more threads in the running state.
There are now 2 oficiall examples ( |
Can you create an actual application and put it on github.
Unlike other extensions I own/support, this is a unique one. Anyone who contributes has to do that is it is impossible to know all the different OSes. |
Sure, I’ll. Just some questions to be sure:
|
Sorry missed that on my smartphone 🫢. And of course in SMP we're good with one table. Mixed AMP, SMP and SMP with core pinning somehow in my head. @haneefdm Thanks for jumping in here. I do have some RP2040 boards lying around, so I'm happy to help with testing once the example project ist setup 😃 |
|
Example project with simple build instructions are here |
|
some updates? is it going to be merged? |
|
Well - last merge to this repo is March 2023... If you want it, I'm afraid you have to fork and be on your own... |
|
Will try to test this soon. Was very busy and @haneefdm also (see Marus/cortex-debug#1027) |
|
hi @PhilippHaefele ,i try this at my esp32 board which use freertos. it use smp so mainline can`t match rtos type. but @hwmland esp32 also have double core, and it all show |
|
Hello, for whatever reason it does not read xTaskRunState from TCB here: const xTaskRunState = thInfo['xTaskRunState']?.val;I don't have environment set for esp32 nor time now to do so now (and honestly no motivation anymore as there is no view to progress with rtos-views now). If you want to investigate yourself and perhaps improve this PR - try to check why xTaskRunState is not there. Just put breakpoint after this block: const thInfo = await this.getExprValChildrenObj(
`((TCB_t*)${RTOSCommon.hexFormat(threadId)})`,
frameId
);and check what is awailable in thInfo - perhaps this explains us something... Edit: additional though: @USTHzhanglu, do you have perhaps link to repo with your FreeRTOS you are using? Perhaps we'll see there something obvious in TCB. Please check as well how you defined |
thanks for answer.i don't know why i if (this.pxCurrentTCB !== null) {
threadRunning = threadId === this.curThreadInfo;
mySetter(DisplayFields.Status, threadRunning ? 'RUNNING' : state);
} else {
const xTaskRunState = thInfo['xTaskRunState']?.val;
if (xTaskRunState !== undefined) {
if (xTaskRunState === '-2') {
threadRunning = false;
mySetter(DisplayFields.Status, 'YIELD');
} else if (xTaskRunState === '-1') {
threadRunning = false;
mySetter(DisplayFields.Status, state);
} else {
threadRunning = true;
mySetter(DisplayFields.Status, 'RUNNING(' + xTaskRunState + ')');
}
} else {
if (this.pxCurrentTCBs !== null) {
threadRunning = threadId === this.curThreadInfo;
mySetter(DisplayFields.Status, threadRunning ? 'RUNNING' : state);
} else {
threadRunning = false;
mySetter(DisplayFields.Status, 'UNKWON');
}
}
}finally, very thanks for yor PR, it`s very useful for me. |
|
Will merge it soon. Sorry, but my absence was unavoidable. Questions
The rest looks good, but I haven't reviewed the code.
I would not expect the chip has anything to do with it. It has to be FW or our code right? |
|
Hello @haneefdm , nice to have you back! I hope you don't take my post as blaming you - it was not ment so. I hope you are fine now! But back to the business :)
I agree that it has nothing to do with chip (but don't know it there is some special/hacked version of FreeRTOS for this chip) -> FW As to your concert about runtime on cores with different clock speed - up to my knowladge it's calculated based on ticks and those are the same (I hope) independent on frequency |
Yes, guess it is normalized to a tick. It is fine. It was more of a curiosity.
Clearly the FW is different between the two examples. The sheer number of Back to the FW, how can we figure out whose version is the truth? One of the links you provided matches what is the current release. (V11.1.0) In the past, I had said that there were changes in FreeRTOS data structures and I was told that doesn't happen. I think it does happen. The last LTS release seems to be 10.4.3 on Sep 16, 2022. It appears that neither links to tasks.c are using officially released versions. Granted that it just shows the comments that are mass edited. But what it tells me is that there are too many versions floating around and sometimes people are picking up whatever is current at the time. I see the type of changes since last LTS and they have to do with SMP support, security, support, new architectures, MPU, etc. I don't think FreeRTOS people consider it to be LTS ready. Why am I saying all of this? In the least, we should settle on one published minimum version and claim support for that and let people use it at their own risk, other/newer versions. And, report issues and volunteer to help. |
|
@hwmland @haneefdm i know why. private updateCurrentsThreadAddr(frameId: number): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (this.pxCurrentTCBs !== null) {
this.pxCurrentTCBs?.getValue(frameId).then(
(ret) => {
if (ret !== undefined) {
const match = ret.match(/\d+/);
this.pxCurrentTCBsNum = match ? parseInt(match[0]) : 0;
} else {
this.pxCurrentTCBsNum = 0;
}
my_log(`pxCurrentTCBsNum: ${this.pxCurrentTCBsNum}`);
for (let i = 0; i < this.pxCurrentTCBsNum; i++) {
this.getExprVal('pxCurrentTCBs[' + i + ']', frameId).then(
(ret) => {
this.curThreadInfos[i] = parseInt(ret || '');
},
(e) => {
reject(e);
}
);
}
resolve();
},
(e) => {
reject(e);
}
);
} else {
resolve();
}
});
} const xTaskRunState = thInfo['xTaskRunState']?.val;
if (xTaskRunState !== undefined) {
if (xTaskRunState === '-2') {
threadRunning = false;
mySetter(DisplayFields.Status, 'YIELD');
} else if (xTaskRunState === '-1') {
threadRunning = false;
mySetter(DisplayFields.Status, state);
} else {
threadRunning = true;
mySetter(DisplayFields.Status, 'RUNNING(' + xTaskRunState + ')');
}
} else {
if (this.pxCurrentTCBs !== null) {
threadRunning = false;
for (const num in this.curThreadInfos) {
if (this.curThreadInfos[num] === threadId) {
threadRunning = true;
mySetter(DisplayFields.Status, 'RUNNING(' + num + ')');
break;
}
}
if (!threadRunning) {
mySetter(DisplayFields.Status, state);
}
} else {
threadRunning = false;
mySetter(DisplayFields.Status, 'UNKNOWN');
}
}
}at mainline freeRTOS, the pr is good. |
|
Ok, so we have answer what was going on with ESP32 (FreeRTOS hacked by ESP) I'll ignore this in following anylyzis and return to it later.
So I'd say that extension should be valid/working for Finally - to have ESP32 support, @USTHzhanglu changes should be merged (as his code would not work for other FreeRTOS) My problem is that I still did not recreate my dev environment after computer crash in December and I'm not able to test it. Based on my work I don't see possibility to find enough time for this before summer :( |
@hwmland Did you mean that? So, we only support ESP version? Or do I have it backwards? In case there is a misunderstanding, we should be worried about the general user first. Then add other implementations if they are important. It is not okay to say, my needs are met and not worry about other users. Not saying you are thinking like that, but just a reminder. |
|
Sorry, I was not clear. |
|
now we have Three situations
i think this pr just not included 3. private pxCurrentTCBsNum = 0;
private curThreadInfo = 0; // address (from pxCurrentTCB) of status (when multicore)
private curThreadInfos: number[] = []; //address (from pxCurrentTCBs) of status of all threads (when multicore)add a new fuction private updateCurrentsThreadAddr(frameId: number): Promise<void> {}use this fuction at promises.push(this.updateCurrentThreadAddr(frameId));
promises.push(this.updateCurrentsThreadAddr(frameId));finally if pxCurrentTCB is null, xTaskRunState is undefined,and pxCurrentTCBs not null, for (const num in this.curThreadInfos) {
if (this.curThreadInfos[num] === threadId) {
threadRunning = true;
mySetter(DisplayFields.Status, 'RUNNING(' + num + ')');
break;
}
}and if all of them is null ,we Prompt unknown else {
threadRunning = false;
mySetter(DisplayFields.Status, 'UNKNOWN');
} |
|
Hello, from my point of view no problem if you push changes to 'my' PR, our common goal is to make things better. Much more question to @haneefdm what he thinks - what is better/more safe. promises.push(this.updateCurrentThreadAddr(frameId));
promises.push(this.updateCurrentsThreadAddr(frameId));those 2 methods have too similar names for my taste, it's confusing, took me time till I realized they are different... |





This PR resolves #14 and resolves #43