coder . cl » c http://coder.cl web developer & system programmer Sat, 03 Nov 2012 12:37:47 +0000 en hourly 1 http://wordpress.org/?v=3.4.2 hierarchical state machines http://coder.cl/2012/10/hierarchical-state-machines/ http://coder.cl/2012/10/hierarchical-state-machines/#comments Mon, 29 Oct 2012 15:33:00 +0000 Daniel Molina Wegener http://coder.cl/?p=2921 I need to work with a hierarchical state machine. The main problem that I am currently facing is how to pass messages or trigger events on each event transition. Since I am using C Plus Plus, I will use class methods. In this case, I will use a hardware device class method. On each state transition, an event will be thrown, and the given event should trigger an action — in this case a class method — that will complete the state transition. The advantage of the hierarchical state machine is the fact that you can manage composite hardware devices without problems, because each sub-device can be handled individually with its own state, but increases the complexity of the program.

On this case, I will iterate over the list of units on the scheduler — where each unit is a composite device — it will assign a new work state on each device, calling the run method on the device object. The run method will launch the child state machine of the required action, but the parent state machine only has few states storing the device status, so the processing scheduler knows which event should be triggered on each scan cycle. The required state transitions on the parent state machine, which are informational rather than hardware related, will be useful handling nested event handling.

Each cycle will determine whether read or write actions should be triggered, even if they are manual or automatic operations on each device, and only then the program will be able to call read and write once they are required. There are some actions not using the communication channel, so I can avoid calling read and write, enhancing the application performance a little, but still I will need to check the device state to check for some automatic reads, required to display the device state and ModBus holding registers.

You can find several models of hierarchical state machines, but I prefer to write one using events bound to class methods, where each class method drives an action on the device. This approach is simpler than others using signals and similar event handling methods, but I need to keep the source code as simple as possible, because increasing the complexity should increase the development time. Finally, the unit class will be only a gateway to the each hardware device, where each state will be triggered by the scheduler. Before this model, I was using a priority queue using messages, very similar to message queues, but is required on this system, to have direct access to the device state, and that message queue is not so synchronous as it is required, where a direct feedback from the device should be placed on each state transition.

Now I have finished the scheduler and the state machine processor, I just need to complete the integration between each component and I will deliver the new device management application. Also, the HMI has changed a little, and the new model allows some direct actions like resetting the device and its state.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/hierarchical-state-machines/feed/ 0
compiler flags for correctness http://coder.cl/2012/10/compiler-flags-for-correctness/ http://coder.cl/2012/10/compiler-flags-for-correctness/#comments Fri, 05 Oct 2012 10:52:29 +0000 Daniel Molina Wegener http://coder.cl/?p=2853 As I have discussed on a previous blog post, static typing helps on correctness by providing well-typed programs through type checking algorithms. Compiler warning messages and compiler error messages are not thrown as they were made by a capricious developer. Almost all of them are following a language definition, and they help if you want to build better programs. The more strict are your compiler flags, better are your programs. Using language extensions, which are not present on their standard definitions is not so cool as it seems. That depends on the language, sometimes there is very long time after certain language extensions are passed to the language definition. So, you should try to look on how can you write better code for that language without abusing of its extensions and extra features provided by the compiler.

Almost every compiler or language interpreter has warning and error flags that can help you to write better code. On my case, I use the flags “-Wall -Wextra -Wshadow -pedantic -std=c99” with gcc(1) and “-Wall -Wextra -Wshadow -pedantic -std=c++98” with g++(1). That allows me to write better source, which can be compiled by different versions of the same compiler, and that source code is easier to be migrated to other platforms, because it is not abusing of some nifty gcc(1) extensions. The same strictness is applied to other languages. I compile Haskell source code using the flags “-Wall -Werror” with ghc(1). I think that you have similar options in your compiler, and what those compiler flags on my examples are doing is pretty clear — if you have deep programming practices.

The same applies to language interpreters. I recall my Perl scripts starting with the “-W” and the “use strict” directives. So, compiler flags can help you to write better code, but sometimes compiler flags are not enough to build better programs. You can use third party tools that can help you too. Most compiler flags enabling strict checks are making your code use a better approach on its type checker and language constructs, but there are some third party tools that will allow you to check your source code for common mistakes and flaws. That is the case of static analyzers, metric tools and style checkers. Each tool will bring you a better idea about how your code can meet correctness through a type checker and similar semantic analysis. Strict language semantics will lead you to better scopes of your program goals. For example if you are working on a Python 2.X project, that will be ported to Python 3.X, you can use the “-3” flag to warn you about incompatibilities with Python 3.X. Start reviewing your compiler flags, playing a little with them, learning on how your compiler can enhance your programming practices.

