XDA-Developers came up with another fantastic Android hacking resource: XDA-University
Monthly Archives: December 2012
Quick git patch commands
As always, git has many more options…
Creating a git patch is very similar to SVN.
$ git diff [commit-id-before] [commit-id-after] > my.patch
format-patch
is a command to create ready-to-send patches. One commit is created in one file. To extract the three topmost commits from the current branch:
$ git format-patch -3
To extract patches from a range of commits:
$ git format-patch commit-id-start..commit-id-end
To extract patches since a commit:
$ git format-patch commit-id
Note: In the latter case, this extracts patches since the commit-id excluded.
Applying a patch
Test the patch:
git apply --check my.patch
Finally, sign it off:
git am --signoff < my.patch
More nice git usage examples can be found in Git memo.
Quick SVN patch commands
Create an SVN patch
svn diff > my.patch
And to apply a patch (after inspecting it!)
patch -p0 -i my.patch
Latitude and Longitude – UTM conversion
Geographic/UTM Coordinate Converter is a great tool for converting from Latitude and Longitude to UTM and vice versa. Some time ago, I had to automate some conversions and I rewrote the javascript code from that website in python.
Sample usage
import latlonutm as ll [[northing, easting], zone, hemi] = ll.LatLonToUtm(lat, lon) [lat, lon] = ll.UtmToLatLon(northing, easting, zone, southhemi)
Implementation
''' This module converts between lat long and UTM coordinates. Geographic coordinates are entered and displayed in degrees. Negative numbers indicate West longitudes and South latitudes. UTM coordinates are entered and displayed in meters. The ellipsoid model used for computations is WGS84. Usage: import latlonutm as ll [[northing, easting], zone, hemi] = ll.LatLonToUtm(lat, lon) [lat, lon] = ll.UtmToLatLon(northing, easting, zone, southhemi) Converted from javascript by Nenad Uzunovic Original source http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html ''' import math # Ellipsoid model constants (actual values here are for WGS84) sm_a = 6378137.0; sm_b = 6356752.314; sm_EccSquared = 6.69437999013e-03; UTMScaleFactor = 0.9996; def DegToFloat(degrees, minutes, seconds): ''' Converts angle in format deg,min,sec to a floating point number ''' if (degrees>=0): return (degrees) + (minutes/60.0) + (seconds/3600.0) else: return (degrees) - (minutes/60.0) - (seconds/3600.0) def DegToRad(deg): ''' Converts degrees to radians. ''' return (deg / 180.0 * math.pi); def RadToDeg(rad): ''' Converts radians to degrees. ''' return (rad / math.pi * 180.0); def ArcLengthOfMeridian(phi): ''' Computes the ellipsoidal distance from the equator to a point at a given latitude. Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. Inputs: phi - Latitude of the point, in radians. Globals: sm_a - Ellipsoid model major axis. sm_b - Ellipsoid model minor axis. Outputs: The ellipsoidal distance of the point from the equator, in meters. ''' # Precalculate n n = (sm_a - sm_b) / (sm_a + sm_b); # Precalculate alpha alpha = ((sm_a + sm_b) / 2.0) * (1.0 + (math.pow (n, 2.0) / 4.0) + (math.pow (n, 4.0) / 64.0)); # Precalculate beta beta = (-3.0 * n / 2.0) + (9.0 * math.pow (n, 3.0) / 16.0) + (-3.0 * math.pow (n, 5.0) / 32.0); # Precalculate gamma gamma = (15.0 * math.pow (n, 2.0) / 16.0) + (-15.0 * math.pow (n, 4.0) / 32.0); # Precalculate delta delta = (-35.0 * math.pow (n, 3.0) / 48.0) + (105.0 * math.pow (n, 5.0) / 256.0); # Precalculate epsilon epsilon = (315.0 * math.pow (n, 4.0) / 512.0); # Now calculate the sum of the series and return result = alpha * (phi + (beta * math.sin (2.0 * phi)) + (gamma * math.sin (4.0 * phi)) + (delta * math.sin (6.0 * phi)) + (epsilon * math.sin (8.0 * phi))); return result; def UTMCentralMeridian(zone): ''' Determines the central meridian for the given UTM zone. Inputs: zone - An integer value designating the UTM zone, range [1,60]. Outputs: The central meridian for the given UTM zone, in radians, or zero if the UTM zone parameter is outside the range [1,60]. Range of the central meridian is the radian equivalent of [-177,+177]. ''' return DegToRad(-183.0 + (zone * 6.0)); def FootpointLatitude(y): ''' Computes the footpoint latitude for use in converting transverse Mercator coordinates to ellipsoidal coordinates. Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. Inputs: y - The UTM northing coordinate, in meters. Outputs: The footpoint latitude, in radians. ''' # Precalculate n (Eq. 10.18) n = (sm_a - sm_b) / (sm_a + sm_b); # Precalculate alpha_ (Eq. 10.22) # (Same as alpha in Eq. 10.17) alpha_ = ((sm_a + sm_b) / 2.0) * (1 + (math.pow (n, 2.0) / 4) + (math.pow (n, 4.0) / 64)); # Precalculate y_ (Eq. 10.23) y_ = y / alpha_; # Precalculate beta_ (Eq. 10.22) beta_ = (3.0 * n / 2.0) + (-27.0 * math.pow (n, 3.0) / 32.0) + (269.0 * math.pow (n, 5.0) / 512.0); # Precalculate gamma_ (Eq. 10.22) gamma_ = (21.0 * math.pow (n, 2.0) / 16.0) + (-55.0 * math.pow (n, 4.0) / 32.0); # Precalculate delta_ (Eq. 10.22) delta_ = (151.0 * math.pow (n, 3.0) / 96.0) + (-417.0 * math.pow (n, 5.0) / 128.0); # Precalculate epsilon_ (Eq. 10.22) epsilon_ = (1097.0 * math.pow (n, 4.0) / 512.0); # Now calculate the sum of the series (Eq. 10.21) result = y_ + (beta_ * math.sin (2.0 * y_)) + (gamma_ * math.sin (4.0 * y_)) + (delta_ * math.sin (6.0 * y_)) + (epsilon_ * math.sin (8.0 * y_)); return result; def MapLatLonToXY(phi, lambda_pt, lambda_ctr): ''' Converts a latitude/longitude pair to x and y coordinates in the Transverse Mercator projection. Note that Transverse Mercator is not the same as UTM; a scale factor is required to convert between them. Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. Inputs: phi - Latitude of the point, in radians. lambda_pt - Longitude of the point, in radians. lambda_ctr - Longitude of the central meridian to be used, in radians. Outputs: xy - A 2-element array containing the x and y coordinates of the computed point. ''' # Precalculate ep2 ep2 = (math.pow (sm_a, 2.0) - math.pow (sm_b, 2.0)) / math.pow (sm_b, 2.0); # Precalculate nu2 nu2 = ep2 * math.pow (math.cos (phi), 2.0); # Precalculate N N = math.pow (sm_a, 2.0) / (sm_b * math.sqrt (1 + nu2)); # Precalculate t t = math.tan (phi); t2 = t * t; # tmp = (t2 * t2 * t2) - math.pow (t, 6.0); # Precalculate l l = lambda_pt - lambda_ctr; # Precalculate coefficients for l**n in the equations below # so a normal human being can read the expressions for easting # and northing # -- l**1 and l**2 have coefficients of 1.0 l3coef = 1.0 - t2 + nu2; l4coef = 5.0 - t2 + 9 * nu2 + 4.0 * (nu2 * nu2); l5coef = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * nu2 - 58.0 * t2 * nu2; l6coef = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * nu2 - 330.0 * t2 * nu2; l7coef = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2); l8coef = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2); # Calculate easting (x) xy = [0.0, 0.0] xy[0] = N * math.cos (phi) * l + (N / 6.0 * math.pow (math.cos (phi), 3.0) * l3coef * math.pow (l, 3.0)) + (N / 120.0 * math.pow (math.cos (phi), 5.0) * l5coef * math.pow (l, 5.0)) + (N / 5040.0 * math.pow (math.cos (phi), 7.0) * l7coef * math.pow (l, 7.0)); # Calculate northing (y) xy[1] = ArcLengthOfMeridian (phi) + (t / 2.0 * N * math.pow (math.cos (phi), 2.0) * math.pow (l, 2.0)) + (t / 24.0 * N * math.pow (math.cos (phi), 4.0) * l4coef * math.pow (l, 4.0)) + (t / 720.0 * N * math.pow (math.cos (phi), 6.0) * l6coef * math.pow (l, 6.0)) + (t / 40320.0 * N * math.pow (math.cos (phi), 8.0) * l8coef * math.pow (l, 8.0)); return xy; def MapXYToLatLon(x, y, lambda_ctr): ''' Converts x and y coordinates in the Transverse Mercator projection to a latitude/longitude pair. Note that Transverse Mercator is not the same as UTM; a scale factor is required to convert between them. Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. Inputs: x - The easting of the point, in meters. y - The northing of the point, in meters. lambda_ctr - Longitude of the central meridian to be used, in radians. Outputs: philambda - A 2-element containing the latitude and longitude in radians. Remarks: The local variables Nf, nuf2, tf, and tf2 serve the same purpose as N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect to the footpoint latitude phif. x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and to optimize computations. ''' # Get the value of phif, the footpoint latitude. phif = FootpointLatitude (y); # Precalculate ep2 ep2 = (math.pow (sm_a, 2.0) - math.pow (sm_b, 2.0)) / math.pow (sm_b, 2.0); # Precalculate cos (phif) cf = math.cos (phif); # Precalculate nuf2 nuf2 = ep2 * math.pow (cf, 2.0); # Precalculate Nf and initialize Nfpow Nf = math.pow (sm_a, 2.0) / (sm_b * math.sqrt (1 + nuf2)); Nfpow = Nf; # Precalculate tf tf = math.tan (phif); tf2 = tf * tf; tf4 = tf2 * tf2; # Precalculate fractional coefficients for x**n in the equations # below to simplify the expressions for latitude and longitude. x1frac = 1.0 / (Nfpow * cf); Nfpow *= Nf; # now equals Nf**2) x2frac = tf / (2.0 * Nfpow); Nfpow *= Nf; # now equals Nf**3) x3frac = 1.0 / (6.0 * Nfpow * cf); Nfpow *= Nf; # now equals Nf**4) x4frac = tf / (24.0 * Nfpow); Nfpow *= Nf; # now equals Nf**5) x5frac = 1.0 / (120.0 * Nfpow * cf); Nfpow *= Nf; # now equals Nf**6) x6frac = tf / (720.0 * Nfpow); Nfpow *= Nf; # now equals Nf**7) x7frac = 1.0 / (5040.0 * Nfpow * cf); Nfpow *= Nf; # now equals Nf**8) x8frac = tf / (40320.0 * Nfpow); # Precalculate polynomial coefficients for x**n. # -- x**1 does not have a polynomial coefficient. x2poly = -1.0 - nuf2; x3poly = -1.0 - 2 * tf2 - nuf2; x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2 - 3.0 * (nuf2 *nuf2) - 9.0 * tf2 * (nuf2 * nuf2); x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2; x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2 + 162.0 * tf2 * nuf2; x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2); x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2); # Calculate latitude philambda = [0.0, 0.0] philambda[0] = phif + x2frac * x2poly * (x * x) + x4frac * x4poly * math.pow (x, 4.0) + x6frac * x6poly * math.pow (x, 6.0) + x8frac * x8poly * math.pow (x, 8.0); # Calculate longitude philambda[1] = lambda_ctr + x1frac * x + x3frac * x3poly * math.pow (x, 3.0) + x5frac * x5poly * math.pow (x, 5.0) + x7frac * x7poly * math.pow (x, 7.0); return philambda def LatLonToUTMXY(lat, lon, zone): ''' Converts a latitude/longitude pair to x and y coordinates in the Universal Transverse Mercator projection. Inputs: lat - Latitude of the point, in radians. lon - Longitude of the point, in radians. zone - UTM zone to be used for calculating values for x and y. If zone is less than 1 or greater than 60, the routine will determine the appropriate zone from the value of lon. Outputs: xy - A 2-element array where the UTM x and y values will be stored. ''' xy = MapLatLonToXY(lat, lon, UTMCentralMeridian(zone)); # Adjust easting and northing for UTM system. xy[0] = xy[0] * UTMScaleFactor + 500000.0; xy[1] = xy[1] * UTMScaleFactor; if (xy[1] < 0.0): xy[1] = xy[1] + 10000000.0; return xy; def UTMXYToLatLon(x, y, zone, southhemi): ''' Converts x and y coordinates in the Universal Transverse Mercator projection to a latitude/longitude pair. Inputs: x - The easting of the point, in meters. y - The northing of the point, in meters. zone - The UTM zone in which the point lies. southhemi - True if the point is in the southern hemisphere; false otherwise. Outputs: latlon - A 2-element array containing the latitude and longitude of the point, in radians. ''' x -= 500000.0; x /= UTMScaleFactor; # If in southern hemisphere, adjust y accordingly. if (southhemi): y -= 10000000.0; y /= UTMScaleFactor; cmeridian = UTMCentralMeridian(zone); latlon = MapXYToLatLon(x, y, cmeridian); return latlon def LatLonToUtm(lat, lon): ''' Converts lat lon to utm Inputs: lat - lattitude in degrees lon - longitude in degrees Outputs: xy - utm x(easting), y(northing) zone - utm zone hemi - 'N' or 'S' ''' if ((lon < -180.0) or (180.0 <= lon)): print 'The longitude you entered is out of range -', lon print 'Please enter a number in the range [-180, 180).' return 0 if ((lat < -90.0) or (90.0 < lat)): print 'The latitude you entered is out of range -', lat print 'Please enter a number in the range [-90, 90].' # Compute the UTM zone. zone = math.floor ((lon + 180.0) / 6) + 1; # Convert xy = LatLonToUTMXY (DegToRad(lat), DegToRad(lon), zone); # Determine hemisphere hemi = 'N' if (lat < 0): hemi = 'S' return [xy, zone, hemi] def UtmToLatLon(x, y, zone, hemi): ''' Converts UTM coordinates to lat long Inputs: x - easting (in meters) y - northing (in meters) zone - UTM zone hemi - 'N' or 'S' Outputs: latlong - [lattitude, longitude] (in degrees) ''' if ((zone < 1) or (60 < zone)): print 'The UTM zone you entered is out of range -', zone print 'Please enter a number in the range [1, 60].' return 0 if ((hemi != 'N') and (hemi != 'S')): print 'The hemisphere you entered is wrong -', hemi print 'Please enter N or S' southhemi = False if (hemi == 'S'): southhemi = True # Convert latlon = UTMXYToLatLon(x, y, zone, southhemi) # Convert to degrees latlon[0] = RadToDeg(latlon[0]) latlon[1] = RadToDeg(latlon[1]) return latlon
Hopefully somebody finds it useful.
Linux Scheduler
Mainline linux kernel distribution received a number of real-time additions over that last few years. More details on OASDL site. Here is my small experiment with a program that changes it’s own scheduling policy and example on how to see traced kernel events using ftrace.
Example below shows how to change scheduling policy from within the program itself. Note, if the scheduling policy does not change at runtime a perhaps cleaner and easier solution is provided via schedtool
(command line tool).
#include <sched.h> #include <stdio.h> #include <unistd.h> const char * ParsePolicy(int policy) { switch (policy){ case SCHED_FIFO : return "SCHED_FIFO"; case SCHED_RR : return "SCHED_RR"; case SCHED_OTHER : return "SCHED_OTHER"; case SCHED_BATCH : return "SCHED_BATCH"; default : return "Did not recognize policy"; } } int GetPolicy() { int policy = sched_getscheduler(0); if (policy == -1){ perror(__FUNCTION__); return -1; } fprintf(stdout, "%s - %sn", __FUNCTION__, ParsePolicy(policy)); return policy; } int SetPolicy(int policy) { pid_t pid = getpid(); fprintf(stdout, "pid = %dn", (int)pid); fprintf(stdout, "%s - %sn", __FUNCTION__, ParsePolicy(policy)); struct sched_param param; param.sched_priority = sched_get_priority_max(policy); fprintf(stdout, "max priority = %dn", param.sched_priority); int setsch = sched_setscheduler(pid, policy, &param); if (setsch == -1) perror(__FUNCTION__); return setsch; // 0 - OK, -1 - fail } long long BusyWait(long long cycles) { while(cycles) cycles--; return cycles; } int main() { GetPolicy(); long long wait = 200000000; SetPolicy(SCHED_FIFO); GetPolicy(); BusyWait(wait); SetPolicy(SCHED_RR); GetPolicy(); BusyWait(wait); SetPolicy(SCHED_OTHER); GetPolicy(); BusyWait(wait); SetPolicy(SCHED_BATCH); GetPolicy(); BusyWait(wait); return 0; }
Since the program uses a simple while counter as a busy wait, you need to compile it without optimization flags.
gcc -Wall -O0 test_schedule.c -o test_schedule
Now, in order to actually see what is happenning under the hood, we use ftrace
(tracing functionality built-in in most newer kernels), trace-cmd
, and kernelshark
. These packages are in default Ubuntu repositories and can be installed with "sudo apt-get install trace-cmd kernelshark"
.
trace-cmd
has many useful options. I suggest reading the man page. In this case, I will show a simple use case for the example above. We will run trace command that will execute the scheduler test from above and store scheduling info.
sudo trace-cmd record -e sched ./test_schedule
This command saves trace.dat
, and shows output that looks like this:
$ sudo trace-cmd record -e sched ./test_schedule disable all enable sched path = /sys/kernel/debug/tracing/events/sched/enable path = /sys/kernel/debug/tracing/events/*/sched/enable GetPolicy - SCHED_OTHER pid = 10628 SetPolicy - SCHED_FIFO max priority = 99 GetPolicy - SCHED_FIFO pid = 10628 SetPolicy - SCHED_RR max priority = 99 GetPolicy - SCHED_RR pid = 10628 SetPolicy - SCHED_OTHER max priority = 0 GetPolicy - SCHED_OTHER pid = 10628 SetPolicy - SCHED_BATCH max priority = 0 GetPolicy - SCHED_BATCH offset=535000 offset=575000 offset=700000 offset=886000 offset=9ea000 offset=9f9000 offset=b57000 offset=cbc000 Kernel buffer statistics: Note: "entries" are the entries left in the kernel ring buffer and are not recorded in the trace data. They should all be zero. CPU: 0 entries: 0 overrun: 0 commit overrun: 0 bytes: 2708 oldest event ts: 274629.435366 now ts: 274630.751883 CPU: 1 entries: 0 overrun: 0 commit overrun: 0 bytes: 2620 oldest event ts: 274630.577012 now ts: 274630.752018 CPU: 2 entries: 0 overrun: 0 commit overrun: 0 bytes: 1056 oldest event ts: 274630.581643 now ts: 274630.752128 CPU: 3 entries: 0 overrun: 0 commit overrun: 0 bytes: 3020 oldest event ts: 274630.578163 now ts: 274630.752241 CPU: 4 entries: 0 overrun: 0 commit overrun: 0 bytes: 3872 oldest event ts: 274630.514477 now ts: 274630.752359 CPU: 5 entries: 0 overrun: 0 commit overrun: 0 bytes: 1728 oldest event ts: 274630.579316 now ts: 274630.752472 CPU: 6 entries: 0 overrun: 0 commit overrun: 0 bytes: 852 oldest event ts: 274630.581604 now ts: 274630.752558 CPU: 7 entries: 0 overrun: 0 commit overrun: 0 bytes: 2300 oldest event ts: 274630.574664 now ts: 274630.752643
trace.dat
is a file readable by kernelshark
If we start kernelshark
in the same directory, it will automatically open trace.dat
and we can closely analyze events that happened during this run.
Useful links:
Long lines in emacs
“Modes such as AutoFillMode insert a line ending after the last word that occurs before the value of option 'fill-column'
(a column number).”
“Besides relying on this fill-as-you-type behavior, you can manually fill an existing paragraph with command 'fill-paragraph'
('M-q'
). Instead of wrapping a single line around to the next window line, the line is divided into two separate lines, separated by a line ending.”
Source: EmacsWiki: Line Wrap
CMake Experiences
Content is stored in CMakeLists.txt
Need to specify minimum version:
cmake_minimum_required(VERSION 2.6)
Specify project name:
project(Tutorial)
Find libraries using pkg-config
. First argument becomes variable prefix, last argument is the actual library name.
find_package(PkgConfig) pkg_check_modules(BULLET REQUIRED bullet)
Set CFLAGS
:
add_definitions(-g -Wall) # Set include dirs include_directories( ${BULLET_INCLUDE_DIRS} )
Add a program and link flags:
add_executable(TutorialApplication TutorialApplication.cc) target_link_libraries(TutorialApplication ${BULLET_LIBRARIES} )
Make uninstall can be implemented by following directions on CMake FAQ. Simple solution is to just remove files listed in install_manifest.txt
like this:
xargs rm < install_manifest.txt
BASH_SOURCE
BASH_SOURCE
variable is a LIFO stack of scripts that are currently being called.
From official documentation:
BASH_SOURCE
An array variable whose members are the source filenames where the corresponding shell function names in theFUNCNAME
array variable are defined. The shell function${FUNCNAME[$i]}
is defined in the file${BASH_SOURCE[$i]}
and called from${BASH_SOURCE[$i+1]}
This functionality combined with readlink -f
creates useful combination that can make writing scripts less prone to relative path errors.
Example:
Script aaa.sh
#!/bin/bash echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}" source bbb.sh
Script bbb.sh
#!/bin/bash echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}" source ccc.sh
Script ccc.sh
#!/bin/bash echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}" for i in ${BASH_SOURCE[@]}; do readlink -f $i done
Running script aaa.sh
provides ouput that looks like this:
from aaa.sh : BASH_SOURCE = aaa.sh
from bbb.sh : BASH_SOURCE = bbb.sh aaa.sh
from ccc.sh : BASH_SOURCE = ccc.sh bbb.sh aaa.sh
/tmp/ccc.sh
/tmp/bbb.sh
/tmp/aaa.sh
Simple Makefile
Sometimes when I am building simple examples and/or learning new pieces of software I find it useful to have a quick and dirty Makefile handy. Here is my example:
CXXFLAGS = -g -Wall
LDFLAGS = -pthread
.phony : default clean all
default : all
clean :
rm -vf *.o $(PROGRAMS)
define ADD_PROGRAM # template
PROGRAMS += $(1)
all : $(1)
$(1) : $(2)
g++ -o $$@ $$^ $(LDFLAGS)
endef # end ADD_PROGRAM
$(eval $(call ADD_PROGRAM,example,example.o))
The reason I like this Makefile is because template implementation makes it cleaner to add more programs to the mix. Also, it keeps track of all the programs that are built and cleans them up properly. Basically, it saves me a few copy and pastes…