Saturday, October 23, 2010

And that’s a wrap

After spending the entire day Thursday implementing the scuba computer, we found out Friday morning that the use of a real-time operating system (RTOS) to implement it was overkill.

I shouldn’t really be surprised; at my work I have worked on projects of much greater complexity without needing an RTOS.  The reality is, is that there is a continuum between hard real-time and soft real-time, along which most embedded systems fall, and using an RTOS may bring more disadvantages than advantages. 

Specifically when you have a priority scheme allowing a high priority task to snatch the processor away from a lower priority task it leads to a number of complicated problems regarding sharing the processor’s resources.  If a low priority task is using the serial port for example, and a high priority task takes over and wants to use the serial port, it could lead to corruption of the serial port data.  Tasks need to play nice and share the processors peripherals in a manor that won’t lead to corruption, while at the same time ensuring that the high priority tasks meet their time constraints. 

Now these problems have all been addressed in the design of modern RTOS’s but these solutions are not free, they require processor time, resulting in a lot of overhead that simply isn’t required if an RTOS is not used.

So Friday’s lecture was about RTOS alternatives, and it turns out that there are quite a few.  Specifically we talked about the following:

  1. Big loop + interrupt systems
  2. Cyclic executive systems
  3. Co-routine systems
  4. Proto-thread systems
  5. Function Queue systems
  6. State-machine systems

I don’t have time to touch on them here but from my perspective I have used 1, 5 and 6 to some extent.

State-machine programming is the topic that I want to discuss today, because more than all of the others it really is an entirely different programming paradigm.

What I mean by a paradigm is both the style of programming used, and subsequently the thought processes used to break down a problem.

There are many different programming paradigms, the most common being:  procedural, functional, parallel, and object-oriented.

Traditional embedded programming is entirely procedural with some parallel programming concept thrown in when using an RTOS.

State-machine programming is something a little different.  In has a correlation with the desktop world where it goes by the name of event-driven programming.  For example in Windows if you are writing an application you might draw a nice little button using the graphical tools Windows supplies and then you program the code to handle all the possible events that might happen to that button.  Specifically you would tell the computer what to do if a user clicked on the button.

In the embedded world you can design a system in a somewhat similar way.  Using our scuba computer as an example we could define some states that our system might be in.  They might be:

  • At the surface with no oxygen
  • At the surface with oxygen
  • Decending  with sufficient oxygen to reach the surface
  • Ascending with sufficient oxygen to reach the surface
  • Decending  without sufficient oxygen to reach the surface
  • Ascending without sufficient oxygen to reach the surface
  • Below the surface at a depth of greater than 40m
  • Ascending faster than 15m per minute

These are the system states.  We then also would define the possible events that could occur.  Some may be:

  • Oxygen is added.
  • Oxygen is depleted
  • Ascending
  • Descending

We then program the system to change state depending on each event that might occur.  For example if we are in the “at the surface with no oxygen” state and then oxygen is added, our new state would be at the surface with oxygen.  If instead the “descending” event occurred without adding oxygen, our state would be “descending without sufficing oxygen to reach the surface”.  Also not all events would be handled by each state.  If we are at the surface we would simply ignore the ascending event.  Also some events might just keep us in the current state.  If we are descending, a descending event wouldn’t change our state unless at the same time we ran low on oxygen or we exceeded the maximum depth.

It might not be immediately obvious to the non-programmer, but this way of thinking about a system is very different from the usual procedural way of thinking, when we instruct the computer to first do one then then do another.  Now the program literally does nothing until an event triggers it to do something.  Then with each event we might do something as we leave a state, do something as we transition between states and then maybe do something upon entering a new state.  Once this was done we then sit and spin in the new state doing nothing but waiting for the next event.  To my mind this is a fascinating way to look at a whole set of problems that I face day in and day out as an embedded programmer.

I wasn’t unfamiliar with these techniques before the course, but certainly now having had them refreshed I feed much more capable as an embedded programmer and ready to tackle the next problem that my employer sends my way.

Thursday, October 21, 2010

Coming up for air

Well that was fun.

