Sunday, October 4, 2015

MOS Development Start

This weekend I got a little bored, and decided to start up operating system development again.  There is a video of MOS running at the end of the post;
I know, it's been a while.  Firmware development is pretty similar anyway (they both use cross-compilers and have almost nothing in the way of library code.  Originally I bought the HP 530S desktop machine in the video for OS development testing.  I figured I would have a go at making MOS boot on the test machine.  Well, here is an overview.

I have the following directory structure setup:


The functionality provided in my build setup so far:
  • documentation
  • object dumps
  • size of kernel
  • building the kernel
  • rebuilding the kernel
  • cleaning
  • updating the floppy image
I am using (of course) standard Linux tools:
  • gcc
  • nasm
  • ld
  • objdump
  • doxygen
  • size
  • make
  • cscope
  • ctags
  • perforce

Compilation has pretty clean output (when stuff goes right, anyway) :


The output isn't that bad when stuff goes wrong either:


Bochs does a pretty good job of running MOS for debugging / testing quickly:



I have already found the CPU Register window helpful in debugging:





I am also starting to really become a fan of the doxygen generated documentation, this just looks fantastic:


Last, but not least, here is the video I promised at the start of the post.


Sunday, August 16, 2015

Power Supply Firmware Upgrade

This weekend I decided to upgrade the firmware in my home made power supply.  I wanted to increase the stability of the voltage measurement and the response of the display.
  Oversampling the ADC is how I decided to increase the accuracy and stability of the voltage measurement.  I chose to use a new architecture, that utilizes a real time operating system.  The first RTOS that came to mind for an 8-bit microchip processor was OSA RTOS.  This is a wonderful, tiny RTOS that is meant to be used on very small processors, such as the PIC18F46K22 that is inserted into the READY for PIC board used in my power supply.  I bought the board from MikroElectronika, just for this project.  The below picture shows the power supply with the top open, you can see the READY for PIC board on the right near the back.


The firmware architecture is fairly simple, I used 3 tasks in conjunction with message passing.
The firmware entry point ( main ) sets up this architecture and then schedules all tasks, this can be seen below in the diagram.


The firmware first initializes the system, which consists of board support type operations such as LCD, ADC and Timer initialization routines.  After this, the real time operating system is initialized, and the tasks are created.  Once those steps are complete, we need to have the operating system enable all the interrupts, so that the scheduler can cycle between tasks.  Finally, we enter into an infinite loop that will schedule time for each task in turn.

The first task, is also the most complicated one.  The handle samples task, manages the ADC sampling, voltage monitor oversampling and decimation.  This task actually samples 4 different ADC channels which all point to the same signal, this decreases the number of iterations
required to calculate the voltage value to display. The task makes use of a module called voltage monitor to handle the rolling over sample and decimation process.  Once it has the decimated value, it checks to see if the message is available, and then sends the decimated sample if possible.  In the event that there is a timeout while waiting for the message, the task will yield to the operating system scheduler.  This can all be seen in the below diagram.


The second task, is the update LCD task.  The diagram for this task is found below.

As you can see from the diagram, this task simply waits until there is a message to update the LCD.
If there is a message available; it will be retrieved, the voltage will be calculated, then output buffers will be built and displayed.  Again, like the handle samples task, if the message is not available, the task will yield to the operating system scheduler.

The final task, the idle task is very simple.  This is a task I used mostly for debugging the system. However in the future, it could be used to gather real time data about the system if I add more features.  For instance, I could add PC based control of the power supply via a UART.  There would be a task added to handle the commands from the UART, I could add a command to retrieve the diagnostic data from the global status structure.  Currently, the idle task tracks operating system errors, operating system event errors, operating system messages received and sent.  The flow of the idle task can be seen in the diagram below.


You may have noticed common theme in the way the tasks behave, namely that they always yield to the operating system scheduler as soon as they can.  This promotes a fast responsive application. The task flow knows the best possible way to give control back to the operating system, so it is best to do that when possible.

