Exploring My Technical Learnings... Which could be a doubt or solution..!
Wednesday, September 30, 2009
fopen() usage using fgets() buffer: One of my bugs fixing
One day, when working on implementation of Device Detection code in C, we wanted to read the temp file which is the output of find command. When i read the first path from the file using fgets() function and used the same buffer in fopen(), opening a file has failed...!
system("find /home/raghu > temp");
fp = fopen("temp","r");
fgets(buffer_path, 500, fp);
fgets(buffer_path, 500, fp);//this is to avoid reading of first line in temp file which is the name of the directory itself
fp2 = fopen(buffer_path, "r");
Here, fp2 was NULL. I was shocked..! path of the file present in the buffer_path is valid, but fopen was failing..! I thought how it is possible? Then I tried,
fp2 = fopen("/home/raghu/temp","r");
Then, fopen was successful...! Then, have printed buffer_path character by character using one for loop. It was printing 'next line character' (going to next line) at the end when printed using '%d'. I have made it as '%x'. Then it has printed 'a' at the end BEFORE NULL CHARACTER. Then I tested by adding a SPACE character the end of path like,
fp2 = fopen("/home/Raghu/temp ", "r");
Then fopen has failed. I confirmed that fopen will fail if any extra character is present at the end. Then I made it like,
buffer_path[strlen(buffer_path)-1]='\0';
Then it worked fine.
In windows operating system also behavior is same as in Linux. I have tested. I had a doubt regarding this in Windows. But same behavior.
When i have done this, i got more confidence in my coding skill. From that day itself, i have involved in porting the application into linux. Hence i have understood more implementations of my colleagues on linux.
Even though coding language is same, every new implementation will give us more confidence and more happyness. Thats why i have started this blog also....
Feel free to write to me regarding ur doubts and suggestions. pramoda.ma@gmail.com
I wish u best of luck...
Sunday, September 27, 2009
Small C Program for USB device insertion detection in Linux Environment
As i have told u before in previous posts, at the first time i have written a small C program for device detection using mount API of linux.
I am giving here that. Please look once.
void main()
{
Char Buffer[256];
FILE *fp1;
system ("ls /dev/sd* > NodeList");
fp1 = fopen (NodeList, "r");
if(fp1 == NULL)
{
printf("IN CM FIle Open Fail\n");
}
pthread_create(&threadID , NULL, (void*)detect, NULL);
}
void detect(void)
{
int i;
FILE *fp;
char Node[256];
while (1)
{
fp = fopen(NodeList, “r”);
if(!fp)
{
Printf(“File open unsuccessful\n”);
continue;
}
while(!feof(fP))
{
fgets(Node, BYTES_TO_READ,pp_fd);
i = mount(Node,"/mnt/DEVICE","vfat",0,0);
if(i == 0 )
{
printf("Mounted %s\n”, DeviceNode);
}
fgets(Node, 256, fp);
}
fclose (fp);
system ("ls /dev/sd* > NodeList");
Continue;
}
}
Mount API of Linux returns zero when mounting is successful. Hence i am checking here the return value of mount API.
It was working fine when it was not integrated with our other modules. But when we integrated, this was not working sometimes. I dont know why it was inconsistent in our project. Hence i have implemented my other idea using shell scripting and signals. I have posted the same in previous posts.
But it could give problem at sometimes when some hard disk or more devices are connected to the system. Also, in some embedded linux, USB device detection itself will take more time. For example, our current linux Freescale linux is taking near by 8 secaonds to create a node in /dev/ directory. Hence our application (my shell script) also will take more time.
If anybody finds a different and easy ways for device detection, please fell free to write to me at pramoda.ma@gmail.com.
Wish u best of luck...
Sunday, September 20, 2009
Autolaunching our Application in Embedded Linux
We have used Qt 4.3 for developing HMI(GUI) application.
What I wanted to do was, our USB device detection shell script detect.sh and our GUI application 'Myplayer' both should launch when the system is switched ON. Hence i have written my own shell script at the end of init script in /etc/rc.d/rc.local file.
I have restarted the system and i was waiting for our application come up. But system is restarted but application hasn't come!
I have seen the currently running proccess using 'ps' command. My shell script was running, but after insertion of USB device, no statements were printing! i thought something is going wrong. I was trying more times.
After some time, just i have executes 'ls /mnt/Device'. This was the mounting point after USB insertion. All files were displayed!!!! I have shocked. Then i came to know, 'echo' will not print any statements because before 'console' application is started, shell script has started and hence any outputs will not come to console. I was heppy at that time.
Now i have started to think about the launching of HMI application. Actually to run our application, some paths has to be exported. I was doing this by exceuting a shell script. But those were not exported in console! Exporting of those paths were not affecting the console. Then i came to know that their scope is within the script only. Then i have written an extra statement at the end in shell script /opt/Myplayer where our application was in /opt/ directory.
I was successful.l.l.l.l.l....!!!!!!
Say example, OurStartupScript.sh would be,
export1
export2
export3
.
./opt/Myplayer
Our init script would be,
if [ -f /opt/Myplayer ]
then
sh /root/OurStrtupScript.sh &
if [ -f /root/detect.sh ]
then
sh /root/detect.sh &
fi
fi
Previously it was like,
if [ -f /opt/exportEcript.sh ]
then
/opt/exportScript.sh
/opt/Myplayer
if [ -f /root/detect.sh ]
then
sh /root/detect.sh &
fi
fi
After all, our application was starting after 1 min 40 seconds after rebooting/powering the system. Detection was robust. I was feeling happy....!!!
In my next posts, i will be sharing about the creation of shared objects in Linux and one small C program(but inconsistent) to detect the inserted device.
If u get any idea or doubt or solution or suggestion, please mail to pramoda.ma@gmail.com
Good luck.....
Tuesday, September 8, 2009
Shell Script for Embedded Linux
If already some nodes are present in /dev/ directory starting with 'sd' like sda1, sda2 etc, previous script (for Desktop linux) )can be used.
while [ 1 ]
do
set ls /dev/sd[a-z][1-9]
if [ -b $1 ]
then
d=$#
else
d=0
fi
while [ 1 ]
do
set /dev/sd[a-z][1-9]
for p in "$@"
do
if [ -b "$p" ]
then
d=`expr "$d" + 1`
echo "$d"
fi
done
if [ "$d" -gt "$#" ]
then
echo Yes..Now Detected.."${@}"
mount=1
break
else
echo not yet
sleep 1
fi
done
sleep 1
echo "It has come $#"
j=0
for p in "$@"
do
arr[$j]=$p
j=`expr $j + 1`
done
echo j="$j"
echo This is the node "${arr[$#-1]}"
mount -t vfat ${arr[$#-1]} /mnt/DEVICE
ls /mnt/DEVICE
node="${arr[$#-1]}"
echo Final node is "$node"
#------------------------------------------#
d1=$j
echo j="$j" "$node"
i=0
while [ 1 ]
do
if [ -b "$node" ]
then
echo "still existing"
else
echo "Disconnected"
umount /mnt/DEVICE/
mount=0
fi
sleep 1
if [ "$mount" -eq 0 ]
then
break
else
continue
fi
done
done
Fine. I think these scripts can be optimized by the shell script experts. I have done this after long time of my Shell script usage. I have used shell script 3 years back in my academic. But because of this shell script, i was able to refresh most of the syntaxes/concepts of shell script. Thats what i needed.
I was very much happy when i completed this.
If anybody done optimization, please mail me the script to pramoda.ma@gmail.com
Saturday, September 5, 2009
Shell Script for USB Device Insertion/Removal Detection : Embedded Linux and Desktop Linux
First i have done for Embedded Linux in very simple way. But i was not sure about its working on all Linux distributions. Bcoz in some Linux, there could be HDD devices as /dev/sda1, /dev/sda2 and so on. Hence i have decided to make it work in Desktop linux and after, definitely that will work on all embedded linux also.
But my expectation was wrong. What i have executed on desktop Linux which didnt work on Embedded Linux on target. I didnt think about that's reason. Anyway after i have modified the same script to make work on Embedded linux.
Lets share tha same.
Script for Desktop Linux:
while [ 1 ]
do
set /dev/sd[a-z][1-9]
d=$#
while [ 1 ]
do
set /dev/sd[a-z][1-9]
if [ $# -gt "$d" ]
then
break
fi
echo not yet "$d"
sleep 1
done
echo "It has come $#"
j=0
for p in "$@"
do
arr[$j]=$p
j=`expr $j+1`
done
echo This is the node "${arr[$#-1]}"
mount -t vfat ${arr[$#-1]} /mnt/DEVICE
ls /mnt/DEVICE
#------------------------------------------#
d1=$#
while [ 1 ]
do
set /dev/sd[a-z][1-9]
if [ $# -lt "$d1" ]
then
break
fi
echo "Still connected"
sleep 1
done
echo "Disconnected now"
umount /mnt/DEVICE
done
done
But. this script should be running in background. Will generate the signal when device is detected or new node has come under /dev/ directory.
For which process signal has to be sent, that's PID is the input for 'kill' command. Process's PID i am getting here using 'grep'. Process name is the input for grep and 'ps' has to executed before 'grep' to get PID of the process.
When device is detected, i am mounting the same to a specific path, here is /mnt/DEVICE. In my proogram, i will read the contents of the device from the same path.
Actually, we were using thread (pthread_create) and 'mount' system call to detect the device insertion/removal. That program also i will give in y next post which could help or could give more idea to others.