Saturday, April 28, 2012

Installing MPLAB X IDE on Linux




MPLABX Integrated Development Environment (IDE) is a free, integrated toolset for the development of embedded applications on Microchip's PIC and dsPIC microcontrollers.

MPLAB X is not a new version of the current MPLAB IDE v8 framework but is instead based on Oracle's open-source NetBeans platform. In addition to its predecessor's functionalities and compatibility with Microchip's existing development tools, the new IDE utilises many NetBeans features allowing for user-interface improvements and performance upgrades[1]

Presumption

System: Fedora Core 16 - x64

Downloading


download IDE and your favorite compiler
http://ww1.microchip.com/downloads/mplab/X/index.html

OR using wget
wget http://ww1.microchip.com/downloads/mplab/X/mplabx-ide-v1.10-linux-installer.run # mplab X IDE
wget http://ww1.microchip.com/downloads/mplab/X/mplabc18-v3.40-linux-full-installer.run # C18 Compiler

Since IDE written in Java we need java run time if you already them installed go to next step if you dont, following the link below

http://www.java.com/en/download/help/linux_install.xml

Installing

$ chmod 755 mplabx-ide-v1.10-linux-installer.run
$ chmod 755 mplabc18-v3.40-linux-full-installer.run

$ ./mplabx-ide-v1.10-linux-installer.run
$ ./mplabc18-v3.40-linux-full-installer.run

$ reboot

Configuring

now we should configure the IDE before we start compiling codes

Run mplabx

$ mplab_ide

from "run" menu --> Set Project Configuration --> customize...

In left-most click on mcc18 then in right-most scroll down and double-click on "Include directories", a new dialog will be opened,double-click on it and change the default path for header file directories to "/opt/microchip/mplabc18/v3.40/h".

Compiler Configuration

Click ok.

In left-most click on MPLINK then in right-most scroll down and double-click on 'Library directories',a new dialog will be opened, double-click on it and change the default path for header file directories to "/opt/microchip/mplabc18/v3.40/lib/".

Linker Configuration


Click ok.

Apply then ok.

Case-Sensitive Problem


i have notice a small problem when i tried to compile an old project. the error was "Error - could not find file 'LibName.lib'.

this problem happen because lib names are written as high-letter on hard disk whereas MPLINK looking for low-letter names. eg ( on disk p18F4550.lib and MPLINK looking for p18f4550.lib).

to solve this problem we will make all of them low-letter


$ su -  # be root
# cd /opt/microchip/mplabc18/v3.40/lib
# for f in `find`; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done


Known Bug in Oracle Java JDK 1.6.x



Bug Description

incorrect mouse pointer position on java menus when running the application
maximized under gnome-shell.

1. If I single-click a menu in the menu bar, the menu will flash
briefly and disappears (instead of staying opened).
2. If I click and hold on a menu in the menu bar, the menu stays
opened, but the selection is vertically displaced (I have to move the
mouse to the third menu item to select the first one, for example).
3. If I right-click to access a context-menu, the selection is
displaced as described in the previous case).


The problem is that when the window is maximized java was not updating the
 window position properly. If the window was at pixel (100,100) then it was
 maximized, AWT thinks that it is still at pixel (100,100) instead of close to
(0,0). This causes it to miscalculate mouse pointer positions relative to the
window. [2]

Solution for this bug

remove old packages
# yum remove java-1.6.0-openjdk-1.6.0.0-65.1.11.1.fc16.x86_64 java-1.6.0-openjdk-devel-1.6.0.0-65.1.11.1.fc16.x86_64

*this could be vary from system to another, to know yours
$ rpm -qa|grep java

install new packages
# yum install java-1.7.0-openjdk
# yum install java-1.7.0-openjdk-devel

Set default Java version to mplabx_ide
# cp  /opt/microchip/mplabx/mplab_ide/etc/mplab_ide.conf  /opt/microchip/mplabx/mplab_ide/etc/mplab_ide.conf.bk
# gedit /opt/microchip/mplabx/mplab_ide/etc/mplab_ide.conf

