Archive

Archive for the ‘Tech’ Category

Slow disk access and overall speed issues in newer ubuntu and linux mint

April 10, 2017 Leave a comment

I have the subjective feeling that the newer versions of ubuntu and its derivatives including linux mint has slowed up a bit compared to pre unity ubuntus(11.04) or linux mint 17. I had been looking for the reason for some time. This probably won’t apply to you unless you are using a slow ‘hard disk’. The symptom is that subjectively the disk access latencies are larger (eg. applications take longer to start).

Linux has a software component called the IO scheduler. This takes care of scheduling requests to the permanent storage devices. There are a few choices for the algorithm to be used for this purpose. The choices and current selection can be seen by issuing

cat /sys/block/sda/queue/scheduler

(For me the sda is the drive containing all linux partitions. It may change for you ie. sda, sdb, sdc.. or hda, hdb, hdc…)

The default in modern ubuntu and linux mint is the ‘deadline‘ scheduler; probably a decision based on benchmark performance results on modern hardware. I changed this to ‘cfq‘, and subjectively the system became a lot more responsive. You can temporarily tryout the setting by writing the new scheduler name to the above file using command

sudo sh -c 'echo cfq > /sys/block/sda/queue/scheduler'

If you find think system responsiveness is better than before, you can make the changes permanent by writing following settings to /etc/default/grub and running update-grub2

sudo vim /etc/default/grub

Type the setting

GRUB_CMDLINE_LINUX="elevator=cfq"

Exit editor.

update-grub2

From next reboot onwards the setting should now takeplace at boot itself.

Area vs Time: A look at algorithmic complexity in Hardware and Software

Many of us would have studied in our college that implementing something in hardware will be faster than implementing the same in software. What i see from this situation is a time complexity being converted into area complexity. And the benefits provided by pipelining, and reduced control overhead resulting from special purpose control implementation (As opposed to more generic&bulky control logic required by a general purpose CPU).

My own recent expeditions in this area suggest something that is not so obvious. The inverse proportion between Logic Area and Time starts after a discontinuity. Some algorithms will benefit substantially if a very minimal part of the algorithm is implemented in hardware. Beyond that point the Area vs Time relation will be an inverse proportional relation.

I would call these minimal logic that brings in huge value add as a ‘primitive function’. Now a little bit of theory. A general purpose processor does some sort of data manipulation function (eg. add, subract, multiply, divide, compare shift etc..) between two registers. Basically for a simple RISC 32 bit processor, whose instruction set is capable of taking 2 32 bit register operands and producing 1 32 bit register output, there is some combinational logic between the 64bit input and 32 bit output, depending on the current instruction. The typical instruction set of a RISC is <256 instruction. Is this enough to do all the possible function mapping from a 64 bit input to a 32 bit output domain?. No certainly not. You can always have one function that mirrors one of the 32 bit input to the output.

So for any of the general purpose processors, it is not possible to implement all the possible function mapping from a 2 word space to a 1 word symbol space. Instead it just implements the most commonly used function mappings like add, subtract, boolean operators, shifts etc. If you take the case of mirroring of bits in a 32 bit word, it will sure take at-least 32 cycles to do it in a general purpose CPU. But implementing a mirroring in hardware doesn’t consume much logic. But instantly reduces the time required for computation of the mirror by a large amount.

So if you are tasked with implementing custom hardware constrained by area, the first thing to ask is: is my CPU capable of supporting all the primitive logic function, relevant for the algorithms in use.

TODO: To be updated with some rough sketches indicating my idea

Categories: Philosophy, Tech, Viewpoints Tags:

Building gcc as cross-compiler

Motivation

A cross-compiler is a compiler that runs on your PC and reads source code in your PC and converts that into binary suitable for some other CPU. Sometimes the precise cross compile tool may not be available as a binary package. For example, in my case i wanted to use bare-metal x86 tools(To build BIOS or similar low level system software). It was not available as binary package. Hence only option is to build it.

Dependencies