Correctness can be easily reached if you can use strict semantics of your favorite programming language. For example if you are using Python as a programming language, you can use some static analyzers like pylint, pycheckers, pep8 and pyflakes, among other tools. If you can pick all those warnings thrown by that kind of tools and your compiler flags, you will be writing better code.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/compiler-flags-for-correctness/feed/ 0
base conversion tricks http://coder.cl/2012/10/base-conversion-tricks/ http://coder.cl/2012/10/base-conversion-tricks/#comments Thu, 04 Oct 2012 11:13:10 +0000 Daniel Molina Wegener http://coder.cl/?p=2847 Base conversion can be used to compress number representations, and can be used to hide the real number representation. The algorithm is well known, anyone can program that algorithm, and it is not so hard to handle. I was playing with Haskell writing that algorithm to check how effective is that algorithm to create URL shorteners. My idea is quite simple, you have an URL database ID, which is an integer number, indexed as many entries on the database, but once the database starts growing, the number can reach a length that is not so easy to remember. For example the ID 999 999 999 999 is not so easy to remember.

The basic algorithm is to have an ASCII alphabet as representation of positional numeric system symbols, and then to apply the standard base conversion algorithm using that alphabet to get the string representation of the number, so encoding and decoding algorithms in Haskell can be written as follows.


alpha :: String
alpha = "0123456789"
        ++ "abcdefghijklmnopqrstuvwxyz"
        ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        ++ "._"

alphaLength :: Integer
alphaLength = fromIntegral $ length alpha

aenc :: Integer -> String
aenc i = let fin = fromIntegral alphaLength
             encn :: Integer -> String -> String
             encn x y
                 | x == 0 = reverse y
                 | otherwise = let (n, m) = x `divMod` fin
                                   r = alpha !! fromIntegral m
                               in encn n $ y ++ [r]
         in encn i []

adec :: String -> Integer
adec i = let fin = alphaLength
             lns = fromIntegral $ length i
             decn :: String -> Integer -> Integer -> Integer
             decn (x:xs) y z = let
                 pw, el, nm :: Integer
                 pw = lns - (fromIntegral z + 1)
                 el = fromIntegral
                      $ fromJust
                      $ elemIndex x alpha
                 nm = (el * (fin ^ pw)) + fromIntegral y
                 in decn xs nm (z + 1)
             decn [] y _ = y
         in decn i 0 0

The encoding and decoding algorithms above are using a numeric base of 64, and the alphabet is case-sensitive. So, for the number 12 345 we have the string representation on numeric base 64 as “30V”. The number 999 999 999 999 has the representation as “ezkFg__” and 999 999 999 999 999 has the representation as “3znWAND__”. The trick on the base conversion on numbers with that size is made thanks to the data types used on the base conversion. The standard integer and long data types in C have up to 64 bits and probably 128 bits in some systems. Still they have a limit. With the Integer data type in Haskell there is almost no limit because they are “arbitrary-precision integers”. To use that kind of numbers on C, you must install a library like apcalc.

Also you can hide the number representation if you keep your alphabet private and you modify the positional symbols, where you can have a very different number representation of any number using this kind of base conversion, depending on your alphabet. Another option is to use bit representations, so you can extend the base alphabet to other ASCII symbols and have an extended base conversion, for example using 128 printable characters you can have a base 128 encoded number.

This encoding is very similar to Base N encoding, but the algorithm is quite different. It is being described on the RFC 4648. I have implemented that algorithm but any alphabet and any base encoding on the Caffeine Project — you can use base 128 if you want — and the difference with other implementations is the fact that it can handle streaming data, so you can create base encoded streams, and do not requires fixed size buffers. The standard functions can encode fixed size buffers, and encode_stream and decode_stream can encode and decode streaming buffers. You can see the source code here.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | One comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/base-conversion-tricks/feed/ 1
type safety is not security http://coder.cl/2012/10/type-safety-is-not-security/ http://coder.cl/2012/10/type-safety-is-not-security/#comments Tue, 02 Oct 2012 11:58:17 +0000 Daniel Molina Wegener http://coder.cl/?p=2840 Standar ML is defined as safe using the following definition «ML is safe, in that a program that passes the type-checker cannot dump core, access private fields of abstract data types, mistake integers for pointers, or otherwise “go wrong.”». A type-checker verifies that each term used in the programming language should have the correct type once it is used. For example if a function is defined to receive an integer type, once it is called, an integer term should be used, otherwise the compiler may throw an error and the execution “goes wrong”. If the type-checking algorithm accepts the program, then it is well-typed. When a programming language has a type-checking algorithm on its compiler, we call it statically-typed. Dynamic typing does not have a type checker on its compiler, you can write the same function, it will not have any sentence defining an input type, and it will be able to receive a string when an integer is required.