search for jdkhome="/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.3.x86_64/" and replace it with jdkhome="/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.3.x86_64/"

*this could be vary from system to another, to know yours
$ ls /usr/lib/jvm/

References

[1] http://en.wikipedia.org/wiki/MPLAB
[2] https://bugzilla.redhat.com/show_bug.cgi?id=698295

Friday, April 27, 2012

Installing usburn on linux for brenner8


usburn is a Linux program, that analyses a HEX-file and transfers the
contained data via USB to the PIC-programmer Brenner8 or Brenner9. 

Prepare a place for installation
$ mkdir usburn && cd usburn  

download the usburn for Linux using firefox

or using wget
$ wget http://www.sprut.de/electronic/soft/usburn/linux/usburn_0_4.tar

then extract it
$ tar xvf usburn_0_4.tar 

modify "makefile" with your favorite text editor
$ gedit makefile 

change the line "-L/usr/local/lib" to 'libusb.so' location. I've found it under /lib/ directory so i will change the line to "-L/lib/". to find the location of yours, simple execute

$ locate libusb.so

save and close.

$ make
$ sudo mkdir /usr/bin/usburn.dir
$ sudo  cp -r usburn *.dat b8_firmware/ b9_firmware/ bootloader_0_2550/  /usr/bin/usburn.dir
$sudo gedit /usr/bin/usburn

write
#!/bin/sh
cd /usr/bin/usburn.dir
./usburn



save and close

$chmod +x /usr/bin/usburn

Usburn uses libusb instead of kernel modules to access the programmer,
consequently root privileges are required. To give access to normal users one
has to create a file "/etc/udev/rules.d/99-sprutbrenner" and to write into this
file: 

SUBSYSTEM=="usb", SYSFS{idProduct}=="ff0b", SYSFS{idVendor}=="04d8",
GROUP = "plugdev" [1]

$ cd /etc/udev/rules.d/
$ sudo echo "SUBSYSTEM=="usb", SYSFS{idProduct}=="ff0b", SYSFS{idVendor}=="04d8", GROUP = "plugdev" " >> 99-sprutbrenner

now programmer need to be calibrated, the manual below shows the steps
http://sprut.de/electronic/pic/projekte/brenner8/calibration_under_linux.pdf

the manual of usburn exist on

*NOTE* usburn does not support x64 in the meantime due to database incompatibility. check this out http://sprut.de/electronic/soft/usburn/linux/usburn_linux.htm#probleme

Thursday, April 26, 2012

Fedora :: error: db4 error(-30974) from dbenv->failchk: DB_RUNRECOVERY

While I'm trying to install a program using yum, yum was locked by another process then i had to freed it by sending it SIGKILL, and after that i passed my program to yum to install it then ... OPS !! yum is displaying a fatal error 

"error: db4 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db4 - (-30974)
error: cannot open Packages database in /var/lib/rpm
CRITICAL:yum.main:
Error: rpmdb open failed"

tried too many solution like cleaning up the yum's DB and it didnt solve it and in the end i fixed the problem by cleaning the RPM's DB and rebuild it again.

$ sudo rm -rf /var/lib/__db*
$ sudo rpm --rebuilddb
$ reboot # i had to reboot to solve it as well.

Wednesday, April 25, 2012

/boot/syslinux/ldlinux.sys: no match for target

If you are getting the error

"/boot/syslinux/ldlinux.sys: no match for target
syslinux: warning: unable to move ldlinux.sys"

then you are probably trying to install the syslinux boot loader to solve it make sure

1) your drive ( partition)  which you are trying to install syslinux on is either FAT16 or FAT32 otherwise syslinux will fail to start.

2) you have already created the file in your storage. using

$ mkdir -p /boot/syslinux/

then normally execute the syslinux installation command

$ syslinux -f -d /boot/syslinux /dev/sdb1

Tuesday, April 24, 2012

Installing Skype on Fedora 16 x64 machine using Autoplus (Error: Protected multilib versions)