As I worked on this project, I used a logic analyzer to capture start up to full task scheduling in the application.  You can see that screenshot below, if you want to see a video of me talking about the power supply and this upgrade please use this link to view the video.


Sunday, June 21, 2015

RioRand EP2C5T144 Altera Cyclone II FPGA Mini Dev Board


Around March this year I received this mini FPGA dev board.  I have finally had some time to work with it some.  I found a good bit of helpful information available on Leon Heller's Page for this board.  I wrote a real quick test project, the code (VHDL) is below. Here is the link for the video of the project working.

library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.numeric_std.all;

 entity TestProject is
    Port (
           Clk_In : in  std_logic; -- Clock in from board (50 Mhz)
           led_1 : out std_logic;  -- Labeled D2 on board
              led_2 : out std_logic;  -- Labeled D4 on board
              led_3 : out std_logic   -- Labeled D5 on board
            );
 end TestProject;

 architecture RealTimeLogic of TestProject is
    constant slow_count : natural := 48000000;
     constant fast_count : natural := 12000000;
    signal Reset : std_logic;
 begin
   
    Reset <= '0';     -- Clear Reset.
    alternating_led_sequence : process(Clk_In,Reset)
        variable alternating_led_counter: natural range 0 to slow_count;
        begin
        if Reset = '1' then
            alternating_led_counter := 0;
            led_1 <= '1';
                led_2 <= '1';
        elsif rising_edge(Clk_In) then
                --    Handle the Oscillating Led sequence.
            if alternating_led_counter < slow_count/2 then
                alternating_led_counter := alternating_led_counter + 1;
                led_1 <= '1';
                     led_2 <= '0';
            elsif alternating_led_counter < slow_count then
                led_1 <= '0';
                     led_2 <= '1';
                alternating_led_counter := alternating_led_counter + 1;               
            else
                led_1 <= '1';
                     led_2 <= '0';
                alternating_led_counter := 0;
            end if;
            end if;
        end process alternating_led_sequence;
       
        blinking_led_sequence : process(Clk_In,Reset)
          variable blink_counter : natural range 0 to fast_count;
         begin
         if Reset = '1' then
                blink_counter := 0;
                led_3 <= '1';
         elsif rising_edge(Clk_In) then
                --    Handle the fast blinking Led Sequence
                if blink_counter < fast_count/4 then
                    blink_counter := blink_counter + 1;
                    led_3 <= '1';
                elsif blink_counter < fast_count then
                    led_3 <= '0';
                    blink_counter := blink_counter + 1;
                else
                    led_3 <= '1';
                    blink_counter := 0;
                end if;               
        end if;
         end process blinking_led_sequence;

 end RealTimeLogic;

Sunday, June 7, 2015

Linux Mint display resolution fix ( MAG 700P )

Don't you just hate it when you know that your LCD monitor can do some specific resolution, but  Xorg doesn't want to have any parts of it?

I do as well!  Here is a small fix that worked for me in relation to my MAG 700P LCD monitor.
First I found the correct mode line by running the following command:

cvt 1280 1024

This command will spit out the mode line for running a monitor at 1280 x 1024 @ 60 Hz:

# 1280x1024 59.89 Hz (CVT 1.31M4) hsync: 63.67 kHz; pclk: 109.00 MHz
Modeline "1280x1024_60.00"  109.00  1280 1368 1496 1712  1024 1027 1034 1063 -hsync +vsync


Now that I have the new mode line in hand, I can add it as a new mode to my current output device.

Test this information by running the following commands:

xrandr --newmode "1280x1024_60.00" 109.00 1280 1368 1496 1712 1024 1027 1034 1063 -hsync +vsync
xrandr --addmode VGA1 1280x1024_60.00
xrandr --output VGA1 --mode 1280x1024_60.00


If all of these commands are successful, then we should see the display switch to 1280x1024 mode.

These commands were successful for me, so I added them to a .xprofile file in my user directory.

** Note this only changes to 1280x1024 for my user **

Now, this doesn't matter as I am the only user of this computer.

Screenshot:





Sunday, April 5, 2015

Build Process for Firmware

If you have been following this from the beginning, I am going to talk about the build process for the firmware ROM images for the different platforms.  If you haven't been following you can find the first post here.

The build process overall should do some simple things:
  1. Build the ROM images from source.
  2. Clean old ROM images and build remnants out of the repository.
  3. Run a static code analysis of the source that makes up the ROM images.
 I chose to start with the three most similar platforms to configure the build process.  I decided on using clicker 2 for PIC32, mikromedia for PIC32, and the chipkit Pro MX4 boards.  These three boards all utilize a PIC32MX460F512L processor and we can use the free xc32 compiler from Microchip.

I am using Linux as my development platform, specifically Linux Mint 17.1 Rebecca.  I created my project directory to isolate as much of the hardware specifics as possible from the main firmware application code.
My directory structure looks as so:

 

Build ROM images from source


The master makefile is contained in the firmware folder, and it utilizes platform specific makefiles contained in the makefiles directory.  The master makefile has targets to build a specific platform's ROM image, or all ROM images.

Here is an excerpt of the master makefile, it's quite simple.


###############################################################################
#    Target Definitions
###############################################################################
#
#    NOTE: Usage of @ prior to the command will quiet the output of the command.
#
###############################################################################

###############################################################################
#    Build the firmware image that runs on the chipKIT Pro MX4 Board
###############################################################################

mx4:
        @make -f makefiles/Make_Chipkit_Pro_Mx4.mk

           

Building the mx4 target results in output as follows.

cmartin@mega ~/source/AlphaBot/source/firmware $ make mx4
make[1]: Entering directory `/home/cmartin/source/AlphaBot/source/firmware'
[CC ] main
[CC ] board
[LNK] AlphaBot
[HEX] AlphaBot
   text     rodata       data        bss        dec        hex    filename
      0          0       1644          0       1644        66c    build/debug/chipkit_pro_mx4/AlphaBot.hex
make[1]: Leaving directory `/home/cmartin/source/AlphaBot/source/firmware'




The specifics of building code, generating ROM hex images and cleaning up the build directories are contained in each platform makefile.  This provides flexibility that will be needed in the future when the STM32 and Zynq boards are used as targets also.

The platform specific makefiles are very similar to each other since they use the same compiler and processor.  There are several issues that you can run into trying to use the xc32 compiler from the command line only.  The following makefile excerpts are used to build the object files for modules.


###############################################################################
#    Board Specific Definitions:
###############################################################################

BOARD=PRO_MX4
IMAGE_NAME=AlphaBot
PROCESSOR=32MX460F512L


###############################################################################
#    Tools:
###############################################################################

TOOL_PATH=/opt/microchip/xc32/v1.34/bin

CC=$(TOOL_PATH)/xc32-gcc
SIZE=$(TOOL_PATH)/xc32-size
HEX=$(TOOL_PATH)/xc32-bin2hex

###############################################################################
#    Compiler:
###############################################################################

PROCESSOR_FLAG=-mprocessor=$(PROCESSOR)
CC_OBJECT_CFLAGS=-g -c $(PROCESSOR_FLAG) -D$(BOARD) -MMD -MF
CC_IMAGE_CFLAGS= $(PROCESSOR_FLAG) -Wl, --defsym=__MPLAB_BUILD=1 


###############################################################################
#    Build all objects in the project.
###############################################################################

all:    main board
    @echo [LNK] $(IMAGE_NAME)
    @$(CC) $(CC_IMAGE_CFLAGS) $(BUILD_PATH)/main.o $(BUILD_PATH)/board.o -o $(BUILD_PATH)/$(IMAGE_NAME).elf
   
main:    $(SOURCE_MAIN)/main.c
    @echo [CC ] $@
    @$(CC) $(CC_OBJECT_CFLAGS) $(SOURCE_MAIN)/main.d $(SOURCE_MAIN)/main.c -o $(BUILD_PATH)/main.o