Today we had no lecture, instead the entire day was devoted to a team project.  Specifically we designed and implemented the software for a scuba diving computer.  Something that would look like this.

dive computer

Our hardware actually looked like this, but the functionality was much the same.

board

We worked in teams of 4 to develop the software required to do the following.

1 - Show ascent-rate, depth, oxygen remaining, elapsed dive time and time to surface on the display.

2 - Sound one of three alarms.

  • High priority alarm if there is not enough oxygen in the tanks to reach the surface.
  • Medium priority alarm if the rate of ascent is greater than 15 meters per minute (prevents getting the bends).
  • Low priority alarm if your depth is greater than 40 meters.

3 – Toggle the display between showing the elapsed time, and the time to surface every 2 seconds.

This is why I love being an engineer; you get to build really cool things.  As an aside our team was the only one to finish the project.  We finished it 5 minutes before the deadline.  Whew…

To complete the project our design used 8 tasks.

  • LED driver task
  • Pushbutton driver task
  • Speaker driver task
  • Analog to digital converter driver task
  • Calculation task
  • Display task
  • Alarm task
  • Watchdog monitoring task

As a point of interest I have included below some of the code that I worked on today which did the calculations for the displayed values.  Probably not the most elegant code since we were under a time constraint, but it shows the proper use of several forms of inter-task communication.  Enjoy.

/***********************************************************
DIVE COMPUTER CALCULATION TASK
***********************************************************/
void AppTaskCalc(void * pdata)
{
   INT16S         rate_of_ascent_in_mpm = 0;
   INT16U         elapsed_time_in_s = 0;
   INT32S         depth_in_mm = 0;
   INT32S         air_supply_in_cl = 0;
   OS_FLAGS       flags;
   INT8U          err;
   INT16U         sample;
   INT16U         tick_counter = 0;
   INT16U         air_to_surface_in_cl;
   INT32U         alarm_curr = GF_ALARM_OFF;
   INT8U          at_surface = 1;

   static display_data_t display_data = {0,0,0,0,0}; 

   while(1)
   {
      flags = OSFlagPend(gh_sys_flags, GF_TIME_CALC |
              GF_BUTTON_AIR, OS_FLAG_WAIT_SET_ANY |
              OS_FLAG_CONSUME, 0, &err);
      assert(OS_NO_ERR == err);   
     
      if (flags & GF_TIME_CALC)
      {
         tick_counter++;
         // Pend on the A2D mailbox
         sample = (*(INT16U *) OSMboxPend(ghMboxAdc,
                                          10, &err));
         assert(OS_NO_ERR == err || OS_TIMEOUT == err);
        
         // Calculate the rate of ascent
         rate_of_ascent_in_mpm = sample - 511;
         rate_of_ascent_in_mpm /= 13;
         depth_in_mm -= depth_change_in_mm(
                                  rate_of_ascent_in_mpm);
         if(depth_in_mm <= 0)
         {
            depth_in_mm = 0;
            at_surface = 1;
         }

         // Calculate the elapsed time if depth is not 0
         if (depth_in_mm != 0)
         {
            if (at_surface == 1)
            {
               at_surface = 0;
               elapsed_time_in_s = 0;
            }
            if(tick_counter & 0x01)
            {
               // Every other .5s tick increment
               //   the elapsed time
               elapsed_time_in_s++;
            }
         }

         if(at_surface == 0)
         {
            air_supply_in_cl -= gas_rate_in_cl(
                                   depth_in_mm / 1000);
            if(air_supply_in_cl < 0)
            {
               air_supply_in_cl = 0;
            }
         }
         air_to_surface_in_cl = gas_to_surface_in_l(
                                   depth_in_mm / 1000);
         // Update display_data struct
         if(at_surface == 1)
         {
            display_data.rate_of_ascent_in_mpm = 0;
         }
         else
         {
            display_data.rate_of_ascent_in_mpm =
                                      rate_of_ascent_in_mpm;
         }
         display_data.depth_in_m = depth_in_mm / 1000;
         display_data.air_supply_in_cl = air_supply_in_cl;
         display_data.elapsed_time_in_s = elapsed_time_in_s;
        
         // Maximum ascent rate is 0.25m / s
         display_data.time_to_surface_in_s =
                          display_data.depth_in_m * 4;

         err = OSMboxPost(ghMboxCalc, &display_data);
         assert(OS_NO_ERR == err);
        
         OSFlagPost(gh_sys_flags, GF_MBOX_DISP,
                                        OS_FLAG_SET, &err);
         assert(OS_NO_ERR == err);
        
         // Set current alarm state.
         if(at_surface == 1)
         {
            alarm_curr = GF_ALARM_OFF;
         }
         else if (air_supply_in_cl < air_to_surface_in_cl)
         {
            alarm_curr = GF_ALARM_HI;
         }
         else if (15 < rate_of_ascent_in_mpm)
         {
            alarm_curr = GF_ALARM_MID;
         }
         else if (40 < (depth_in_mm / 1000))
         {
            alarm_curr = GF_ALARM_LOW;
         }
         else
         {
            alarm_curr = GF_ALARM_OFF;
         }

         // Signal change of speaker priority to the alarm
         OSFlagPost(gh_sys_flags, alarm_curr,
                                      OS_FLAG_SET, &err);
         assert(OS_NO_ERR == err);
      }
     
      if (flags & GF_BUTTON_AIR)
      {
         // Increment the air count at 5L per semaphore
         do
         {
            // Wait for a signal from the button driver
            OSSemPend(ghSemB1, 10, &err);
            assert(OS_NO_ERR == err || OS_TIMEOUT == err);
            if ((OS_NO_ERR == err) && (at_surface == 1))
            {
               if (air_supply_in_cl <= 199500)
               {
                  air_supply_in_cl += 500;
               }
               else if (air_supply_in_cl < 200000)
               {
                  air_supply_in_cl = 200000;
               }
            }
         }while (OS_NO_ERR == err);
      }
      // tell watchdog we are alive
      OSFlagPost(gh_sys_flags, GF_ALIVE_CALC,
                                       OS_FLAG_SET, &err);
      assert(OS_NO_ERR == err);     
   }
}

