Saturday 16 August 2014

Accessing hardware registers in userspace using memmap in Linux

Introduction:
If you want to access hardware registers in Linux userspace you can use the following example to explore access.  However if I recommend creating a Linux Device Driver if you want to do this properly.
Note that this is an advance Linux topic, so please do NOT try this first in a production system.

Example:
Full man can be found at
http://linux.die.net/man/3/mmap
Example:
/*
 * Maps real memory address to a virtual address.  The virtual address
 * then could be used to read/write the real memory as if it was
accessed
 * directly.
 * Adapted by Janaka Subhawickrama. Copyright 2007.
 * GPL software.
 */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>

//Virtual address that is associated with the physical address
static char *regmap_addr = NULL;
//The following is the physical address of memory mapped registers of
the CPU
#define REGISTRY_MAP_ADDRESS_OFFSET        (0xE0000000)
#define REGISTRY_MAP_SIZE                (0x000FFFFF)
#define GPIO2_DATA_DIR_REG_OFFSET        (0x00000D00)
#define GPIO2_DATA_REG_OFFSET                (0x00000D08)
#define GPIO2_DONE_PIN                        (0x00800000)
#define GPIO2_FAULT_PIN                        (0x00400000)
#define GPIO2_PROGB_PIN                        (0x01000000)

int main(int argc, char *argv[])
{
        int devmem; // this is the "/dev/mem" descriptor
        //Registers of the CPU I am using is 32bit
        volatile unsigned int uiGet;
        volatile unsigned int *ptmp = NULL;
        //On embedded systems you may have to mknod /dev/mem
        printf("\nOpening /dev/mem");
        devmem = open("/dev/mem", O_RDWR | O_SYNC);
        if (devmem < 0)
        {
                printf("\nOpening of /dev/mem failed with (%d) %s\n", errno,
strerror(errno));
                return -1;
        }
        printf("\nMapping Memory mapped registers at %08X with size %08X",
REGISTRY_MAP_SIZE, REGISTRY_MAP_ADDRESS_OFFSET);
        regmap_addr = (char *)mmap( 0, REGISTRY_MAP_SIZE, PROT_READ|
PROT_WRITE, MAP_SHARED, devmem, REGISTRY_MAP_ADDRESS_OFFSET);
        if (regmap_addr == (char *)MAP_FAILED)
        {
                printf("\nCould not map registers (%d) %s", errno, strerror(errno));
                close(devmem);
                return -1;
        }
        //Now you can write to CPU registers as if you were from a boot
loader
        //Setup directions of GPIO pins
        *(volatile unsigned int *)(regmap_addr + GPIO2_DATA_DIR_REG_OFFSET) =
GPIO2_FAULT_PIN | GPIO2_PROGB_PIN;
        //Turn some GPIO Pins on
        *(volatile unsigned int *)(regmap_addr + GPIO2_DATA_REG_OFFSET) =
GPIO2_FAULT_PIN | GPIO2_PROGB_PIN;
        //Get some values of GPIO lines
        uiGet = *(volatile unsigned int *)(regmap_addr +
GPIO2_DATA_REG_OFFSET);
        printf("\nGPIO register %08X", uiGet);
        //Cleanup
        munmap((void *)REGISTRY_MAP_ADDRESS_OFFSET, REGISTRY_MAP_SIZE);
        close(devmem);
        return 0;
}

More comments and caveats can be found at:
https://groups.google.com/forum/#!msg/comp.os.linux.embedded/kOKNHeMGg58/pTY-jLMFu_gJ

Review of : Linux Device Drivers, 3rd Edition

Janaka 29/May/2008 - "High-water mark for LDD development books"

Introduction:
I picked this book up as an experience embedded software engineer who wanted to explore and learn about Linux device drivers. With a background in real-time embedded software development(with some RTOS experience) and years of Linux/nix user/developer experience this book nicely matched my learning path.

Layout of the book:
The chapters are layed out in a logical and incremental fashion where introductory chapters stick to the big picture stuff while later on chapters delve deep in to the internals.

Contents and Examples:
Book takes the approach of explaining the subjects in concise manner with examples and interesting incite. However the code examples in many cases are incomplete, and duly so. I say this because the lot of examples, in their entirety, are provided on their web/ftp site.

Currentness and compatibility:
The book uses x86 as its platform and for its examples. I found some minor differences in API interfaces on other platforms(i.e.:PPC). Also some of the latest kernels have altered some of the APIs slightly.

For who:

In my opinion this book is for software engineers/developers who has experience in C and Makefiles. Any embedded development experience will help understand why things are done the way they are and the deeper issues of concurrency and timing.

Conclusion:
This book is the benchmark for Linux device driver books. It is well set out and a easy read. To get the maximum out of the book you will need to play around with the examples/ideas that are covered in this book.

Toshiba P870/027 (PSPLBA-02700S) review

Specs: 
Core i7-3610Qm, 16GB (1600MHZ) RAM, 64-bit Windows 7, 1920x1080 Display, Intel 4000 HD + a 2GB Nvidea GT 630M video card, Blu-ray burner, 4 x USB 3.0 ports, Bluetooth 3.0, Wireless b/g/n, HDMI and VGA out, 1Gb/s Ethernet, DVB-T TV card, HD webcam

Look and feel: 
 The pictures on the Toshiba site does not do justice to this laptop. It looks and feels much more sexier than what the picture tells. Entire non-functional surfaces of the laptop feels like its an aluminium or a metal alloy. It is NOT plastics painted to look like metal.

Size : 
It is thin, but wide and long. It feels like Toshiba could have done some more compacting given the wasted real-estate. It might be a bit too big to lug around if you are a frequent traveller.

Screen: 
First class. Vibrant and bright. Good refresh rates. More than reasonable viewing from extreme oblique angles. Good for watching movies. But I haven't tried playing games yet.

