Can I save register values inside of ISR code? - operating-system

I am new to OS interrupts and wondering why do we need to save all the register values before going into ISR? Can we write the code to save register values inside of ISR code so that the register values can just get pushed to the stack by ISR's own code?

Answer is clear,it will be to complex to add a part of code to save context before every ISR and restore it.It's easy to reuse every code by macro.Surely,when you write a ISR,you'd rather use C than ASM.But when you using a C code,every action expected depends on your complier, it means that C code will do more than you write.

Related

Can we edit callback function HAL_UART_TxCpltCallback for our convenience?

I am a newbie to both FreeRTOS and STM32. I want to know how exactly callback function HAL_UART_TxCpltCallback for HAL_UART_Transmit_IT works ?
Can we edit that that callback function for our convenience ?
Thanks in Advance
You call HAL_UART_Transmit_IT to transmit your data in the "interrupt" (non-blocking) mode. This call returns immediately, likely well before your data gets fully trasmitted.
The sequence of events is as follows:
HAL_UART_Transmit_IT stores a pointer and length of the data buffer you provide. It doesn't perform a copy, so your buffer you passed needs to remain valid until callback gets called. For example it cannot be a buffer you'll perform delete [] / free on before callbacks happen or a buffer that's local in a function you're going to return from before a callback call.
It then enables TXE interrupt for this UART, which happens every time the DR (or TDR, depending on STM in use) is empty and can have new data written
At this point interrupt happens immediately. In the IRQ handler (HAL_UART_IRQHandler) a new byte is put in the DR (TDR) register which then gets transmitted - this happens in UART_Transmit_IT.
Once this byte gets transmitted, TXE interrupt gets triggered again and this process repeats until reaching the end of the buffer you've provided.
If any error happens, HAL_UART_ErrorCallback will get called, from IRQ handler
If no errors happened and end of buffer has been reached, HAL_UART_TxCpltCallback is called (from HAL_UART_IRQHandler -> UART_EndTransmit_IT).
On to your second question whether you can edit this callback "for convenience" - I'd say you can do whatever you want, but you'll have to live with the consequences of modifying code what's essentially a library:
Upgrading HAL to newer versions is going to be a nightmare. You'll have to manually re-apply all your changes you've done to that code and test them again. To some extent this can be automated with some form of version control (git / svn) or even patch files, but if the code you've modified gets changed by ST, those patches will likely not apply anymore and you'll have to do it all by hand again. This may require re-discovering how the implementation changed and doing all your work from scratch.
Nobody is going to be able to help you as your library code no longer matches code that everyone else has. If you introduced new bugs by modifying library code, no one will be able to reproduce them. Even if you provided your modifications, I honestly doubt many here will bother to apply your changes and test them in practice.
If I was to express my personal opinion it'd be this: if you think there's bugs in the HAL code - fix them locally and report them to ST. Once they're fixed in future update, fully overwrite your HAL modifications with updated official release. If you think HAL code lacks functionality or flexibility for your needs, you have two options here:
Suggest your changes to ST. You have to keep in mind that HAL aims to serve "general purpose" needs.
Just don't use HAL for this specific peripheral. This "mixed" approach is exactly what I do personally. In some cases functionality provided by HAL for given peripheral is "good enough" to serve my needs (in my case one example is SPI where I fully rely on HAL) while in some other cases - such as UART - I use HAL only for initialization, while handling transmission myself. Even when you decide not to use HAL functions, it can still provide some value - you can for example copy their IRQ handler to your code and call your functions instead. That way you at least skip some parts in development.

Libnodave on value changed

I am using libnodave 0.8.4.4 library to connect to a S7 PLC and what I would like to know if how can I detect if a bit (e.g. DB100.DBX8.0) in PLC DB changes its value. What I did is to read this bit within a while loop but I would like to create an event on value changed on this bit and launch a task when it happens.
There is no default event available with libnodave or any other libraries like S7.net.
Either you need to use OPCor write your own function which will read the set of bits set on time and notify to the main program.

Which method is generally used to communicate between programs in Structured Text