Static typing have its basis on the “Semantic Soundness Theorem”. This theorem states that an environment p is on the domain of the type environment Γ, where each variable x in p respects the environment Γ. Then, if an expression e has the type τ in the environment Γ and the environment p respects Γ, the expression e in p has the type τ. In other words — if you have experience with Haskell or Standard ML — once you create a function of type τ, the function as expression should have the type τ. Seen from another perspective, if you define a function prototype in C as double f (double x), the type-checker will not allow another type than double.

There are two types of soundness, where we have weak and strong soundness. On weak soundness we can do some tasks like type casts, with strong soundness we cannot. On Java we can type cast returning values to another type, and the compiler will allow that. On other languages, like Haskell, type casting is implemented using its type system, but we cannot type cast variables using expression built in the compiler, because the type system uses strong soundness and does not have type casting operators, and each compile time error has a type, on Java each non related type — which is being type casted — does not have its own type. On strong soundness each variable and expression is strictly bound to a type within an error with the wrong type.

Java is not type-safe because it allows a very powerful way of organizing the type-space at run-time (through user-extensible class loaders ). This power can be utilized to write a program that exposes some flawed design decisions in the Java Virtual Machine. Specifically, one can produce a class A and an associated ersatz class A’ which can “spoof” A: its name N is the same as A, but it defines members (fields and methods) arbitrarily differently from A. A “bridge ” class B can be defined which delivers to a class D (for which the name N is associated with A’) an instance of A. D can then operate on this instance as if it is an instance of A’, thus violating type-safety. [Vijay Saraswat, “Java is not type-safe”].

We can have type safety implemented on the compiler using a type checker in compile-time, like Java does. Seems that it is not entirely safe on run-time, due to the research quote above. But seems that languages like Haskell are type-safe languages in compile-time too. But can you ask yourself what is the scope of type-checkers and its type-safety?. For me type-safety aims to be the correctness prover for each program. Like Agda and Haskell does, “a proof is a program; the formula it proves is a type for the program”. So, safety is not strictly bound to security, and it just defines the correctness of the program, not its environment.

I wanted to see how great Haskell’s static typing is, so I ran darcs under an LD_PRELOAD library that had a hacked open() call. [Zed Shaw, Twitter Quote].

Type safety just brings correctness, not security. Correctness provides security — in example a string cannot be used as integer — but not provides a full security layer, and we can define that type safety brings security in terms of correctness, and not its environment. Once a program is compiled, we cannot control its environment. With some very reduced set of examples, like Plesk. For example on not so early stage as web developer, I had a problem with Apache in the compiled version inside Plesk, giving me a core dump due to some Unicode characters on a configuration file, so I have tried to use the well known Linux strace(1), I have noticed that Plesk binaries were not allowed to run with the processor debug flags enabled. That is a way to control the environment, but I certainly cannot imagine a run-time enabled type-checker. What should be verified? Each variable?, Each function parameter?.

Although verification of type safety is not mandatory to run managed code, type safety plays a crucial role in assembly isolation and security enforcement. When code is type safe, the common language runtime can completely isolate assemblies from each other. This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability. [Microsoft .NET Framework 4.5, “Type Safety and Security”].

I cannot expect that type-safety will bring me security. It only brings correctness in some manner, and the provided security only defined in terms of program correctness, rather than environmental. That is the common approach and I agree with it, we cannot expect that each program in our operating system keeps checking its environment and searching for flaws, that is a little bit weird and paranoid.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | One comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/type-safety-is-not-security/feed/ 1
mutability on states machines http://coder.cl/2012/09/mutability-on-states-machines/ http://coder.cl/2012/09/mutability-on-states-machines/#comments Sun, 30 Sep 2012 15:52:32 +0000 Daniel Molina Wegener http://coder.cl/?p=2814 The basic definition of a state machine is a set of states S, with a subset of initial states I, another subset of final states F, and a set of transitions between states T, and every state s’Ss”S where ISFS, and each element on T { s’, s”, h }, with s’ as the current state, s” as the next state and h as the state action. On my current automation project where I am using ProView, I have each device controlled by state machines, and each user or automatic control request is queued on a priority queue, where the highest priority is executed replacing any previous execution state, because we have only one communication channel. So the basic state machine definition is not enough to hold every environmental variable that we are using to control each device.

