Archive for the ‘Programming’ Category
Posted by Derek@TheDailyLinux »
Add Comment »
The following sections give quick, heavily commented, and ready-to-run examples that will give you a head start in creating a unit test framework in Python (pyUnit). First, we’ll take a look at a standalone module with several simple examples of unit tests. Then, we’ll take a look at a more complicated version that uses modules and test suites.
Here’s the first example. As long as you are running Python version 2.1 or greater, you can copy/paste this code, save it to unittest.py, and run it using python unittest.py.
'''This is a simple program to demonstrate how to create a unittest in
Python. For more information and documentation, please see the official
documentation page here: http://docs.python.org/library/unittest.html'''
import unittest #Include the pyUnit unittest framework
def add(a,b,c=0):
'''A simple adding function to demo unittest'''
return a+b+c
# The following is the class in which all functions will be ran by unittest
class AddTest(unittest.TestCase):
''' Main class for add testing; Can be added to a suite'''
# The function "setUp" will always be ran in order to setup the
# test environment before all the tests have run.
def setUp(self):
'''Verify environment is setup properly''' # Printed if test fails
pass
# The function "tearDown" will always be ran in order to cleanup the
# test environment after all the tests have run.
def tearDown(self):
'''Verify environment is tore down properly''' # Printed if test fails
pass
# Functions beginning with "test" will be ran as a unit test.
def test_positive_add(self):
'''Verify that adding positive numbers works''' # Printed if test fails
self.assertEqual(add(10,23,22), 55) # Test will fail if "false" (boolean)
self.assertEqual(add(11,23), 34)
self.assertEqual(add(1,1,17), 19)
# Functions beginning with "test" will be ran as a unit test.
# @unittest.skip("demonstrating skipping") # Skip this test (Python >= 2.7)
def test_negative_add(self):
'''Verify that adding negative numbers works''' # Printed if test fails
self.assertEqual(add(-12,23), 11)
# Functions beginning with "test" will be ran as a unit test.
# In this case, this test will be skipped.
#@unittest.skip("demonstrating skipping")
def test_negative_add_skip(self):
'''Verify that adding negative numbers works''' # Printed if test fails
self.assertEqual(add(-12,23), 11)
if __name__=='__main__':
unittest.main()
For more complicated test suites and modularity, please take a look at the git repository I’ve setup on bitbucket.org. Download the source, read the README file, and you’ll be able to have a working example of a testsuite (run with python pyunit_intro/suite/test/unittest_run_all.py).
https://bitbucket.org/dhildreth/pyunit_intro
Source: Much of the code from above was done first in this great introductory presentation given by Chander K. Ganesan at PyCon 2010.
Posted by Derek@TheDailyLinux »
2 Comments »
If you’re a programmer, you might be interested in taking advantage of the ctags utility to quickly navigate through your source code in a text editor such as VIM.
Ctags is a utility or program that creates an index (aka tag) file of names found in source and header files of various programming languages. This index includes things such as functions, variables, class members, macros, etc. This is great because vim can take advantage of this index and you can more quickly navigate through source files. For more information, wikipedia has a nice article on it here.
To start using ctags, you must first have the ctags utility. A quick check would be to just type ctags --version in the terminal:
thelinuxdaily@localhost> ctags --version
ctags (GNU Emacs 23.1)
Copyright (C) 2009 Free Software Foundation, Inc.
This program is distributed under the terms in ETAGS.README
If you have it, then we can immediately start using it. First, build the index by running in the directory where you keep the source code:
ctags source.c
If you’d like to be able to recursively scan all of your source files, you must insure that you’re using the exuberant ctags utility. In a Debian based system, this is simply done with:
sudo apt-get install exuberant-ctags
sudo update-alternatives –config ctags
Then, open the source in vim and use ctrl ] to jump into the tag and ctrl t to jump out of the tag.
There’s quite a bit of information available out there on using these tools together. I would recommend taking a look around. Here are a few that I found:
Stackoverflow: Vim and Ctags tips and tricks
Linux.byexamples: Vim with Ctags
Posted by Derek@TheDailyLinux »
Add Comment »
Upon starting up your Linux kernel, a bogoMIPS calculation will be made and recorded into /proc/cpuinfo. This is a value that is not dynamically updated, so if you change the clock speed of the CPU, the bogoMIPS value contained in /proc/cpuinfo will not be updated. If all you’re interested in is a simple verification that your CPU speed was changed, you could compile and run the following bogoMIPS calculation program both before and after the clock speed change.
http://www.ibiblio.org/pub/linux/system/status/bogo-1.2.tar.gz
Simply call ‘make’ to compile the program. You may need to modify the Makefile in accordance to your needs (cross compiling, gcc flags, etc). You may notice that the bogoMIPS value calculated by this program is not the same as the value calculated by the kernel. That’s okay. What matters here is that you can verify a change in CPU speed. After all, “bogo” stands for “bogus” which simply means “fake”.
Source:
http://tldp.org/HOWTO/BogoMips/bogo-faq.html
Posted by Derek@TheDailyLinux »
Add Comment »
Here’s yet another quick example of a serial capture c program that I came across while at work the other day. I just figured I would share…
int main(int argc, char * argv[]){
while(1){
FILE *fp;
fp = fopen("/proc/bus/usb/001/003", "r");
char buff[100];
while(fscanf(fp, "%s", buff) != EOF){
printf("%sn", buff);
}
fclose(fp);
}
return 0;
}
Posted by Derek@TheDailyLinux »
12 Comments »
The following is a quick c program that will capture raw keyboard data from the event device node such as /dev/input/event1. Simply compile and run with the specific device node as an argument. ie. ./keyboard_key_capture /dev/input/event1.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
void handler (int sig)
{
printf ("nexiting...(%d)n", sig);
exit (0);
}
void perror_exit (char *error)
{
perror (error);
handler (9);
}
int main (int argc, char *argv[])
{
struct input_event ev[64];
int fd, rd, value, size = sizeof (struct input_event);
char name[256] = "Unknown";
char *device = NULL;
//Setup check
if (argv[1] == NULL){
printf("Please specify (on the command line) the path to the dev event interface devicen");
exit (0);
}
if ((getuid ()) != 0)
printf ("You are not root! This may not work...n");
if (argc > 1)
device = argv[1];
//Open Device
if ((fd = open (device, O_RDONLY)) == -1)
printf ("%s is not a vaild device.n", device);
//Print Device Name
ioctl (fd, EVIOCGNAME (sizeof (name)), name);
printf ("Reading From : %s (%s)n", device, name);
while (1){
if ((rd = read (fd, ev, size * 64)) < size)
perror_exit ("read()");
value = ev[0].value;
if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
printf ("Code[%d]n", (ev[1].code));
}
}
return 0;
}
Here is an example output from running the above command. Notice that Code[] is printed before the key that was pressed.
# ./keyb_key_cap_x86 /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd
Reading From : /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd (Dell Dell USB Keyboard)
Code[30]
aCode[48]
bCode[46]
cCode[32]
dCode[18]
eCode[33]
fCode[34]
gCode[35]
hCode[23]
iCode[36]
jCode[37]
kCode[38]
lCode[50]
mCode[49]
nCode[24]
oCode[25]
pCode[16]
qCode[19]
rCode[31]
sCode[20]
tCode[22]
uCode[47]
vCode[17]
wCode[45]
xCode[21]
yCode[44]
zCode[2]
1Code[3]
2Code[4]
3Code[5]
4Code[6]
5Code[7]
6Code[8]
7Code[9]
8Code[10]
9Code[11]
0
This is only an example program that I picked up from work. I hope it will be of use to somebody out there so it can quickly help you get started with your project.
Posted by Derek@TheDailyLinux »
Add Comment »
For any of you out there who would like to learn about serial programming or are in need of a simple serial program for testing, I would recommend checking out the one from “Captains Universe” here:
http://www.captain.at/howto-simple-serial-port-test-example.php
It’s easy to understand, modify, and compile and I think it’s a valuable tool in any programmers or embedded Linux users arsenal.
Posted by Derek@TheDailyLinux »
1 Comment »
Until today, I had only heard of the time program to track how much time a program took to execute entirely. This is useful to see if there are any optimizations that can be made to make the program run quicker, but it doesn’t help troubleshoot or debug a program very easily since it only tracks the entry and exit of the program being ran. Another utility that allows you to track time in a more detailed manner is called gprof. Here’s a quote from the CS department of Utah School of Computing (link) explaining it in more detail:
Profiling allows you to learn where your program spent its time and which functions called which other functions while it was executing. This information can show you which pieces of your program are slower than you expected, and might be candidates for rewriting to make your program execute faster. It can also tell you which functions are being called more or less often than you expected. This may help you spot bugs that had otherwise been unnoticed.
Be sure to check out the man pages and other many guides out there that explain how to use it (no need for me to reinvent the wheel).
Posted by Derek@TheDailyLinux »
1 Comment »
Here is a method that will allow you to essentially merge elements of an array into a single variable and then back again in c.
unsigned char mac_addr[6];
long long int x;
x = mac_addr[0] << 40;
x |= mac_addr[1] << 32;
x |= mac_addr[2] << 24;
x |= mac_addr[3] << 16;
x |= mac_addr[4] << 8;
x |= mac_addr[5];
mac_addr[0] = x >> 40;
mac_addr[1] = x >> 32;
mac_addr[2] = x >> 24;
mac_addr[3] = x >> 16;
mac_addr[4] = x >> 8;
mac_addr[5] = x;
You could probably take it a step further and throw it into a loop of sorts. If you have another solution, feel free to share it in the comments below!
Posted by Derek@TheDailyLinux »
Add Comment »
If you utilize the rt2501usb chipset (rt73 driver) and are connect to your wireless LAN using WPA2 encryption, then you may have noticed a flurry of messages showing up in your syslog or dmesg output, filling up you logs:
[ 1321.830000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1323.980000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1328.170000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1330.480000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1332.990000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1337.060000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
It seems to me that these are simply status/debugging messages and don’t serve much of a purpose other than fillings up the logs with information that’s not all that valuable to an end-user. The connection still works, so it doesn’t seem out of line to simply comment out the offending lines in the source code. If you don’t have the source code already, then you’ll need to goto RaLink and download them. There are readme files that will help you compile from scratch. When you have the source code, simply use grep to find the messages:
grep -rn "ReqVarIEs with CipherTmp"
You should find that the lines occur in the assoc.c file at line 348 and line 402. Comment these lines out and recompile. After this, your logs will be scotch-free of all those messages.
Posted by Derek@TheDailyLinux »
2 Comments »
The following is a very introductory guide to cross compiling a simple C++ program targeted towards an ARM platform. Development environments differ greatly, but for the most part, they all follow similar steps like outlined below. The very first step is to obtain a cross compile toolchain. CodeSourcery has a free, lite gcc toolchain available for download (as mentioned in a previous post). Once you download an appropriate toolchain for your target, you’ll need to extract it on your development host machine. You’ll notice a directory structure similar to opt/crosstool/gcc-4.0.1-glibc-2.3.5/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu- which is what we’ll use here.
[Read more →]