The packages and libraries needed to build gcc are well documented along with gcc. If you usually build softwares on your linux build PC, there are not much extra dependencies on the PC. One important dependency to build cross gcc is you should already have cross binutils for the same platform. And the binaries especially linker(ld) and assembler(as) should be available in the path. Eg. to build i686-elf-gcc, i686-elf-ld and i686-elf-as should be available in the system path. So

  1. Step 1 is to build binutis
  2. Step 2 is to build gcc

Further I will list the steps needed to build the cross gcc; specifically the i686-elf variant

Step 1: Build binutils as cross-tool

Download binutils. Extract, configure from a separate build directory, build and install it using following commands.

tar -xvf binutils-2.26.tar.bz2
mkdir build_binutils
cd build_binutils
../binutils-2.26/configure --target=i686-elf --prefix=<path-to-bin> --disable-nls --with-sysroot
make
make install
cd ..

All binaries will be available in the path specified in <path-to-bin>

Step 2: Build gcc as cross-tool

First set the path to binutils executables that got generated in the previous step.

PATH=<path-to-bin>:$PATH

Download, extract, configure from a separate build directory, build and install it using following commands

tar -xvf gcc-gcc-4_9_3-release.zip
mkdir build_gcccd build_gcc
../gcc-gcc-4_9_3-release/configure --target=i686-elf --prefix=<path-to-bin> --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

All binaries and libraries generated will be available in path specified in <path-to-bin>

References

OSDev: GCC Cross-Compiler

OSDev: GCC tool naming/prefix convention

Categories: Log, Tech Tags: , , ,

Automatic Hardware Configuration for Embedded Systems

June 18, 2011 Leave a comment

Most of the time required in embedded systems development (atleast in case of hobby level projects) is in the configuration of the on chip peripherals of the microcontroller. The traditional approach is to look up in datasheets and then set associated register values for the desired functionality. This is very tiedious and time consuming. A better option is to define some of the frequently used configurations using some name indicative of functionality, and OR in different such values to generate the value for a single register. This is the option provided by common compilers like gcc.

A better way is to code small pieces of code, that will automatically configure the peripherals for a subset of the functionalities offered (believe me, it is difficult to programme for all the functionalities provided by the hardware using such a program). This piece of configuration code will be executed at the beginning only, so it will not impact the performance of the system other than consuming some extra flash code memory. Quite often startup time or flash memory is not a limitation, compared to RAM or CPU.

The process of creating such a code is very labour intensive. But once such an auto config code is created, most often, you can reuse the code as such, and sometimes with slight modifications, to incorporate extra functionality. This makes the development much faster. Code generators producing the configuration code, based on specifications are available for some of the platfroms like AVR. But such tools are not available for all existing and yet to be marketed hardware.

Examples

The following illustrate the three methods for configuring the Timer0 of Atmega32 to CTC operation at a frequency of 5kHz, when the IO clock is 8MHz. The compiler used is avr-gcc, which is available in the repositories of Ubuntu 11.04.

Crude Method

TIMSK|=0x03;    //Enable overfolw, and compare match interrupts
TCCR0=0x8a;    //Prescaler is divide by 8; timer mode....
OCR0=200;

Need to go through a datasheet to code and understand.

Formal Method

TIMSK|=(1<<OCIE0)|(1<<TOIE0);
TCCR0=(1<<FOC0)|(1<<WGM01)|0x01;
OCR0=200;

Still need to go through a datasheet to understand or code. But easier to understand than crude method

Proposed Method

initTimer0(5000,8000000,T0_TIMER,T0INT_COMP,0.5);

Only need to specify the requirements-Easy to understand, modify etc. Not as easy to code, as the real thing is behind the function call, as given below.

The function is defined in another file or library as,

//Timer modes
#define T0_PWM  0x68
//Fast_PWM mode, clear OC0 on compare match (up count)
#define T0_SYMPWM 0x60
//Phase correct PWM, clear OC0 on compare match during up count, and set during down count
#define T0_TIMER 0x88
//OC0 disconnected, CTC mode

//Timer interrupts
#define T0INT_ALL   0x03
#define T0INT_COMP  0x02
#define T0INT_OVRF  0x01
#define T0INT_NONE  0x00