The state machine model includes on each transition a basic model defined as { s’, s”, g, f, h }, with s’ as the current state, s” the next state, g a boolean function evaluating the environment, f as guard boolean function preventing errors and h as action function. Where g is similar to f, but it covers the feasibility of the state change, because it evaluates if the device state (offline, online + automatic, online + manual), and f evaluates if the request is feasible according to the current composite device state (pump + valve + manometer), where each operation request was written as follows.


struct fcu_request_s {
    bool     channel;
    bool     done;
    bool     nobreak;
    int      errors;
    int      cycle;
    fcu_io  *device;
    pwr_tUInt16          operation;
    fcm_task_prio_t      priority;
    struct timespec      start_t;
    struct timespec      current_t;
    struct timespec      end_t;
    fcu_state_machine_t  *machine;
};

Where every boolean member is evaluated using the boolean function g, integer members are evaluated using the boolean function f, and if both function are not blocking the action, the action h is executed.

HMI

HMI (the image was modified to be shown).

Finally the state machine is mutable, because there are dynamic states which are triggered by boolean functions, and every transition is not strict, they are only a behaviour template rather than strict states to be used on each transition. From the processing node, each HMI signal is checked against the boolean functions, and each state transition is strictly evaluated before executing the action. This is more representative than single state transitions from the original state machine model, allowing better control. Where we are using dynamic programming to hold state transition tables and previously evaluated boolean functions which are common to the composite device state.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/mutability-on-states-machines/feed/ 0
choose C or C++ http://coder.cl/2012/09/choose-c-or-c/ http://coder.cl/2012/09/choose-c-or-c/#comments Tue, 18 Sep 2012 14:07:25 +0000 Daniel Molina Wegener http://coder.cl/?p=2793 How to choose between C and C++?. The answer is pretty clear. C allows powerful data type abstractions using three star and two star pointers, C++ only allows one star pointers. Also void pointers on C are more powerful once you try to pass abstract parameters to functions and procedures. The abstractions on C++ are built on top of virtual classes and templates, not its data types as C does. So, if you need to create complex data types, for example to handle hardware buffers, you should use C rather than C++, but if you want to create abstractions to manage real life objects, an object oriented interface like C++ does have is pretty good, enough to support almost any object oriented abstraction that you want to implement.

Another interesting fact is how you can integrate both C and C++ libraries and programs without too much effort. For example for the lower level of abstractions in our ProView systems, we are using C interfaces to reach the hardware layer, but that layer has an abstraction layer that allow us to see each device as a C++ class, so we can get device status, device errors, device data among other interesting operations as one single object instance, rather than using device descriptors or data structure pointers. So, we can operate each device instance, even if that device is a composite device that drives multiple sub-devices, as one single object instance with its own data and methods. That makes our life much easier than handling devices as data structures and plain C routines.

For example we have named a composite device PCU or Pump Control Unit, which consist on a pump control, an actuator control, a valve control and two manometers. It is very nice to see that PCU as one device, using plain methods over the PCU rather than using multiple plain C calls over their C data structures and pointers using each sub-device to control the unit. Even if they are using different protocols, we can operate each device transparently, thanks to every abstraction layer that we have placed on the system.

Choosing between C and C++ is not a religious choice. Mainly because I am a language agnostic programmer, and I work with limited set of programming languages where I can find better programmers, like C, C++, Python, Haskell and Lisp. Also I can choose Haskell if I want, because it supports low level function calling thanks to the Foreign Function Interface, where I can create low level interfaces for hardware devices and operate them in higher level using Haskell. For your surprise, I can create complex control algorithms in Haskell, migrate those algorithms to Agda, and create the proper proofs on those controlling algorithms. The result is a formally verified control algorithm. I can do the same with Coq and Haskell program extraction. A simple example for FFI code, is the GeoIP library interface that I have made on my ApacheLogRev project, and you can see the source code here.

