News:

Let's find out together what makes a PIC Tick!

Main Menu

Methods of developing code structure

Started by TimB, Sep 30, 2022, 07:23 PM

Previous topic - Next topic

TimB


Hi all

When I write code I have a very woolly way of managing the writing

First is initialising the system OSC set up etc. Generally I set up the interrupt routine to get timers running. 1hz 10hz 100hz etc

Then Start: on the main routine working of the ticks. All this is done off what I think in my head. I try and comment it as I work or make the var names so obvious you can figure out.

BUT it is really a mess, If you come back to the code there is no way to see exactly what is the flow its read it all and try and figure out what the hell I was doing, even a year later.

So I'm on a new project. I hope it will be BIG so consider the code needs to be portable. I should be able to give the spec or what ever to someone else and they can write it in any language just from the brief

My brief is pretty short but considering I am going to the effort of writing it and working out algos I want to, even if its just for myself have a documentation system where I write it out and that even I can follow it and produce the code.

This where I'm at and looking for advice what do you do? Is there a system of software package to use to document the flow. I tried the flow charts of old with decision triangles etc. I spent more time doing the drawings than actually developing the code so gave up. I think now its time to revisit it, What is there and what do you recommend I use?

Thanks
Tim

normnet

I also have occasionally found a large program hard to determine the flow of the code due mainly to the PC only displaying one page at a time.  I print out the section and hand draw the brackets of matching if-endifs making a note of certain sections on the bracket lines as well.  This gives me an overall picture of the flow!  I also add a unique string of identifying comment such as '********* at the end of important procedure calls to make them stand out.  Good indentation of the nested code is helpful with this technique.

John Drew

When I start a project there's a fair bit of thinking goes on about what I want to achieve. The goals if you like. I then create my Main: with the list of actions I think may be necessary written as procedure calls. In the old days they were Gosubs.

It might look like this-
Main:
   BringInSerial()
   AdjustData()
   DisplayData()
   Goto Main

I then create the procedures including other procedures that serve them. This is also the time I work on the list of global variables, symbols, setting up of ports, and by then I have a growing understanding of the needed micro and it's settings, memory requirements, pins etc.

The key is to use the Main as the determiner of flow.

I don't try  a compile until I'm happy with structure and the key elements of the program.

Because many of my early programming projects were in Pascal I learned the importance of program flow and structure.

John

joesaliba

I think that one will perfect the method of coding over time. Everyone has its own rules.

Don't laugh, the other day I opened a code that I made 7 years ago.

Trying to go through it was a pain, and I asked myself how it worked, as what I saw did not make sense.

Now a days it is something as John described. However, I am still in my early days playing with procedure and do not know if they are best placed at the beginning or at last in the code, although, I found out that an include file with procedures does make the code more readable.

Joe

charliecoutas

My programs usually use timers, interrupts and serial in/out. I always copy an existing program which contains all these elements and I know works, then delete all the stuff I don't need. This way I have all the interrupt flags and enables, baud rate code etc as a basic framework.

Looking at code I wrote several years ago shows the value of good comments. But looking at my old code shows that I was cleverer then than now, or perhaps less aware of what could go wrong.

Charlie

top204

#5
Totally agree Charlie. Code I wrote years ago is much cleverer than now and was more ambitious. :-)

I have always found flow charts and those bubbles with all the winding lines going to other bubbles (I can't remember its name), extremely confusing! They work OK with small programs, but larger programs just get so muddled up in them it is impossible to follow all the lines, and not all programs work with them. For example, where does an interrupt go in the flow or bubbles with curved lines?

The same with this, very stupid, method now of having graphical blocks and connecting one block to another, a bit like a lego set on the screen. :-) Again, with simple programs thay can look good, but they are useless for "real" programs, and teach very little about actual programming techniques IMO.

For about 18, or so, years now, I always use indentations and comments and procedure or subroutine header lines and texts, so they are easily identified and easily seen what they do. I also give variables and constants and alias' and labels and procedures and macros etc, meaningful names and give variables and constants a preceding character so I can see what they are in the main program's flow. i.e. cConstantValue, bMyVarForThis, wMyVarForThat. I also place blocks of code that do a specific task in seperate include files, so I know, for example, all the EEPROM handling routines are in the "EEPROM.inc" file etc...

As Joe stated, it is an individual method because writing code is like writing a story or a book and it is personalised. You can learn the fundamentals of programming from a book or another person, but the flow of a program comes from exerience and time, and enjoyment of writing in a specific language. I once tried to program in "Forth", and what a nonesense language that was. :-) It just never made sense when looked at. LOL But it was good for interpreted languages because it was written in the method an interpreter or compiler has to parse a program. i.e. Reverse Polish, so it ran faster on the older 8-bit machines.