Wednesday, October 20, 2010

Rate Monotonic Analysis

Say what?

Yes that is right, this mornings lecture covered the fascinating subject of rate monotonic analysis.

I say that somewhat in jest, but it actually was a fascinating subject.

Here is the problem.

Given a given set of tasks that an RTOS wants to schedule, what is the appropriate priority level for each task?  Further more can we guarantee that all time constraints can be met?

Now I didn’t talk about task priorities in yesterday’s post, but in a true RTOS, tasks which are deemed to have a higher priority will always get access to the resources of the processor over any lower priority task.  This is necessary if we are to meet the real time constraints of an embedded system.

Going back to the problem statement though, if we have a dozen tasks or more, each of which has a real time constraint, how do we decide which priority to give to each task, and can we always be sure that the time constraints will be met.  Well rate monotonic analysis can provide the answer for us.

In order to do this analysis we need to know 3 main things about the embedded system.

  1. How many tasks are there.
  2. What is each task’s time constraint; how often must it get access to the processor
  3. What is each task’s worst case time for how long it needs access to the processor

Once we have this information we can simply follow the following steps.

  1. Assign task priorities based on each task’s time constraint.  The task which has the shortest time constraint has the highest priority.  That was easy.
  2. Multiply each time constraint by its worst case execution time to get the CPU utilization for that each task.  This is actually quite hard to calculate.
  3. Add up all the utilizations to determine the total processor utilization.

Now if the answer to 3 is greater than 100% we know that it is impossible to schedule the events so that all the tasks time constraints can be met.  It is time to buy a faster processor, or improve the code to speed up the tasks.

The question now becomes if the overall processor utilization is less than 100% do we guarantee all time constraints can be met?

The answer is no.  In order to guarantee all time constraints are met the maximum processor utilization turns out to be the equation:  n * (2^(1/n) – 1), where n is the number of tasks.

For one task we can obviously have 100% processor utilization.  For two tasks this drops to 82.8% processor utilization.  For three tasks it is 77.9% .  And for n as it grows the limit approaches 69.3% processor utilization.