So, is much better to be a language agnostic programmer than be linked to programming languages as religions…


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/choose-c-or-c/feed/ 0
dynamic control on state machines http://coder.cl/2012/09/dynamic-control-on-state-machines/ http://coder.cl/2012/09/dynamic-control-on-state-machines/#comments Fri, 14 Sep 2012 12:35:00 +0000 Daniel Molina Wegener http://coder.cl/?p=2786 We are doing pretty good advances on the ICS/DCS that we are doing. The current code base is using the STL std::priority_queue as operation request queue, but we are changing the task request priority each time that the communication channel is being used by any transition that requests the Profibus channel. We cannot saturate the communication channel with requests, because it runs on a very low bandwidth connection, so each request should be correctly measured, where all operations on the machinery is being directed by states machines with dynamic priorities of execution, and the STL priority queue is doing a good job. But was a little bit complex to think in terms of source code with the model presented as state diagrams and flow control diagrams on a whiteboard, and took me about one week to finish the final skeleton of the primary source code.

Now just remains operation details, such as state machine definitions for each operation that is required for the machinery operations that system will handle. The system has two main kinds of operations, automatic operations and manual operations, where manual operations have a higher priority than automatic ones, also automatic operations can be interrupted by manual operations, so the state machine that is running an automatic operation can be interrupted by any manual operation. Each state transition is monitored checking the system state, looking if a requested a manual operation should replace the current automatic operation, or the automatic operation should be interrupted by another automatic operation with a higher priority.

The algorithm — now that is implemented and not placed as diagram on the whiteboard — looks much simpler, and the basic algorithm looks as follows.


req = dev_get_request(MAIN_CONFIG, NUM_DEVICES);
if (req != NULL) {
    queue_task(req);
}

while (!channel && (req = check_queue())) {
    if (req->done) {
        break;
    }

    req->device->run(req);
    if (!req->channel) {
        continue;
    }

    sts = io_write(io_ctx);
    if (EVEN(sts)) {
        errh_Fatal("ra_fcm: io_write error, %m", sts);
        fcm_io_alarm(req->device, FCM_IO_WRITE);
    }

    sts = io_read(io_ctx);
    if (EVEN(sts)) {
        errh_Fatal("ra_fcm: io_read error, %m", sts);
        fcm_io_alarm(req->device, FCM_IO_READ);
    }

    if (req->nobreak) {
        channel = false;
    } else {
        channel = true;
    }
}

The dev_get_request method checks if there is a pending request, automatic or manual, if there is a pending request, it is being queued, and immediately the process starts processing the queued items, where they can be finished in one step or not, and the device runs the state machine referenced by the request, if the state machine transition uses the I/O channel, the ProView methods io_write and io_read are called, then, if the transition requests a no-break operation to make a continuous usage of the communication channel, it keeps running the state machine. Otherwise the state machine breaks its operation and seeks another operation request in the queue. The check_queue method seeks the proper prioritized request on the queue, where its priorities are changing inside the state machine on the run method.

But the state machine runner — placed on the device as run method — as an abstraction of the managed device by the priority queue, where there are several devices to manage, schedules their tasks using a simple algorithm. The real complexity is placed on the operation of each device, and the algorithm itself is an abstraction of the generalized state machine that we are running.


if (dev_state == DEV_ST_INACTIVE) {
    dev_state = DEV_ST_ONLINE;
}

request->nobreak = false;
machine->channel = false;
request->channel = false;

for (c = 0; c < machine->num_states; c++) {
    tr = &(machine->states);

    if (tr->curr_st != dev_state) {
        continue;
    }

    if (!tr->guard(tr, machine, request, this)) {
        break;
    }

    if (!operate(tr, machine, request)) {
        break;
    }

    errh_Info(st_msg_fmt, fcu_state, tr->next_st, tr->curr_st);
    dev_state = tr->next_st;

    if (tr->next_st == machine->final_state) {
        request->done = true;
        break;
    }

    if (tr->channel) {
        chn = true;
        request->nobreak = tr->nobreak;
        machine->channel = true;
        request->channel = true;
        break;
    }

}

return chn;