JonW

I don't use the squiggles and bubble flow diagrams either but have a word or PPT file with written descriptions of he general flow and then details of libraries used and variables used in the libraries.

If I am working on a new device, once the code is setup with the required peripherals and running then I will make a template file so I can start new projects on that device quickly and can be tweaked in minutes.  Lately I have started to produce libraries in inc files passing and returning as much data as possible using Procs and local variables.  I comment these heavily, including headers on each proc etc.  Using this structure its much easier to debug and familiarise  yourself with the code flow in the main program.  It also saves a boot load of time reusing the inc files and if the processor changes the files can be copied and renewed with any different register definitions. Another plus point is that these can be used by multiple coders and altered if needed.  We keep a running library with history of engineering change notes (ISO500x).  I am just working on flash write procs(that will be inside the inc files) for the 26/27k42 so I can store large calibration files to flash and these were easily created from the Q4x HEF procs from an older project, very easy to port and I have full control of the routine for debug and customising.  The main code flow is then simplified with proc calls and is way easier to read the flow.  With the inclusion of the procedures, heap variables etc I find that only the most basic compiler and math routines are required.  Coupled with a good IDE (I use Positron Studio) its much easier to keep track of large code structures




 

shantanu@india

I have never really changed my PIC program wrting style in the last 17 years. I just keep copying and pasting like Charlie and rarely use any procedures(Is Les frowning?)
The strength of the compiler lies in it's back-compatibility.... apart from the hardware interrpt structure very little has changed which can force you to rewrite your code.
I'm more into projects and application engineering and have very little time to experiment on new coding techniques.
Regards
Shantanu

Stephen Moss

Quote from: top204 on Oct 01, 2022, 06:28 PMI have always found flow charts and those bubbles with all the winding lines going to other bubbles (I can't remember its name), extremely confusing!
I also find state machines confusing, occasionally I will create a flow diagram but only at a very basic block level, not for each sub level, but generally just use a piece of paper with headings (groups of associated functions) and sub headings (functions within each group). Not sure if that saves time or not as sometimes I reach a point where I decide to change how I do something or where I place code, such as moving code to a separate file/procedure because it has reached a size where it has become too large and unwieldy to keep in a single file.
In Visual Basic that is easy as you can create separate modules to group code in such as one for file read/write, one for menu functions, thereby removing that from the main code making that simpler to read so if I see a command "Call File_IO.Read_User_Data(UserName)" with the comment Load User Data in the User_Data_Array I can see that the procedure Read_User_Data in module File_IO is loading data from the filename in variable UserName into an array.

It is not quite as straight forward as that when using Positron, although ther eare two waysof achieving something similar to that...
  • As John Drew indicated, try to divided your code in to Procedure/Subroutine blocks then call the blocks when needed, a suitable comment indicating what the called Procedure/Sub does should help you to understand the program flow, that helps minimise the amount of code in the Main loop while enabling an understanding of the program flow.
  • Use the Project feature of the Positron Studio IDE does enable you to do something similar to what I do in VB, in that you could place all you coms procedures/sub routines in one include file (VB module), all your Interrupt handlers in another, global constants/variables in another, that way you can have all the relevant files open and switch between them if necessary to see the actual code without jumping back and forth through a single unified mass of code and thus keeping both your you main code file and main code loop as small and easy to follow as possible.
1


I have only started doing this part recently (taking a Page from Les' book), but at the start of every procedure/sub I place a header to clearly identify the beginning of a block of related code, then for each sub/procedure I include Notes and where I think it necessary an MO, such as the following...
    '#####################################
    '#####  Add items to Inventory  ##### - Complete 09/09/2022
    '#####################################
    'NOTES:
    'Calling Proceedure: LoanBook(Btn_Multi_Func_Click)
    'Inputs: TxtBox_JobNumber text
    'Outputs: Add_Lab_No
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    '~~~ METHOD:
    '~~~ Check the entered Lab Number for the correct format
    '~~~ If incorrect then notify user of error
    '~~~ If correct format then restore user information in case it was changed by due to previous incorrect entry
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~


As you can see the notes tell me which procedure(s) in which module(s) (Positron include file) called that procedure, the parameters passed into and out of the procedure and when I am happy that each section is operating correctly I mark it as complete along with the date on which it was initially completed, comments regarding any changes made after that are added to the notes section and also dated so I know which sections are finished and which still need work.

Generally with PIC code I tend to go...
Device
Xtal
Fuse Config
Contants/Variables/Aliases
Peripheral setup
Subroutines/Procedures, I used to put them after the main loop, but have a vague recollection of I reading that returns are fast going forward so switched.
ISR
Main Code