void initTimer0(unsigned long frequency,unsigned long clkIO,unsigned char mode,unsigned char interrupt,float dutyCycle)
{
    unsigned char config, count;

    TIMSK=TIMSK|interrupt;

    if(frequency>=clkIO/256){
        config=mode|0x01;   //Prescaler divide by 1
        count=(unsigned char)(clkIO/frequency);
    }
    else if(frequency>=clkIO/(8*256)){
        config=mode|0x02;
        count=(unsigned char)(clkIO/(8*frequency));
    }
    else if(frequency>=clkIO/(64*256)){
        config=mode|0x03;
        count=(unsigned char)(clkIO/(64*frequency));
    }
    else if(frequency>=clkIO/((long)256*256)){
        config=mode|0x04;
        count=(unsigned char)(clkIO/(256*frequency));
    }
    else{
        config=mode|0x05;
        count=(unsigned char)(clkIO/(1024*frequency));
    }
    TCCR0=config;
    if(mode==T0_TIMER)
        OCR0=count;
    else
        OCR0=(unsigned char)(dutyCycle*255);
}



Getting FreeRTOS to work with GCC and LPC2129

March 10, 2011 Leave a comment

FreeRTOS is a good OS to start with, if you have some fairly good hardware, like an LPC2129, ARM based chip. FreeRTOS is aimed to work with different processor architectures. The OS has two parts – a set of architecture independent codes, and a set of architecture specific codes called ports. The syntax for non standard functionalities like interrupt handling and inline assembly will be different for different compilers. Interrupt Service Routines and inline assembly are typically necessary for the architecture dependent files. Therefore, a port will be specific to a compiler and a target chip. But the present version of FreeRTOS doesn’t have a port for LPC2129 – GCC combination.

I assume that you have a working gcc compiler and other tools already installed. Refer to ARM Development under Ubuntu 10.04, for how to setup tools under Linux. Download FreeRTOS from sourceforge.net. Unzip into a convenient location.

The files you will need to compile are

  • list.c, queue.c, task.c and croutine.c from Source/
  • port.c and portISR.c form Source/portable/GCC/ARM7_LPC2000
  • heap_2.c from Source/portable/MemMang
  • A file containing the main() routine
  • boot.s and lpc2106-rom.ld from Demo/ARM7_LPC2106_GCC
  • LPC21xx.h from Demo/ARM7_LPC2138_Rowley

Rename lpc2106-rom.ld to LPC2129-ROM.ld, and open it using text editor. You will see the following at the start of the file.

Change these lines as displayed in the following figure. The size of the Flash and RAM are modified to that of the LPC2129.A simple main file will look like

#include “FreeRTOS.h”
#include “task.h”