The guard checks environmental variables, and if there are good environmental conditions to operate, then it starts operating the device according to the current transition, that holds the action as enum type, with a simple switch statement to check the action that should be taken on the state transition. On a successful operation and the proper prioritization, the queue is reordered outside the state machine runner, allowing queued operations to trigger alarms if they are not finished, among other similar error checking and environment checking routines. So, the system keeps working, alerting the user through the HMI if there is any condition that never meets the required operation. ProView has several ways to alert users about the system conditions, and we are using almost everything that we can. I think that this system is very well structured and now running dynamic priorities is even more stable than using plain task requests, mainly due to environmental variables. This scheduler looks preemptive, but it is not.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/dynamic-control-on-state-machines/feed/ 0
scheduler using priority queues http://coder.cl/2012/09/scheduler-using-priority-queues/ http://coder.cl/2012/09/scheduler-using-priority-queues/#comments Sun, 09 Sep 2012 13:55:58 +0000 Daniel Molina Wegener http://coder.cl/?p=2768 As you know I am working on an Industrial Control System — ICS/DCS to be more specific — and this system requires a task schedule to activate some pumps with a very strict calendar, monitoring the amount of liquid that has been passed through the valve, and it should allow manual operations, interrupting the automatic operation of that node on the plant. This seems to be difficult to implement, as I wrote in past posts, we are using a priority queue that contains task requests, where every priority is entirely dynamic, and dependent on the state of the current state machine that is being executed according to the operation request.

During the state machine execution, each state transition has a guard ensuring that the step that will take place on the transition is guaranteed to be executed depending on the environment, if not the step is reserved to the next PLC scan cycle — do you remember that ProView operates C and C++ applications like PLC programs?. The same guard ensure that the operation on the pump will take the required minutes to deactivate the pump, meeting the task calendar. Once the pump is active, its task priority — which is hold on the request data structure — changes its priority, and using the top() and pop() methods of the STL std::priority_queue, is extracted from the queue, the priority is changed, and it is pushed again on the queue using the push() method.

All requests that are using the communication channel have the higher priority, because we have only one communication channel, so we must ensure some concurrency on the channel usage, and we call the io_read() and io_write() ProView functions only once it is required, ensuring that the communication channel is used by one device at time. I think that this is the biggest problem of the system, because the communication channel is very small, and shared between several devices, and it must be used concurrently. But locks are not an option. If the channel blocks due to its usage, the system should continue its work and must keep its system review — reviewing channel status and signal status, and reviewing the error status for several devices.

Since several requests are not using the communication channel, the queue never gets saturated, and every transition is executed. It only blocks on communication channel usage, but it calls the io_read() and io_write() ProView functions rather than using some kind of lock, like semaphore or similar one. Also, errors are not allowed, the code should not have any programming error, and it is being traced by strace(1) and valgrind(1). Also, we are thinking to check the model using spin(1), I have started some Promela code related to the processing model, at least it looks well for now. It will probably get more complexity on the future, but the model looks well, and the code seems to be really good.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/scheduler-using-priority-queues/feed/ 0
generalized state machines http://coder.cl/2012/08/generalized-state-machines/ http://coder.cl/2012/08/generalized-state-machines/#comments Fri, 03 Aug 2012 11:59:56 +0000 Daniel Molina Wegener http://coder.cl/?p=2644 Defining state machines is not so hard as it appears. Initially you can build constructs that can help on building automata processing much friendly than using plain code. Starting from the idea that you can place your state machine inside data structures allowing friendly editing without modifying the processing code. Any stateful processing can be migrated to state machines. As any automata can be represented in a state diagram and then it can be migrated to plain data structures. Even if you are using a purely functional programming language, you can place a stateful processing data structure to be processed as automata.

On a recent project, the project manager has requested to me to code a state machine. Its initial design is not generalized. Along two design sessions and some sample code and constructs I think that I have finally made an abstract state machine, with various reductions, based on the model designed by the project manager on the design sessions, structured mostly as automaton, with very simple state transitions, but I have added error and wait conditions, allowing more friendly error processing and wait events. Mainly because as ProView application it has several similarities to PLC programs, where each cycle can operate one time due to the protocol restrictions, but also it allows multiple operations in one cycle because it can send larger packages with multiple requests.

Generalized State Machine

Generalized State Machine

On each cycle, once the I/O layer is initialized, the device error state is checked, on failure it reports errors using ProView alarms, waits the next cycle and then operates again checking the device state. If no error is detected, it operates immediately once it can do it according to its cycle. And the state machine above is a generalized or abstract state machine, considering CST and OST as checking and operating states, where it is has a normalized transition between both states with the proper error handling states.


typedef struct fcu_sm_trans_s fcu_sm_trans_t;

