Hi folks,

even if this wasn't discussed as much as the other things we discussed, I still 
think it's important.

So I was a strong advocate of the "promised land" ... I wanted to use promises 
and register callbacks for async execution.
Theoretically this I cool ... however I had to notice it's cool as long as you 
have someone cleaning up for you.
In most of the languages I encountered heavy usage of this pattern there are 
garbage collection mechanisms in place and then this is a great feature.

In C however this is not the case. Here you have to manually free previously 
allocated memory and if you don't do that, you'll run out of it pretty soon.

My main issue was that with promises it is difficulty to explicitly clean them 
up as you have no means to see which part of the program is still keeping a 
reference to it. If you clean that up and the other code access it, the failure 
depends on your OS but in all cases it's pretty bad.

So I decided to undo the promises, I just introduced a few days earlier. 

To keep the code half-clean I decided to instead use some manual state-machine 
like code.

Not much more to report besides the fact that I started implementing the actual 
logic. Up to now all methods sort of just returned empty or default objects. 
Now at least you can register drivers at the plc4c system and create connection 
structures, that correctly parse plc4x connection strings and lookup matching 
drivers in the registry. 

Guess in the following days I'll have to work on how I can actually define 
protocols in a way that I can have them processed in the central "loop" method 
without blocking the OS.

Feel free to discuss here or on slack.

I'll continue to post summaries to what's been going on.


Chris




Am 23.04.20, 18:34 schrieb "Christofer Dutz" <christofer.d...@c-ware.de>:

    Hi,

    today we worked quite a bit on making the directory structure more 
C-folks-friendly.
    So what we've now done, it we left the general directory structure 
unchanged, but eliminated the maven-like structure.
    So now every module has a "CMakeList.txt" file and a "src", "include" and 
"test" directory.
    "src" is pretty much what src/main/c and src/main/resources would have 
been, just mixed.
    Same applies for "test".

    The directory structure now matches that of a lot of other projects and it 
would even allow adding a second set of build configurations to allow building 
PLC4C with MyNewts "newt" build tool (But that's for the future ... no worries)

    Today I also added a "simulated" driver which should act similar like the 
one in PLC4J ... in the end it should respect the PLC4C API and be used as some 
dummy driver which mainly helps with writing hello_world applications as well 
as testing new integration modules.

    Also did I extend the "system" with a function to manually create and 
register drivers. 

    Especially in limited environments like embedded systems, I think the 
typical: "I just add all drivers and load what I need" doesn't work. Same as 
you can't just copy a driver to the device, a dynamic search and discovery 
mechanism would be overkill. We will definitely add similar loading mechanisms 
like in Java, but for now I'll work with manually registering drivers to keep 
it simple, small and efficient.

    So far the update for today.

    Chris


    Am 20.04.20, 16:41 schrieb "Christofer Dutz" <christofer.d...@c-ware.de>:

        Hi all,

        currently we’re in a mode of synchronous exchange on creating the PLC4C 
API on Apache slack “the-asf.slack.com” (Please send an email if you need an 
invite).
        We’re doing that as specially in the beginning this simplifies and 
speeds up things drastically.

        But as we’re at Apache and here “If it didn’t happen on the list, it 
didn’t happen” I’m trying to keep the list in sync with the outcome and give 
you folks the chance to participate by writing up summaries.

        So we have the great situation that Otto and Björn have quite some 
experience in C and C++ and are being a huge help with getting this started.

        So a few weeks ago I have already setup a build that’s integrated into 
our normal Maven build. However you need to enable to profiles in order to do 
that:

          *   with-sandbox
          *   with-c

        You need to run the maven build at least once as our plc4x-maven-plugin 
is a maven plugin and we need to have it generate some code first (or the build 
will fail)

        The actual build however is done with CMake. This allows us to use any 
CMake-capable IDE to develop PLC4C (I’m using CLion, but VisualStudio seems to 
also work fine).

        Today I created a branch feature/c-api as I think I’ll sometimes be 
committing unbildable stuff in order to allow collaboration (I commit something 
and others fix it ;-) ).
        So please follow this branch.

        Regarding the directory structure, we decided to stick to a structure 
that is sort of aligned with the one we have in PLC4X as this makes it easier 
to understand the structure (at least from a PLC4J point of view). The 
structure should also not be too strange for a c developer. What C developers 
might consider “an abomination” is that I started off using a directory 
structure for modules which is maven-inspired.

        The reason is that I think this allows to cleanly separate prod from 
test code and code from resources (In this case code from header files) … so a 
C module currently has the general structure:

        CMakeLists.txt
        src
        - main
        - c
        - include
        - test
        - c
        - include

        The CMakeLists.txt file is sort of the equivalent to our pom.xml … it 
tells CMake how to build the module. This is also where you define 
“dependencies” … however in C you rather define the locations of the 
header-files you intend on using … the actual using of code will happen by the 
linker when compiling.

        So now come the parts where I was super happy to have some help with:

          *   In the API module we have a set of header files which define the 
core functions and types
          *   However these types don’t really expose any information on the 
internals of PLC4X. So even if you have a connection structure, you can’t 
access any properties of this directly. If you want to access any properties, 
you need to use the corresponding function. So if in the “connection” domain 
you have a plc4c_connection structure, in order to access the connection_string 
property of that, you need to call the plc4c_connection_get_connection_string 
function and pass in your connection object.
          *   As a currently implicit naming convention we started using a 
prefix “plc4c_” for everything.
          *   We also split up the API functions into domains like “system”, 
“connection”, … all the functions which then results in names like 
“plc4c_system_create”. As we’re expecting the domains to grow, this way we hope 
to keep the sizes of the code blocks manageable.
          *   While the interface a user would use is defined in the API 
module, the implementation is then done in the SPI module (pretty much like in 
PLC4J)
          *   Initially we started playing around with callbacks, much like 
we’re doing in Java and as C does allow function pointers, that seemed like a 
good idea. But people actually coding in C mentioned that this form of coding 
feels very strange for full-blooded C developers. As we want this API to feel 
native for C developers, we’ll go down this path.
          *   As C doesn’t support a try-catch-finally style error handling, 
almost every function returns a return_code enum which can be translated into 
error messages by using some helper functions. So it is important to check if 
an operation returned OK and to do some error handling, if this is not OK.
          *   The API will completely not use synchronous operations. So we 
won’t provide a blocking “connect” function that returns as soon as the 
connection is established, as some of the systems we’re going to support are 
single threaded and don’t have any mutlitasking or scheduling. Therefore we’ll 
have a “plc4c_system_loop()” function which is cyclically called in order to do 
something.

        So far the update … I hope I didn’t skip anything …

        More will follow :-)

        Chris



Reply via email to