This turns out to be very nice for the designer.  Regardless of how many tasks there are, and as long as priorities are assigned in order of time constraint, and as long as our processor utilization is less than 69% we are guaranteed that all time constraints can be met.

See didn’t I tell you.  Pretty cool stuff.

Tuesday, October 19, 2010

Multi-tasking

At the best of times, I am not much of a multi-tasker.  Let me concentrate on finishing one task well and I will be happy.  Give me six things to do at once and inevitably I will forget something.  Just thought that you should know that.

Today’s lesson was on programming in a multi-tasking environment.  Specifically within the framework of a real time operating system, or RTOS for short.

Windows is probably the operating system that most people are familiar with.  At its heart, the main thing that Windows does is co-ordinate the execution of all of the different programs (or tasks more correctly) that I might want to run. 

If I have my e-mail program running, and then I open my internet browser along with my media player, the operating system needs to ensure that each program is permitted access to the limited resources of the processor. 

Since generally there is only one processor and this processor can only do one thing at a time the operating system needs to decide how best to divide up the processors time.

Though it may look like each program is running at the same time, in reality this is an illusion.  The operating system actually divides time into slices and allows each program to run for the duration of a time slice, before switching to a different program.  The programs appear to be running concurrently because this time slice is so small that within a given second every program gets a chance to run many times.  Now this is an over simplification but I think you get the idea.

In the desktop software world you are probably aware of a few operating systems, Windows, Mac OSX, and Linux are far and away the most popular.  In the world of embedded programming things get more complicated.  Depending on the complexity of the embedded system a developer may or may not need an operating system.  Your smoke detector probably doesn’t use an operating system, but most assuredly your TVs and DVD players do.

When is an operating system required?  Well it is not a cut an dry question but certainly as the complexity of the device increases and the number of things it is required to do increases an operating system starts to become a necessity.

So is my DVD player running Windows?  Uh, … no.

Most embedded devices have an additional requirement that desktop computers generally do not have.  A real-time constraint.  Specifically when I want to do something, it needs to be done absolutely within a certain period of time.

Have you ever tried to do something in Windows and waited many seconds for it to respond to your command?  You sit there twiddleing your thumbs while Windows is busy doing something else in the background.  You have to wait for Windows to finish doing what it wants to do before you get any joy.

Now think about this.  How would you like it if the ABS braking system in your car were like that.  You press the brakes and your car decides that it is doing something more important at the time being and that it would get back to you when it was good an ready.

I think you can imagine the consequences.

In the embedded world very often there are hard time constraints for the system to perform a function.  In our example the user presses the brakes, so the ABS system had better be monitoring for wheel lock-ups hundreds if not thousands of times each and every second without fail.

As an aside this is another unique characteristic of embedded systems.  They have to be much more reliable then your typical desktop computer.  Have you have ever heard of a TV having a blue screen of death?  When was that last time you had to reboot your smoke detector?  Embedded systems need to work day in and day out for years on end without ever crashing.

So since embedded systems often have real time constraints, they usually can’t rely on the same operating system that is running your computer.  This is where a real time operating system comes in.

I mentioned the big 3 desktop operating systems, so what are the equivalent big 3 RTOSs for embedded systems?  Well it really isn’t that easy.  Since each and every embedded device has such differing requirements there are many different operating systems available.  Far too many to list here, and even if I did you probably would not have heard of them.  Also in many cases embedded programmers will write their own operating system, a feat unheard of in the desktop world, but quite doable by a single programmer on a small embedded device.

Now all that to get to this.  In today’s lecture we covered the following topics using the uc/OS-II operating system:  task creation, assigning task priorities, understanding how task switching works and guarding against race conditions between tasks.  I won’t go into the details but needless to say today was another interesting day at the embedded software boot camp.

Monday, October 18, 2010

And now for something a little different.

Today’s post finds me just outside of Baltimore Maryland.  I am blessed to be attending a course that is directly applicable to what I do each and every day at work.  It is the Embedded Software Boot Camp, and so far it is looking like it will meet and exceed my expectations. 