struct fcu_sm_trans_s {
    fcu_op_state cst;
    fcu_op_state nst;
    fcu_op_state fst;
    bool alarm;
    bool wait;
};

/* pump and valve transtion table */
fcu_sm_trans_t AUTO_FCU_TRANSITION[] = {
    { FCU_ST_OFFLINE             , FCU_ST_DISCONNECTED      , FCU_ST_OFFLINE      , false, wait  }
    , { FCU_ST_DISCONNECTED      , FCU_ST_COPY_READ_POS_P   , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_READ_POS_P   , FCU_ST_COPY_WRITE_POS_P  , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_WRITE_POS_P  , FCU_ST_COPY_READ_POS_V   , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_READ_POS_V   , FCU_ST_COPY_WRITE_POS_V  , FCU_ST_ERROR        , true , false }
    , { FCU_ST_COPY_WRITE_POS_V  , FCU_ST_READ_POS_P        , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_POS_V        , FCU_ST_READ_POS_V        , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_POS_V        , FCU_ST_READ_BURN         , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_BURN         , FCU_ST_READ_PRES         , FCU_ST_ERROR        , true , false }
    , { FCU_ST_READ_PRES         , FCU_ST_WRITE_POS_P       , FCU_ST_ERROR        , true , false }
    , { FCU_ST_WRITE_POS_P       , FCU_ST_WRITE_POS_V       , FCU_ST_ERROR        , true , false }
    , { FCU_ST_WRITE_POS_V       , FCU_ST_READ_POS_P        , FCU_ST_ERROR        , true , true  }
    , { FCU_ST_ERROR             , FCU_ST_OFFLINE           , FCU_ST_ERROR        , true , true  }
};

And here you have sample transition table for one the controlled devices — which is not the final transition table, because we still do not have the final model implemented, but we have the proper abstraction to implement it — with error handling and wait conditions. The model is very similar to functional guards, where there are some conditions checked, including the error condition, and then the state is processed passing to the next state in the next cycle. Seems that the original model for this kind of processing is present in this paper, and seems that it is fully meeting an IPO model.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/08/generalized-state-machines/feed/ 0
dynamics and actions in proview http://coder.cl/2012/07/dynamics-and-actions-in-proview/ http://coder.cl/2012/07/dynamics-and-actions-in-proview/#comments Thu, 26 Jul 2012 12:17:45 +0000 Daniel Molina Wegener http://coder.cl/?p=2628 Graphical objects in ProView are providing two types animations and behavior attributes, where both can be highly customized. Dynamics are those animations related on how the object operates with the environment — mouse and keyboard — and the logical plant nodes. At the other side, actions are those XTT commands triggered with the user interaction. So, for example we have the Electric > ControlSwitch sub-graph, which has the action DigShift, but we can change the DigShift action to ToggleDig, allowing a digital input switching between True and False, and preserve the rotate animation which is inherited from its definition.

Is really nice to have such type of graphical objects, because we can mix different types of animations, user interface behaviour and XTT commands, allowing almost any type of control to be created, including custom sub-graph objects, which can be linked with custom C or C++ programs. You just need to remember the $object and $local object references once your are instantiating the sub-graph object, mainly once they are pointing to logical plant nodes. Thanks to this flexibility, you can manage for example a simple PushButton, and make it work as SwitchButton, and make it work as ControlSwitch to toggle a digital input value.

Rotate Animation Configuration

Rotate Animation Configuration

For example we can use a PumpAnim2 sub-graph object and change its dynamics to be a rotating animation, rather than using its default, we just need to ensure that the dynamic is linked to the proper object — for example an analog signal on rotate animations — and configure each dynamic attribute correctly, as it was done using the rotate facto on the case above.

Toggle Button

Toggle Button

You have many options to use in your HMI once you are building your ICS applications using ProView. You can read the Design Guide, the Ge Reference Manual, the SubGraph Reference Manual and the Operator Guide. The Operator Guide mainly contains the list of XTT commands, if you need to use any XTT script based commands to work the logical plant. This is really nice, because you can trigger — with a proper design — custom actions inside your rt_appl based application if you need make something complex, like distributing some task in a period, like moving a pump for 20 minutes and monitoring how filled is a tank, blocking its pumping action if it is required. Tasks like that are complex to implement using PLC programming, so a good C or C++ application can do that.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/07/dynamics-and-actions-in-proview/feed/ 0