board: $(SOURCE_PATH)/board.c $(HEADER_PATH)/board.h
    @echo [CC ] $@
    @$(CC) $(CC_OBJECT_CFLAGS) $(SOURCE_PATH)/board.d $(SOURCE_PATH)/board.c -o $(BUILD_PATH)/board.o   



Cleaning the Build remnants

 

The master makefile also contains targets to clean out the build remnants.  Here is the excerpt that accomplishes that goal.
 
###############################################################################
#    Clean all firmware image trees
###############################################################################

.PHONY: clean
clean:
        @make -f makefiles/Make_Chipkit_Pro_Mx4.mk clean
        @make -f makefiles/Make_Clicker2_Pic32mx.mk clean
        @make -f makefiles/Make_Mikromedia_Pic32.mk clean
       
###############################################################################


As before, each platform specific makefile is responsible for cleaning it's build remnants up after a build.  The platform files are all very similar as I said before, so I will include an excerpt from the mx4 file. 

###############################################################################
#    Clean the firmware image tree
###############################################################################

.PHONY: clean
clean:
    @rm -rf $(BUILD_PATH)/*.o
    @rm -rf $(BUILD_PATH)/*.hex
    @rm -rf $(BUILD_PATH)/*.elf
    @rm -rf $(SOURCE_MAIN)/*.d
    @rm -rf $(SOURCE_MAIN)/*.o
    @rm -rf $(SOURCE_PATH)/*.d   
           
###############################################################################



Static code Analysis 

 

I chose to use two utilities to do static code analysis on the firmware code base.
The first utility is called splint, it is a free version similar to the lint that was included in Unix installations.  I was able to use apt-get to install this and use the documentation to configure this to work for my project.

The second utility I chose is cppcheck, which I had some difficulties getting to work.  I tried to specify some include directories during the check of the code and cppcheck couldn't find the xc32 includes. The problem that I ran into had been fixed in newer version of the utility, however Linux Mint installed 1.61 by default.  I was able to fix my issues by retrieving the latest code for cppcheck ( version 1.68 ) and building it from the source.  After that I had no issues running the utility.

The makefile excerpts for this are shown below.

###############################################################################
#    Static Code Analysis of all source trees
###############################################################################
.PHONY: check
check:   
    @echo
    @echo [SPLINT  ]
    @splint -strict -noparams -exporttype -typeuse -nolib \
        -I/opt/microchip/xc32/v1.34/pic32mx/include/ -Iinclude/ source/*.c
    @echo
    @echo [CPPCHECK]
    @../tools/cppcheck-1.68/cppcheck --template '{file}:{line}, {severity}, {id}, {message}' \
                --force --enable=all -q -I/opt/microchip/xc32/v1.34/pic32mx/include/ -Iinclude/ .


I am sure there will be adjustments as I find issues and continue to build upon this code base.  I hope this was helpful in some way or another.

Saturday, April 4, 2015

Start of AlphaBot project.

I have started a new project, one that involves working with robot platforms.

I have acquired a few neat little robot platforms from some really great companies.  I chose these robot platforms because they allow me to work with modular designs that can share some  hardware and firmware.

First, I ordered the Buggy from MikroElectronika.  I haven't really talked about this company or their products, however I love their stuff.  Their products are very well built, documented and they provide examples.  I actually have quite a few of their products, and I can use almost all of the devices I purchased from them with this robot platform.  Eventually I hope use all of the following with this project:
MikroElectronika also has a very interesting plug and play system called mikroBUS.
This allows me to use various sub modules called Click Boards
these boards are great. I can write firmware code and prototype my system without designing and building the hardware first.  I have a few of the click boards, specifically the BLE P click and the nRF C Click that I wish to use with this project.
 
Second, I ordered the MRK Basic and MRK+Line robot kits from DIGILENT.  These robot platforms can't reuse the devices from MikroElectronika without building custom hardware adapters.  However, they have sub modules called pmods I can use with their chipKIT board as well as their ZYBO board.

This project will be quite challenging and enjoyable.  I plan to keep this blog updated as I work on it.