Presumption

you are getting "Error: Protected multilib versions" when trying to install Skype using Autoplus on x64 system.

Solution

"Error: Protected multilib versions: glibc-2.14.90-24.fc16.6.i686 != glibc-2.14.90-14.x86_64"

This error seems to be occurred because skype is x32 bit executable but the system is x64, the "file" output says

/usr/bin/skype: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped


To solve this problem you have to install the glibc but the x32 bit, to do that, simple execute

$ sudo yum install  glibc-2.14.90-24.fc16.6.i686


If you have more "Protected multilib versions" just install thier x32 version then run autoplus and install Skype.

Monday, April 23, 2012

Flowchart and diagram drawing program for Linux


Presumption

Gnome 3 desktop environment is installed.

DIA

If you are looking to draw a flowchart or diagram for your documentation on Linux you may find “dia” project very interesting, the diagram drawing program (dia) is part of gnome project.

The man description says:

"Dia is used to create diagrams. Dia has a number of basic tools, like lines and boxes but can also dynamically load sheets. A sheet is a collection of tools that are used in a certain type of diagram.
Most diagram objects in Dia has handles. Lines can be connected to these handles and this way graph structures can be formed. When objects are moved or resized the connections will follow the objects.
Diagrams drawn in Dia can be exported PostScript."

After using it for hours i believed that is is good tool and it fits my need for drawing flowcharts of my software.

Installation

$ mkdir /tmp/dia
$ cd /tmp/dia/
$ wget ftp://ftp.gnome.org/pub/gnome/sources/dia/0.96/dia-0.96.1.tar.bz2 # size is 4.2 MB
$ tar xfv dia-0.96.1.tar.bz2
$ cd dia-0.96.1/
$ ./autogen.sh
$ make
$ sudo make install

now the program is installed and you can run it from terminal by writing $ dia or by clicking ALT+F2 then write “dia" and hit enter.


Saturday, April 21, 2012

How to customize fedora 16 and make it functional


-->

Presumption

Installed distro is Fedora 16 with Gnome 3 desktop environment.

Adding close and minimize buttons to windows

$ yum install gconf-editor

run it after installation by clicking on ALT+F2 then write “gconf-editor ” and hit enter.

in the Configuration Editor navigate to desktop --> gnome --> shell --> windows
Find “button_layout” and click on it and change it to ":minimize,maximize,close" .
logoff and logon again OR ALT+F2 then write “r ” and hit enter.

Show desktop icons and right clicks

 $ yum install dconf-editor 

Go to org --> gnome --> desktop --> background and check the box to show desktop icons. 

While this brings back desktop icons, and enables right clicking on the desktop, it makes the computer, home, trash icons visible. These are usually hidden with Ubuntu. To make them hidden again, but still allowing icons on the desktop, go to nautilus --> desktop, and uncheck the boxes for the icons you want hidden. 

Taskbar & dock

$ yum install docky # if you like dock-like taskbar
$ yum install tint2 # if you like classical taskbar
$ yum install gnome-panel # if you like the gnome original panel

to run and test them, ALT+F2 then write the name of program you want to run.

Personally i would recommend the gnome-panel for stability reasons, to add it to every system start up, ALT+F2 then write “gnome-session-properties” and hit enter, put name, lets say “gnome panel”, command “gnome-panel --replace”, and comment “ start up gnome-panel” then click add.

Hide all windows

usually, fedora user was hiding all menu by clicking ALT+CTRL+D, i like windows way to hide them (because it is uses less keys) which is WinKey (Or Super)+D.

To make it functional, hit WinKey and write "keyboard" --> "shortcuts" -->navigation --> "hide all normal windows " then set the shortcut you like.

Customizing the icons, fonts & theme

$ yum install gnome-tweak-tool

Then run it by hitting ALT+F2 then write “gnome-tweak-tool ” and having happy customization!
I like default xfce icons which is rodent icon set . I didn't find away to install it independently so i went to install the xfce desktop environment.