Playing blu-rays: 
Smooth when on power pack (did not test on battery). Apparently can play 3D Blu-ray via HDMI to a TV.

TV tuner: 
Antenna connection mostly needed. Excellent tuner. Great reception quality. Even tuned on to hard to get analog TV channels. Got 34 channels in Melbourne including digital radio channels.

Touchpad: 
Has scroll bars and gestures. Very impressed with the smoothness and detection of gestures. It just works (Pinch/zoom, rotate, scroll vertical and horizontal). The touchpad buttons could have been better.

Sound:
Harman/Kordon sound. Excellent quality. Good base and loudness. Good internal mic.

Camera:
Average quality capture. Clumsy application.

HDDs: 
1.5GB (1 + 0.5) good size 5400RPM. Its good for battery life, but It would have been much better if it was 7200RPM. Has good HDD vibration protection.

Comms: 
Ethernet and wireless-n works like a charm. Did not try bluetooth yet. All the connection settings for all network cards are centralised using a Toshiba Comms applet which is intuitive and easy to use.
It has a RTL8723AE. Pretty good when used with the Windows 7 drivers.
However awful Linux support. Still waiting for a stable Linux driver (even in 2014).

Keyboard: 
Toshiba could have done much better in this department. Most keys are large; except for function keys, small space bar and tiny (half-size) arrow keys. Good size number pad. Keys feel plasticky and push buttony, but can get used to it. There is a keyboard back-light (IMO bling) that can be turned off. Keyboard as a whole is not too bad to use if you get used to using the number pad as arrow keys. IMO tiny arrow keys are worst part, specially for SW development.

SD card slot: 
Works well but does not have a dust cover

Battery life: 

Bit disappointing. Just over 3hr when using default profiles.

Heat dispersal: 
Excellent

Default software:
OS is Windows 7 Home Premium (should really have been Windows 7 Pro). Nice features like plug-in USB stick backups (Like the Mac) called Clickfreebackup. There is a reasonable Blu-ray/DVD burning software and some other Toshiba specific apps that can be useful.

Linux Compatibility:
Works great with Kubuntu 12.04 live CD. I think it will work much better when natively installed with BumbleBee (Linux version of NVIDIA Optimus). Can't wait to install it.

Overall very happy and well worth the price I payed at JB HiFi ($1545 + 20% for full 3 year warranty on 2012-Jun-22).

Friday 15 August 2014

Tips and tricks to improve your VmWare VM performance

Problem:
I run various virtual machines on VmWare Player (6.0.3) running on K/Ubuntu 14.04 on a Core i7 laptop.  I get terrible performance on all virtual machines I run regardless of the guest operating system I run (Win7-64, WinVista, WinXP, Linux).  Issues:
  • Slow to start from suspension
  • Freezes occasionally for up to 30 seconds.
  • Seems to thrash the hard drive when running
  • Slow to suspend 
Laptop has more than 8GB of RAM and two hard disks, both running at 5400RPM.  Performance does not improve regardless of the RAM I allocate to the VMs (e.g.: 1-4GB).

Solution:
After various failed attempts I found the following combination of optimisations to worked best with the setup I have:
  • Move VM: Move the VM to another hard drive away from the hard drive that runs the Host system.  Preferably move it to a higher performing HDD (i.e.: 7200RPM or 10000RPM).  What seems to happen is that during certain times, the Host system tries to access the HDD (presumably to access VMware libraries) as the same time as the Guest OS.  This results in HDD trashing and very poor performance.  Sometimes even the Host seems  freeze when this happens.  By moving the VM to a seperate hard drive we remove this bottleneck.  Even USB HDDs seems to perform better when the Guest was moved to it rather than having the Host and the Guest on the same 5400RPM HDD.
  • Use the amount of RAM recommended by VMware:  Using more than the recommended amount of RAM on the VM seems to have no improvement on the system performance of the Guest.  I have read some posts which say that the Guest performance can even be decreased by having more RAM on the VM.  I personally have not seen this effect.
  • Turn 3D acceleration off:  Enabling 3D acceleration seems to thrash the HDD more frequently and did not visually provide any improvements. Turn it off if you are not using 3D acceleration.
  • De-fragmenting the VM hard drives: Marginally improved performance was noticed when using de-fragmented VM hard drives.
  • Do not allocate more than 2 virtual cores (vCores) to the Guest VM.  Adding more cores may actually slow the Guest and Host PCs down if the specific application you are running is not designed to take advantage of SMP. See IssueWithMultipleCores.  

Trials that failed:
  •  Running"Bumble bee" graphics acceleration on the Host and enable the VM 3D acceleration.  Actual performance seems to degrade slightly with this setup.
  • Hacking the VMX files to optimise different option.  There was slight improvement of the performance of the VMs but it was not significant.
Other interesting behavior:
  • Recently discovered that having a Bridged mode network connection occasionally degrades the VM performance for about 5 seconds. The reason is currently unknown (Possibly NetBios announcements causes some extra processing). Things seems to get better longer you keep the VM Open.
  • I have noticed that when the VM is first starts up, from cold boot or from a suspended session, everything seem to be slow for about a minute.  Even mouse moves and clicks seems slow.  Then it gets better and stays better.  My hypothesis is that:
    • Host machine loading the guest RAM in to real RAM (from paged memory) takes time
    • There is some sort of caching that helps performance.
 Conclusion:
If you want to substantially improve the performance of your guest VMs, following will give you a good head start:
  • Move the VM to another HDD (Preferably to a higher performing HDD)
  • Set the guest RAM to VmWare recommendation.
  • Turn 3D acceleration off if you are not using it
  • De-fragment your virtual disks from within the VM as well as from the VmWare Player tools