I have been on training before, but it has always been either soft-skills development (the 7 habits of highly effective people), or application specific development (ECAD software training).  Since my time as a student at the University of Waterloo, I haven't been on a course that was specifically to refresh and advance my technical skills.  Today that has changed and I thank my employer for giving me the opportunity to attend this week of  training.

Over the last few months my ramblings have been pretty much one dimensional for the reason that my faith is and will always be the most important aspect in my life.  I don’t intend to stop writing about it, but I am a multi-dimensional being and I want to augment those discussions with some thoughts regarding other interests that make me uniquely me.  This week I want to write a bit about what I am being taught at the course.  Those that are technically minded might find this interesting, while those that are not might want to stop reading right about now.

As a point of interest, today I learned that there were approximately 12 billion processors sold in 2009.  Leaving aside what a huge number that is, the interesting statistic is that less then 2% of those actually end up in the PCs and Macs that we have on our desks.  The other 98% of the processors sold end up in embedded devices.   Actually it shouldn’t be that surprising when you take the time to compare the number of computers kicking around your house versus the number of embedded devices.  Let me entertain you with my list.

I have one general purpose computer with a Pentium 4 processor in it.

As for embedded devices, here is a list which I am sure is not exhaustive.  I have a mouse, keyboard, monitor, printer, USB flash drivers x4, external hard drive, internal hard drive, floppy drive, pen tablet, optical drives x3, sound card, graphics card, Ethernet card, router, modem, DSL modem, digital camera x2, external flash, digital video camera, microwave, stove, fridge, stereo, TV, DVD player, receiver, VCR, digital watch, clock radio x3, blackberry, cell phone, iPod x3, eBook reader, car stereo x2, car DVD player, car GPS, multiple automobile subsystems, daughters toys (TAG readers x2, toy computer x2, alphabet pal,  fridge letter toy, at least 3-4 other infant toys that make music and flash lights), smoke detectors x4, CO2 detector, garage door opener, garage door remote x2, TV remote control, DVD remote, receiver remote, VCR remote, digital picture frame, baby monitor base station, baby monitor receivers x2, guitar tuner, etc.

All of these things have one thing in common.  They are all electronic devices containing both a processor and embedded software.

Today in the course we covered 2 main topics.  First we reviewed the intricacies of the C programming language and second we learned how to write software which communicated directly with hardware.

Knowledge of the C programming language is pretty much an absolute requirement for anyone wanting to write embedded software.  This is in contrast to programming for desktop computers which have many languages to choose from.  Another difference with embedded programming is that you don’t write the software on the device you are programming.  When programming a PC, you write the software using the PC.  When writing software for a DVD player however, you can’t write the software on the DVD player, you have to use what is called a cross-compiler.  In other words, you write the program on a PC using a cross-compiler which doesn’t create a executable for the Intel X86 processor, instead it creates a file specific to the processor you are using on your embedded device.  This file can be then programmed into the chip on the embedded device.

The second thing we covered was hardware interfacing.  Specifically how to use the C language to communicate with hardware and control its operation.  The exercise today was to write a device driver for an ARM processor that communicated with a timer.  I present my solution here… 

/***********************************************************
DESCRIPTION:
- STR912F Device Driver

***********************************************************/
#include <stdint.h>
#include <includes.h>
#include "timer.h"

// Macros
#define BIT0  (1 << 0)
#define BIT1  (1 << 1)
#define BIT2  (1 << 2)
#define BIT3  (1 << 3)
#define BIT4  (1 << 4)
#define BIT5  (1 << 5)
#define BIT6  (1 << 6)
#define BIT7  (1 << 7)
#define BIT8  (1 << 8)
#define BIT9  (1 << 9)
#define BIT10 (1 << 10)
#define BIT11 (1 << 11)
#define BIT12 (1 << 12)
#define BIT13 (1 << 13)
#define BIT14 (1 << 14)
#define BIT15 (1 << 15)