$ yum install xfce4-icon-theme

ALT+F2 then write “r ” and hit enter, after making any changes.

Fonts

the fonts "Tahoma" and "Calibri" are pretty enough with many languages support , they can be installed from windows directory. 

Gnome shell extensions

to install most of gnome extensions 

$ yum install gnome-shell-extension* 

the gnome-tweak-tool can be used for extensions customization.

Codeblocks

$ yum install codeblocks # for codeblocks
$ yum install codeblocks-contrib #for most plugins 

System monitoring gadget

"gkrellm" is nice and does the job 

$ yum install gkrellm 

To download transparent theme

To install the theme
Untar it on /home/<user_name>/.gkrellm2/themes

Friday, April 20, 2012

Writing Windows Services in C

Overview

This is a quick guide for writing windows services in C; which includes introduction, an example, short manual for service control manager (SCM), and references for more information.

Presumptions

1- You have a good C programming background.
2- You are planning to write your own windows service. I guess it is good to start
from here.

Introduction

A service is a console application that runs in the background and performs tasks that don't require user interaction. The Windows NT/2000/XP operating systems offer special support for service programs. For windows Vista and 7 please read the notes below.

In order to create a windows service, we need three additional functions

1) Service Main: commonly called “ServiceMain” and the standard prototype for it is

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);

It sends information to Service Control Manager (SCM) - which will take care of the status of the service - and it will register the service in the SCM.In the end of this function we will have a loop which will have our service.

2) Service CTRL Handler: this function will handle the standard requests from SCM and will response for its requests. The prototype of this function is:

void WINAPI ServiceCtrlHandler(DWORD opcode);

3) Service Initialization function: this function will initialize the Service topically global variables, cleaning up stuff if needed, and preparation for the service. Note that this function should return a value to tell the SCM that Service successfully initialized.The prototype is:

DWORD ServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError);

Notes

Before showing an example I would like you to consider the following notes:

1- Service name should not contain spaces and it should not be long. In the given example below it was named “MyService”.

2- WINAPI is same as __stdcall and it is not really needed on some compiler.  Also DWORD is equivalent for unsigned long.

3- The outputs of the service on x64 systems will be under “c:\Windows\SysWOW64”, and on x32 systems under “C:\Windows\System32”.

4- If the service requires an interactive process (like sending messages or loading forms) then go and read more about this in the references below. On some versions of windows in control panel --> system and security --> administrative tools --> services, then right click on the service and click on properties, then in the “Log On” tap check “Allow this service to interact with desktop” this may solve the problem.

5- Sometime service seems to be running nicely but it is not behaving as it should, well in this case we should consider the permissions give to this service, specially if we are reading/writing, a great tool called “Procmon” available on Microsoft website allow us to monitor the process so we can debug it, after installing run it and select PID filter to display your service behaviors only.

6- Each service executes in the security context of a user account, and it can be “LocalService”, “NetworkService”, or LocalSystem, every account has different privileges. These accounts do not have passwords.

7- A command-line utility, sc.exe also can be used to control services.  Its commands correspond to the functions provided by the SCM. It Service (like example below) does not have “ServiceInstall” function then we would use this tool to install it.

8- Windows Vista/7 has a security feature called “Session 0 Isolation” which means service runs on Session 0 and regular user runs on session 1, and they can’t send each other messages, so it could be a problem for some services, as solution CreateProcessAsUser function may does the job.

9- The example compiled and tested under windows 7 ultimate x64 with minGW- GCC version 4.6.1.

10- If compiler did not detect the ” _WIN32_WINNT”  declaration automatically then for windows 7 it is (0x0601), Vista (0x0600), and XP (0x0501).

11- Text editors can read and write files using at least the different ASCII CR/LF conventions. The text editor Notepad is not one of them so it would be better to use Wordpad if  “myRamInfo.txt” does not seem to have proper format.

 

Example

/**************************************************************
In this example, the function WriteMemInfo() will write information about available physical memory(RAM) on the system. The file myRamInfo.txt will be updated every 5 seconds.
**************************************************************/