I am maintaining a project for a PLC written in ST. To implement a new feature I need to let cyclic program A know when an event happened in cyclic program B.
How is this generally done in ST? Do I simply use global variables or is there a different method? If I use global variables, how are these then protected from concurrent modification?
I use the X20 PLCs from B&R Automation.
Asynchronous communication is tricky.
So imagine a global A_DONE initialized to false, with B inspecting it occasionally. A runs, and sets A_DONE. B can react to this event... but what does it do if it needs to handle another event?
If you believe that the event that tells A to signal A_DONE occurs only long after B sees A_DONE, B can simply reset A_DONE to false (assuming this always happens before the next A_DONE event) and the cycle can repeat.
If A_DONE can occur "again" while B is handling the results of seeing A_DONE, B cannot just reset A_DONE: you might get a timing splinter in which B reads A_DONE, A sets A_DONE again and B then clears A_DONE; now you've lost an event. If that event is controlling your reactor emergency rods, this could be pretty bad because poof, B missed it.
In this case you will likely need a handshake from A to B and back. We add a signal from B back to A, call it A_DONE_SEEN, to let B tell A that it has processed the event. Then A sets A_DONE, waits for A_DONE_SEEN; A clears A_DONE, waits for A_DONE_SEEN to go false, and continues its business. If A_DONE needs to be set while A_DONE is already set, or A_DONE_SEEN is set, we know we missed an event and some disaster recovery procedure can be run. B watches for A_DONE, handles the A_DONE action, sets A_DONE_SEEN, watches for A_DONE going false, and sets A_DONE_SEEN_FALSE.
I don't know about your specific PLCs, but in many systems there are atomic operations that increment counts, etc. You could use this instead of the handshake.
Yes, you need to declare a variable that has a shared scope to both cyclic programs.
You can do this by using the existing global.var file or you can create a new variable file, and limit what programs can read or write to it by placing it within a "package" (folder in your project).
To create a new var declaration file...
-right click within the logical view
-add object
-select "file" category, and choose new file
-name, and change to "save as *.var" in the drop down
By default, the new variable declaration visibility will be limited to the package it is contained within. To verify this, right click the file and go to properties. Select the details tab.
There is no way to protect from concurrent modification, but you can use the cross reference tool to see where a selected variable is being written and read within your project. First build a cross reference, and then use the tab at the bottom.
Good luck!

GTK3 - Monitoring all signals emitted from a widget

Is there any way to monitor all signals emitted from a widget with GTK3? I know that the event signal is emitted before an event, but I'm not sure of the distinction between "event" and "signal" in GTK terminology - as this does not seem to capture all signals.
I know GDK has a function gdk_set_show_events but this mostly shows events which are sent to the window from the operating system. Is there a GTK3 equivalent?
There is not built in function AFAIK, but I'm sure you can hack something together yourself:
Use g_signal_lookup to get all signal ids for a gtype. Then use g_signal_add_emission_hook on each signal of your instance to register a hook to be called whenever that particular signal is emitted. Inside the hook function, you're provided with the signal id via *ihint, from which g_signal_query should provide you with all the information you need to print debug messages. (I didn't test it, but it should work)
Note that this will unfortunately not work for signals defined with G_SIGNAL_NO_HOOKS.
Use g_signal_lookup to get all signal ids
It's a little more complicated than described. In order to use g_signal_lookup, you first need a signal-name. If you want to monitor every signal independent of the object-type, you first need to list all signals of the specific instance-type. This can be arranged by g_signal_list_ids for exactly one single GType. To get really ALL signals emitted on the instance, you need to iterate over all parent-types of this instance. You can do this by using g_type_parent.
I have build some utility-functions by myself, that provide this functionality for the same debugging purpose the question was intended. You can connect an Emission-Hook for all signals of a GObject-instance with gemu_glib_util_connect_to_all_signals or connect an emission-Hook to a GtkWidget-instance and all its children with gemu_gtk_util_signal_connect_to_widget_children.

Simulink: Synchronizing and timing

in order to simulate some processes I have a problem with getting a predefined working order of my self modeled blocks.
How can I be sure, that for example Block A must be finished before Block B and C start working?
The problem is, that some Blocks shall work after some others and some shall not. I must admit I have not much experience with Simulink in order of doing time-depending things (althought basic knowledge of simulink is available).
For instance this scenario shall be realised:
A -> B, C -> D, E, F
The main thing is, that all blocks A-F have no logic correlation to each other, they all do several things. My aim is to make B and C start working, after A has finished. And D/E/F after B AND C have finished.
In this case, the word "parallel" was the wrong word, this does not have to be calculated really parallely. Just making sure, that this complies with a predifined steady order.
Edit:
My new idea is to use the matlab workspace als buffer, so my block A can push its results to workspace (by the "to workspace" block). But now I have to make sure, that block B and C may read the results (with "From workspace") of A AFTER A pushed its information to workspace...how to do this?
Edit2:
Here's a screenshot which should make some thinks clearer:
As the documentation of "Sorted order" refers, the set up seems to be ok (including the subsystems timing). But unfortunately problem still exists. The variable "simin" is loaded from workspace, before it was written :( As you see, the display shows "1", which it shouldn't do. In the very first run of the simulation I get an exception, that the variable "simin" does not exist.
It would be nice, if you can help me with my issue.
Greets, poeschlorn
So in your example, if you have Block A connected with the same wire to both B and C, when Block A is finished, Block B and C will work in parallel.
EDIT:
I am using the same blocks as you are, but it works for me. I think you are over complicating things. The way you are setting block priorities is no different than how Simulink runs the blocks without them. Below you can see my setup and the output on both binary displays.
The error you see on the first run is due to Simulink not creating the variable until the first time step is being executed. When Simulink builds the simulation it sees that the variable used as input from the workspace is not created.
If the connection between the block are not enough to set the order, you can use block priorities.
A tip to test the execution order is to add an "embedded Matlab block" with a disp command displaying the name of the block.
It's not really clear what you're asking. When you say that Block A must be finished, do you mean the Output function? The way simulation works in Simulink is that the blocks are run serially, so Block B and C would never run until Block A finished it's Output function.
I don't know of any obvious way of running blocks B and C in parallel currently in Simulink.