// Type definitions
typedef struct
{
   uint16_t IC1R;   // Input Capture Register 1
   uint16_t const pad1;
   uint16_t IC2R;   // Input Capture Register
   uint16_t const pad2;
   uint16_t OC1R;   // Output Compare Register 1
   uint16_t const pad3;
   uint16_t OC2R;   // Output Compare Register 2
   uint16_t const pad4;
   uint16_t CNTR;   // Counter Register
   uint16_t const pad5;
   uint16_t CR1;    // Control Register 1
   uint16_t const pad6;
   uint16_t CR2;    // Control R7egister 2
   uint16_t const pad7;
   uint16_t SR;     // Status Register
   uint16_t const pad8;
}TIMER_t;

typedef struct
{
   uint32_t CLKCNTR;
   uint32_t PLLCONF;
   uint32_t SYSSTATUS;
   uint32_t PWRMNG;
   uint32_t ITCMSK;
   uint32_t PCGR0;
   uint32_t PCGR1;
   uint32_t PRR0;
   uint32_t PRR1;
   uint32_t MGR0;
   uint32_t MGR1;
   uint32_t PECGR0;
   uint32_t PECGR1;
   uint32_t SCR0;
   uint32_t SCR1;
   uint32_t SCR2;
   // Other stuff I don’t care about
}SCU_t;

// Public Prototypes
void timer_init(void);
void timer_oneshot(uint16_t ms);
int timer_done_yet(void);

// Private Declarations
// Declare a read_only pointer to a volatile Timer structure
//   and set the pointer equal to the address 0x58002000
static TIMER_t volatile * const pTimer =
   (TIMER_t *) 0x58002000;
#define Timer (*pTimer)

// Declare a read_only pointer to a volatile System Control
//   Unit structure and set the pointer equal to the address
     0x58002000
static SCU_t volatile * const pSCU = (SCU_t *) 0x5C002000;
#define Scu (*pSCU)

/***********************************************************
FUNCTION: timer_init

DESCRIPTION:
- Initialize timer hardware

PARAMETERS:
- None

RETURNS:
- Void
***********************************************************/
void timer_init(void)
{
   Timer.CR1 &= (~BIT15);  // Stop the timer
   Timer.CR1 |= BIT0;      // Set the External Clock Enable
   Scu.SCR1 = 48000;       // Set the clock divisor
}

/***********************************************************
FUNCTION: timer_oneshot

DESCRIPTION:
- Starts the one shot timer

PARAMETERS:
- ms, number of milliseconds to run the timer for

RETURNS:
- Void
***********************************************************/
void timer_oneshot(uint16_t ms)
{
   uint16_t target;

   Timer.CR1 &= (~BIT15);        // Stop the timer
   Timer.CNTR = 1;               // Reset the counter
   Timer.SR &= (~BIT14);         // Reset the Compare Flag

   /* The PLL Configuration Register sets a master clock
      of 96 MHz.  This 96 MHz clock is divided by 48,000
      using SCU Configuration
Register 1, therefore the
      timer input clock is running at 2 KHz, so the number
      of clock ticks is 2x the desired number of
      milliseconds. 
Also, resetting the counter yields a
      bizarre initial value of 0xFFFC.  We have to adjust
      our target count to compensate for this.
   */

   if(ms > 0x8000)
   {
      // The number of ms requested was too large
      // set to maximum
      target = 0xFFFB;
   }
   else
   {
      target = 2 * ms;

      if(target == 0)
      {
         // Setup the timer to be minimum = 0.5ms
         target = 0xFFFD;
      }
      else if(target == 2)
      {
         // 1 ms delay requested; handle this special case.
         target = 0xFFFE;
      }
      else
      {
         // Set the timer compare value
         target =- 4;  
      }
   }
   Timer.OC1R = target;

   // Start the timer
   Timer.CR1 |= BIT15;          
}

/***********************************************************
FUNCTION: timer_done_yet

DESCRIPTION:
-  Checks to see if the one-shot timer is still running

PARAMETERS:
- None

RETURNS:
- 0 if the timer is still running
- 1 if the timer is done
***********************************************************/
int timer_done_yet(void)
{
   // If bit 14 (OCF1) is set we have reached the count
   if(Timer.SR & BIT14) 
   {
      return 1;
   }
   else
   {
      return 0;
   }
}

