Scheduling a Real Time Thread via PREEMPT_RT
Since the 2152 Linux Kernel contains the PREEMPT_RT patch, my assumption is that the ESM uses such to schedule its processes for real-time execution. This would mean that instead of trying to use or adapt the ESM to schedule processes completely outside of PC Worx Engineer, one could simply use PREEMPT_RT to schedule their own real time processes to run in the unused real-time space alongside of PLCnext services.
First, to verify that PREEMPT_RT is installed, use the uname –v command. The results should look like the following:
With PREEMPT-RT, if you create and join a thread with a param.sched_priority of something like 80, the kernel will actually give you such a priority.
On a side note, I read that param.sched_priority legal values on typical Unix systems range from 40 to 80, where only a privileged user can set above 60. Anything from 1 to 39 is set to 40 and anything from 81 to 127 is set to 80. Also note that priorities in the Kernel look a little different from user assigned priorities, where 0 to 99 are reserved for real-time processes and 100 to 139 are for normal processes. Also, to confuse things even more, for real-time processes, kernel representative priority is calculated by inverting the priority (where lower value indicates higher priority).
What all of this means for the example is that to get the highest possible priority, use param.sched_priority = 80;. If the priority actually assigned by the kernel is positive, it’s a normal process. If the priority assigned by the kernel is negative, it’s a real-time process.
Running the example code on Pi v1_B, even though I am requesting 80, it gives me 20 since I do not have real-time access to the kernel on a standard Raspbian installation. Use htop to observe the running processes. Use shift+h while in htop to display all current running threads. Here is a snippet of the example process:
Running the same code on AXC 2152 gives the following results:
We can see that the main thread was given the same priority of 20, but this time it was allowed to spawn a real-time thread with priority of -81.
Example code can be found here:
https://wiki.linuxfoundation.org/realtime/documentation/howto/applications/application_base
Notice towards the bottom where pthread_create is called, the thread_func function is being passed. So just put code in void *thread_func(void *data){} to keep the CPU busy long enough to observe PREEMPT_RT in action.
Also, since we have a lot of the US early adopters are talking about prototyping on a Raspberry Pi, I compiled this on Pi v1_B (same ARM instruction set as the 2152 chip) using gcc –pthread –o RT_Example RT_Example.c –static and then moved the executable over to the 2152 to test.
With the ability to schedule one’s own real-time processes on the AXC 2152, the only missing piece to a complete control application outside of PC Worx engineer on AXC 2152 is the GDS Subscriptions API. This would allow access to things like I/O and OPC UA. The only troubling matter is the following:
Was this diagram generated with the idea that the user would only have the knowledge to schedule their own programs via the standard Linux scheduler? Or can the GDS Subscriptions API be included in a program whose process will spawn a real-time thread to, for example, read/write to inputs/outputs?
Side note, moderators should add just plain "C" as a tag since most Linux system examples will be shown in C and not C++.
Comments
Hi Jacob,
Great post! To me, this demonstrates another layer in the PLCnext architecture, for people who want to go that deep ... of course this isn’t for everyone, but it’s a credit to the openness and flexibility of the PLCnext platform that this is even possible. The ESM and GDS provide people like me - who don’t have the knowledge and/or skill to roll their own real-time processes or inter-process communications methods - the ability to access these sorts of real-time features for fast and reliable application development. And PC WORX ENGINEER is an even higher layer for people who don’t want or need to know about C/C++ programming.
You mention that access to a GDS Subscriptions API would allow access to I/O and OPC UA ... I guess it would be possible to access the physical I/O through Axioline and Profinet C/C++ libraries, rather than through GDS. And it’s definitely possible to implement an OPC UA client in C/C++ without GDS. GDS may be useful for communication between your own processes, but of course this is also possible using other interprocess communication methods. The one place that GDS may be unavoidable is when exchanging data with IEC programs written in PC WORX ENGINEER - although even here you could use files or TCP sockets to exchange data (but only if you don’t want the benefits that are built-in to the GDS).
Thanks again for the interesting and thought-provoking post.
- Martin.
Thank you for the kind words Martin!
We essentially have two different requests from our early adopters in the US that there is no documentation for. 1. C/C++ only with access to I/O bus. 2. C/C++ that runs in Linux and that can interact with the PCWE program. Now that I think about your comments, the GDS Subscriptions API will likely address #2 only. The final questions in the post are still valid though. A customer can use this API to have their real-time (via PREEMPT_RT) C/C++ Linux program interact with their IEC program. So what's up with that last image (found in a PxC document) stating that GDS subscriptions cannot be real-time?
Also, ideally, both #1 and #2 would be addressed as #include's to your C/C++ program. Just like how a Pi accesses a Pi Face I/O board for example.
Hi Jacob,
Most of the services like OPC-UA and the eHMI are implemented as (User)Components within the PLCnext Context, which can access internals in the runtime, having a non-realtime characteristic. From those so called UserComponents, there are some services availble for Subscribing to GDS/system data, getting lowlevel access and even implementing your fieldbusses, but the latter for sure isn't a trivial task and likely requires deep insight knowledge of the systems and sharedmemory access which typically requires input from the development department. To my understanding the GDS construct is also a runtime-core-feature (but i'm no developer, so i could be wrong ). Hence you would require the runtime to be available at all times.
That beging said, from these User-Components you might also spawn thread which you fireup with realtime- priorites, and handing you with access to the services. Especially if your looking to integrate your own. So those UserComponents yield access to the API's.
To my knowledge, having access to IO would require the runtime to be active. Handing out priorities at such high levels might compromise fieldbus reliability as the scheduler which handles field-busses and stacks might starve due to changed scheduler prio's.
But to resume on your questions:
1. C/C++ only with access to I/O bus:
You can of-course span your software like a regular c++ program (so PCWE library) within PLCNext. Having only a single program, and scheduling this frequently. would require a one-time effort to provide the interfaces to/from the pogram and and just swap the logic by uploading future versions of your shared-object. Alternatively you could create your software within an 'User Component' and handle stuff from there. You would end up with an Run-time on the controller, providing data access and using the service-apis and callbacks to synchronize with the runtime and ofcourse IO/GDS/OPC/...
However more documentation regarding these services is mandatory, and is likely to be released in the near future.
2. C/C++ that runs in Linux and that can interact with the PCWE program: There are various ways of achieving this, you could use any message-broker/tcp-connection/... to exchange data back and forth the PCWE and vanilla Linux-domains. Personally i've used NATZ, Redis TCP-connections. When docu will be available regarding RPC services you might opt to use these mechanisms, rather than rolling your own. All depends obviously on real-time requirements, data consistency considerations, ... you have.
I guess that in most scenarios you probably needs the to have access to 'comodity functions', but perhaps someone with better insights might have a different view on the matter
Cheers
Hi Jacob,
thanks also from my side for your great post and I guess the discussion shows how important also additional documentations and examples are. I can confirm that we will have the first examples and docs available end of March. However we are at the beginning of a long term project and especially this part of the story is enormously complex and will need time to be completely discovered.
I’ve spoken today with a few guys from the development and I hope the following information will help you in the meantime.
But before starting, forget the diagram you found on the early adopter slides, it is very simplified and outdated (I know that, because it was from me ).
Better use the one from the Architecture of PLCnext Technology article.
As Vincent already wrote is the firmware essentially composed of different components (system, IO and service), the so called core components. The components are started in a defined order and most are mandatory and some optional in the boot up sequence.
Every component offers services which are available for other components (Remote Service Calls).
Those services could be to get the state of the PLC as well as access the IO. However this will be part of the coming documentation.
It is already with the current firmware possible to create an own internal user component which is started from the PLCnext system manger (system component) and can use the RSC. Inside the internal user component you were able to start threads in non -but also inside the real-time context.
All this is running inside the PLCnext ecosystem.
It is also possible (and this was meant last year with the “GDS subscription”) to access the RSC from other Linux processes.
We will need this to integrate other complex frameworks or maybe other IEC 61131-3 run-times.
All those would need a fast access to the IO system. I guess we will see the first steps how to do so after summer time.
So, you’ll have three ways to handle real-time applications.
I’m no Linux specialist, but I hope that was helpful and please stay patient until the first example is available.
Step by Step!
Take care!