//#define _WIN32_WINNT 0x0501 // for XP
//#define _WIN32_WINNT 0x0601 // for 7
//#define _WIN32_WINNT 0x0600 // for Vista

#include <windows.h>
#include <stdio.h>


SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;

DWORD ServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError);

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD opcode);
void WriteMemInfo(void);


int main(){

SERVICE_TABLE_ENTRY DispatchTable[] = {{"MyService", ServiceMain}, {NULL, NULL}};

if (!StartServiceCtrlDispatcher(DispatchTable))
//WriteMemInfo("StartServiceCtrlDispatcher() failed, error: %d.\n", GetLastError());
printf("StartServiceCtrlDispatcher() failed, error: %ld.\n", GetLastError());
else
printf("StartServiceCtrlDispatcher() looks OK.\n");

return 0;
}

// Stub initialization function...
DWORD ServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError){
// These statments have no effect!
*argv;
argc;
specificError;

return 0;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv){

DWORD status;
DWORD specificError;

// Type of service, application or driver...
ServiceStatus.dwServiceType = SERVICE_WIN32;

// The service is starting...
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;

// The service can be stopped & can be paused and continued.
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

ServiceStatusHandle = RegisterServiceCtrlHandler("MyService", ServiceCtrlHandler);

if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0){

printf("RegisterServiceCtrlHandler() failed, error: %ld.\n", GetLastError());
return;
}else
printf("RegisterServiceCtrlHandler() looks OK.\n");

// Initialization code goes here...return the status...
status = ServiceInitialization(argc, argv, &specificError);

// Handle error condition
if (status != NO_ERROR){

// The service is not running...
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = status;
ServiceStatus.dwServiceSpecificExitCode = specificError;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
return;
}

// Initialization complete - report running status.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)){
status = GetLastError();
printf("SetServiceStatus() error: %ld\n", status);
}
else
printf("SetServiceStatus() looks OK.\n");

// This is where the service does its work...

while(ServiceStatus.dwCurrentState == SERVICE_RUNNING){

WriteMemInfo();

Sleep(5000);
}
return;
}

// Handler function - receives Opcode, calls SetServiceStatus()
void WINAPI ServiceCtrlHandler(DWORD Opcode){

DWORD status;

switch(Opcode){

case SERVICE_CONTROL_PAUSE:

// Do whatever it takes to pause here...
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:

// Do whatever it takes to continue here...
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:

// Do whatever it takes to stop here...
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)){

status = GetLastError();
printf("[MY_SERVICE] SetServiceStatus() error: %ld\n", status);
}

printf("Leaving MyService.\n");
return;

case SERVICE_CONTROL_INTERROGATE:

// Fall through to send current status.
break;

default:
// else
printf("Unrecognized opcode %ld.\n", Opcode);
}

// Send current status.
if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)){

status = GetLastError();
printf("SetServiceStatus error %ld.\n", status);
return;
}

else
printf("SetServiceStatus() is OK.\n");

return;
}

// Some RAM info ...
void WriteMemInfo(void){

MEMORYSTATUS MemState;
MemState.dwLength = sizeof (MemState);
// Get Memory info
GlobalMemoryStatus(&MemState);

// Get Time info
SYSTEMTIME timeInfo;
GetLocalTime(&timeInfo);

FILE *fp;
char Wbuffer[32]=" Free RAM is: ";

sprintf(Wbuffer+strlen(Wbuffer),"%ld MB - ",(MemState.dwAvailPhys)/(1024*1024));
sprintf(Wbuffer+strlen(Wbuffer),"%d:%d:%d \r\n",timeInfo.wHour,timeInfo.wMinute,timeInfo.wSecond);

fp=fopen("myRamInfo.txt", "ab");
fwrite(Wbuffer, sizeof(Wbuffer[0]), sizeof(Wbuffer)/sizeof(Wbuffer[0]), fp);
fclose(fp);

return;
}