Monday, October 11, 2010

Counting My Blessings

1.  I am thankful today for each breath that I breathe.  Every day that I live is a gift from God.

2.  I am thankful today for each step that I take.  My health is a blessing I won’t take for granted.

3.  I am thankful today for the bride of my youth.  She has stood by me for 12 years, and I know that without her by my side, life would not be as blessed or fulfilled.

4,  I am thankful today for my children.  They bring me joy beyond measure.

5.  I am thankful today for my parents.  They are the reason that I am who I am today.

6.  I am thankful today for my extended family.  Though we may not be together all that often, the support of your prayers and the knowledge of your care gives me a confidence to face the world knowing that someone has my back.

7.  I am thankful today for my place of employment.  To be able to work at something that I love; that is a gift too few experience.

8.  I am thankful today for my community of believers.  To know that I am not alone in this life of faith, but that I am supported by so many others enables me to believe for greater things than I would ever believe for alone.

9.  I am thankful today for the daily provisions of my heavenly Father.  My needs have been met, I have never known want.

10.  I am thankful today for Jesus.  He sought me when I was far from him.  He loved me when I was yet in sin.  He bought me by his blood outpoured.  He saved me, and now I’ve made Him Lord.

Thursday, October 07, 2010

Birthday Blessing

My daughters, today you turn four years old and today I thank the Lord for each and every moment that our lives have been entwined.  The joy that I experience each time I see your face or hear your voice comes from the knowledge that God has ordained that you would walk through this life with me as your daddy.

The awesomeness of this responsibility is not lost on me.  I shutter at the fact that I am the primary vessel the Lord has chosen to use to model the character of God in your life.  I shutter but I also know that when I am weak, He is strong, when I stumble, He picks me up, and though I may falter, He never changes.

My prayer for you is the following:  that you would love Jesus and that you would permit the Holy Spirit to direct you towards the purpose that God has for your life.

Together with that prayer, I also bless you this day.

I bless the moments that we spend together, that you may know the love of a father.

I bless the moments that we are apart, that you may be secure in that love.

I bless your relationship with your mother, that you may understand the heart she has towards her children.

I bless your relationship with your sister, that your bond would support you during all of life's difficulties.

I bless your relationship with your extended family, that you would take up the heritage of faith that has been provided for you.

I bless your relationships with authority figures, that you may learn to submit to godly authority.

I bless your relationships with your peers, that you may become wise regarding whom you allow to influence you.

I bless your mind, that your may gain wisdom and knowledge.

I bless your body, that you would continue to be in health.

I bless your spirit, that you would know the path of righteousness.

And I leave you with the blessing of God.

May the Lord bless you and keep you.
May the Lord make his face to shine upon you
  and be gracious to you.
May the Lord lift up his countenance upon you
  and give you peace.

Monday, October 04, 2010

Living in Neverland

When I observe my generation, I can't help but feel frustrated.  When did it become a social norm for men and women to never grow up?

I guess now is the time for me to showcase my "old-fashioned" values. 

There was a season in my life when it was acceptable for me to demonstrate a lack of maturity.  This was called childhood.

Today I am in a season of my life when I should be expected to demonstrate a certain level of maturity and autonomy.  This is called adulthood.

Furthermore, I am also in a season of my life when I am expected to demonstrate a certain  level of responsibility and selflessness.  This is called parenthood.

I can almost hear the voice of some begin to complain that societal expectations are to be  overturned and tossed into the trash bin of history.

I beg to differ.  Especially when I see what they would replace it with.

Instead of maturity, my generation feels that living for today is the pinnacle of human experience.

Instead of responsibility, my generation feels that living free of obligations is liberating.

And instead of selflessness, my generation feels that the only purpose in this life is to live for themselves.

But can I share a truth with you?

Understanding my place within the light of eternity is the source of my happiness.

Living within the confines of responsibility is the source of my liberation.

Sacrificing my needs for the needs of others is the source of my purpose.

These truths transcend time and space.  They have not changed, for the human condition has not  changed.  By running away from them we will only find discontentment and sorrow.  By embracing them we will find contentment and happiness.