int main(void)
{

unsigned char para0, para1;
para0 = 0;
xTaskCreate( foobar, “NAME”, configMINIMAL_STACK_SIZE, &para0, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
para1 = 1;
xTaskCreate( foobar, “NAME”, configMINIMAL_STACK_SIZE, &para1, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
vTaskStartScheduler();
while(1);

}

void foobar( void* pvParameters )
{

unsigned char *flag;
flag=(unsigned char*)pvParameters;
while (1){

if(*flag==0){

//do something

}
else{

//do something else

}

}

}

(Thanks to my friends Abhishek and Nisarg for the original main file)

Now you can compile and link all the files specified above, along with the libc.a , specified by linker option -lc, and chip specification -TLPC2129-ROM.ld. Also add Source/include directory to your include/compiler search path.

The generated elf file can be converted to hex file using arm-elf-objcopy command (if you have followed ARM Development under Ubuntu 10.04 ). The program can be dumped into the LPC2129 chip through the serial connection using command lpc21isp

eg:- lpc21isp -control -hex trial.hex /dev/ttyS0 9600 12000 will program trial.hex into the chip, through serial port ttyS0 at 9600 baud per second. 12000 is the frequency of the crystal (in kHz) used for the LPC2129 chip.

Categories: Tech Tags: , , ,

ARM development under Ubuntu 10.04

March 6, 2011 1 comment

Introduction

ARM is a very popular microprocessor architecture for embedded systems. Many mobile phones, netbooks and other similar portable computing and communication devices have an ARM core inside. Usually these ARM based embedded systems will have some operating system as well. Hence application development for ARM can be either on top of the OS or without the OS. In this page I will be describing about development of ARM applications without an OS (bare metal development).

C is the language of preference for embedded development, especially when it comes to systems without OS. I’m using the following set of tools to develop the C code and turn it into a machine language.

Tools

Code::Blocks IDE

Compiler, Linker etc.

Computer with Ubuntu Linux

Setting up the system

Code::Blocks is an easy to use Integrated Development Environment, which can be installed form Synaptic Package Manager or Ubuntu Software Center. Install Code::Blocks from one of these application.

Some of the bare metal development tools are listed here. Download the GNU GCC Toolchain for Linux. Extract the archive file by right click >> extract here. Now open the terminal and move the extracted folder to /usr/local/ directory. This can be done by issuing the command sudo mv arm /usr/local/. Though it is not absolutely necessary to move it to the /usr/local/ directory, it is the neat way. Add the location of the binaries to PATH, by issuing echo ‘export PATH=/usr/local/arm/bin:$PATH’ >> ~/.profile. You will need a reboot(Logging out and Logging in may be enough) of your computer for the new path to take effect. Verify whether the steps so far are done correctly by issuing arm-elf-gcc -v and see if the gcc is reporting the version. With this the tool chain installation is done.

You have to configure Code::Blocks to use the ARM GCC Toolchain. For this, goto Settings>>Compiler and Debugger…. A dialog box as shown below should appear.

Change Selected Compiler to GNU ARM GCC Compiler. Choose the Linker settings Tab, and add to other linker options -TLPC2129-ROM.ld, as shown. This configures the Code Blocks to use the file named LPC2129-ROM.ld as the linker configuration script.

In the Search directories tab, add /usr/local/arm/arm-elf/include for Compiler and /usr/local/arm/arm-elf/lib for Linker. This step make the Include and lib directory known to Code::Blocks and hence the compiler/linker.

Click on the arrow to the right of the Search directories tab, to reveal more tabs. In the Toolchain executables tab, set the Compiler’s Installation Directory to /usr/local/arm. Press OK to save the configuration. Code::Blocks is now configured correctly with the ARM GCC toolchain.

Starting an ARM project

Choose File>>New>>Project. Select Empty Project from the dialog box, and press Go. Enter ‘Folder to create Project in:’ and ‘Project Title:’ and press Next. Choose GNU ARM GCC Compiler, and clear the ‘Create “Release” Configuration’ checkbox, and press Finish. Now you can add your own source codes to the project. Do remember to add a crt0.S file to the project and to keep a file named LPC2129-ROM.ld in the project’s directory.

Categories: Hobby, Tech Tags: , , , , , ,

JACK Audio Connection Kit

Last weekend, I was trying out the JACK Audio Connection Kit on Linux Environment. They say its not limited to Linux and is/will be available for other UNIX like OS, Windows & Mac. I was lazy and involved with some HTML learning, so I could only understand and execute the basic program provided with it. Coming weekend I may try it for other programs and give you a better article. The following are a few of the things I noticed.

  • JACK is a very simple & intuitive API, for routing & processing digital audio, in realtime.
  • JACK is meant for professional audio, and not very good for very low processing power embedded sytems. May be you can do simple processings with an ARM.
  • JACK is in concept similar to analog modular synthesisers, where you connect one/more modules (eg: sound generators) to one/more other modules (eg: filters), using patch cords. The modules being replaced by software programs(like music players, your own programs etc.), and the interconnection of each module specified in the programs.
  • You can implement your own realtime Audio Processing Algorithm, in C using JACK API.
  • The API is huge and repel many amateurs. The fact is that with 10 to 12 functions, you can build fairly complex audio softwares.

You can expect more of my experiences with JACK in the weeks that follow.