Webinar on Data Logging during System Development

Below is a recording of a webinar I presented live October 16, 2014, along with Steve Sienkowski a developer on my team. We discuss some of the challenges of control system development and some tools we’ve built to help with distributed/networked control development.

New Eagle Data Logger
Posted in Software Development | Leave a comment

Webinar on CAN Network Toolbox

I had the opportunity recently to present a webinar on the network toolbox for MotoHawk that we’ve built. This is a recording of the webinar I presented live September 18, 2014. Here’s a link:

Network Toolbox & CAN Development
Posted in Uncategorized | Leave a comment

Cloud-connected Telematics

In this webinar, which is co-hosted by myself and Scott Favre, we discuss the cloud-connected telematics system we’ve built to remotely monitor and update fielded vehicles and systems. The backend for this system is based in Microsoft’s cloud at Windows Azure, meaning it is capable of enterprise scale and can be throttled up as needed.


This system is compatible with MotoHawk- and Raptor-based controllers and is configured with the industry standard DBC file format for communication. Individual units can be configured remotely via the portal at telematics.neweagle.net.

Here’s the video feed, recorded live August 28, 2014:

Posted in Software Development | Leave a comment

Doing display development in Simulink

At New Eagle, we’ve got a team of application engineers who are experienced using the Simulink tool to create control software. There are a few of us who have been using it for more than 10 years now to create embedded control software using code generation via MotoHawk. As a result, Simulink is the environment in which most of our engineers are most productive, and is therefore the environment used most often for developing the displaysoftware inside the control systems we build for our customers. One place where we have had to resort to ‘old-school’ hand-coding (manually writing *.c, *.h files etc…) has been the embedded displays that go into control systems for user interfaces.

For many years, we had to author these applications manually, which typically meant that a software engineer (vs controls engineer) would need to join the project for a period of time to work on the display. This new team member would need to come up to speed on the project, which involved communication & iteration with the controls engineer who already knew the system. We desired to enable the controls engineer to rapidly develop the display, without resorting to embedded C, C++. With Raptor, we’ve added now three display targets, including a 7in touchscreen, that can be targeted for automated code-generation from Simulink. Besides the productivity improvement, a subtle benefit of enabling this environment is that messaging between an embedded controller, i.e. engine controller, and the display can use the same format, a DBC file, so there is little opportunity for things to get lost in translation controller <–> display.

Here is a link to the raw feed of a webinar I cohosted on the topic, recorded live July 24, 2014:

Model-Based Display Development
Posted in Software Development | Leave a comment

Webinar on J1939

Here is the powerpoint from a webinar I presented today on the J1939 toolbox for MotoHawk we’ve created.



Posted in Software Development | Leave a comment

Debugging A MotoHawk Application using the Application Monitor

Debugging Embedded Control Modules Background

The MotoHawk control system application development tool chain allows for rapid development of control algorithms and produces build outputs that can be seamlessly deployed to rugged, production-validated control modules (ECUs). This system generally works great, however, every once in a while, you are reminded that you are developing in a constrained embedded environment. Inherent in this environment are limitations on CPU throughput and memory resources. Additionally, creating software that is deployed to sealed, production ready hardware limits the ability to utilize debugging tools common in the embedded software development space, such as a JTAG debugger. Such tools allow the developer to halt CPU execution and inspect CPU state, and even step though the software source code (C files) looking for defects during execution. Thankfully, with a robust, mature code-generation platform like MotoHawk the types of issues that these tools are generally used to solve have been resolved already and are available in proven software blocks for you to use in your application. In reality, for the controls developer in the MotoHawk context the source code is really the Simulink model and inspecting the derived (generated) C source code would not necessarily be of much value. However, due to the nature of the inherent constraints of embedded hardware, (limited processing power, limited memory, etc…) at some point something such as a stack overflow, or processor watchdog will happen as you approach these limits. In the general, this would normally cause the ECU to exhibit continual or spurious processor reset or other strange behavior. As a general rule, when the processor resets there is not much indication as to the cause of the error because the state of the processor is wiped on reset. Without additional tools, tracing the error can be quite difficult. This is where the MotoHawk Application Monitor is meant to help.

Application Monitor Basics

The Application Monitor performs continuous run-time checks on an executing application, monitoring key metrics and will halt the application if something goes wrong. When it stops the application it writes an error status to some user accessible variables for inspection and leaves the calibration protocol running so you can connect to the ECU and inspect these messages to determine the issue. By halting the application before the module resets, the error state can be captured by the user using a calibration tool like MotoTune.


  • Stack – In the discussion below the term ‘stack’ is used to refer to an area of RAM set aside for storing state for local usage or to recover at a later time. For instance, when the code enters a function call, most local variables are stored on the stack and used for calculations during that function. If, inside the function, another function is called then the processor state (registers, return address, etc..), called a ‘stack frame’, needs to be pushed onto the stack for recall when the called function returns. In MotoHawk, stacks are of predetermined size and hence exceeding the allocation will generally cause issues as it may attempt to overwrite other allocated RAM.
  • Heap – In the discussion below the term ‘heap’ refers to an area of RAM set aside for storing memory that is allocated at runtime. For instance, the OS framework utilizes heap storage for communication queues and resource instantiation. Applications that have a lot of communications and/or resource (I/O) usage will use more heap.

Application Monitor Setup

To set up the Application Monitor, you must add it to your model. The ‘Application Monitor’ block can be found in the Simulink Library browser at ‘MotoHawk->System Debug Blocks’. There are two versions, the ‘motohawk_app_monitor’ for ‘legacy’ modules (5xx based) and the ‘Application Monitor (2nd Gen)’ for ‘MotoCoder’ modules, (S12, 55xx, and newer etc..). After adding it to your application you may wish to configure its settings. Although the defaults usually work fine get started, you may want to work with each of the following parameters to tailor the configuration to your needs:

  • Foreground Stack Margin [bytes]

Configures the required headroom (margin) for the Foreground Task(s) stack under which the Application Monitor will halt the application.

  • Foreground Angle Stack Margin [bytes]

Configures the required headroom (margin) for the Foreground Angle Task(s) stack under which the Application Monitor will halt the application. This parameter relates to tasks which take place based on angle triggers.

  • Background Stack Margin [bytes]

Configures the required headroom (margin) for the Background Task(s) stack under which the Application Monitor will halt the application.

  • Idle Stack Margin [bytes]

Configures the required headroom (margin) for the Idle Task stack under which the Application Monitor will halt the application. Note that in most cases the calibration protocol will run in the idle task.

  • Interrupt Stack Margin [bytes]

Configures the required headroom (margin) for the Interrupt Task(s) stack under which the Application Monitor will halt the application.

  • Heap Margin [bytes]

Configures the required headroom (margin) for the heap usage. If the peak heap usage comes within this margin of the amount of allocated heap memory the Application Monitor will halt the application. More on this in ‘Section 6 – Tuning the Application Monitor’.

  • CPU Margin [%]

Configures the minimum amount of idle CPU capacity that must be maintained. If the CPU idle capacity goes below this value (CPU is too busy due to large tasks, etc…), the Application Monitor will halt the application.

  • On Startup – This allows you to configure the startup behavior of the application for debugging. The Application Monitor can pause execution of the application to allow you to connect with the calibration tool to inspect the state of the controller before the subsequent steps are executed.
    • Do No Pause on Startup [Default]

Application executes normal startup running user tasks as typically expected. (Normal Operation)

    • Pause Before Model Initialization

The application will halt before executing model initialization code.

    • Pause After Model Init – Before STARTUP Event

Model-generated initialization code is executed. The model initialization code takes care of setting default values for data stores and other global variables, as well as initial time values for dT blocks and initial values on 1/z blocks.

    • Pause After STARTUP Event – Before Run

The application pauses after the STARTUP event (Operating System Event). Any code you have placed in STARTUP event triggered subsystems will have been executed.

Each of these options allows you to effect the startup behavior of the ECU under control of the Application Monitor. This can be useful in debugging situations where the software you have flashed into the controller fails to operate.



In the screenshot above we can see that the Application Monitor has stopped the application for ‘Idle CPU margin violation’. This occurred because the CPUIdlePcent value dropped below the CPU Margin [%] specified in the Application Monitor block. To resolve this you would normally either slow down the Foreground Rate (10ms vs 5ms), optimize your code, or partition functionality among different tasks depending on your situation.


In the example above, the Application Monitor has halted the application due to ‘Foreground stack margin violation’. Although this is a contrived example (your settings would generally be larger) you can see the Foreground Stack Margin [bytes] setting in the Application Monitor is set to 161 bytes. The Target Definition block has a Foreground Stack size set to 1024 bytes. In MotoTune you can see the FgndTimeStackMinBytesFree is 160 which is below the margin threshold setting for the Application Monitor, hence it has halted the application. To resolve this you would normally just allocate more Foreground stack space in the Target Definition block.

Tuning the Application Monitor

The Application Monitor may halt your application for the reasons below. The reason will be indicated in ‘System->Debug->ApplicationStopReason’. Some information on tuning for each case is described.

  • Requested by user

User requested via ‘System->Debug->ApplicationStatus’. This is a manual halt caused by user intervention. The ‘ApplicationStatus’ variable can also be used to restart the application.

  • Foreground stack margin violation

Monitoring FgndTimeStackMinBytesFree in ‘System->Status->OS’ shows the cumulative minimum free bytes of allocated stack for Foreground Task(s). If this value dips below the established margin, the Application Monitor will halt your application. You can adjust Foreground Stack Margin [bytes] in the Application Monitor block, or increase the Foreground Stack in the Target Definition Block.

  • Background stack margin violation

Monitoring BgndStackMinBytesFree in ‘System->Status->OS’ shows the cumulative minimum free bytes of allocated stack for Background Task(s). If this value dips below the established margin, the Application Monitor will halt your application. You can adjust Background Stack Margin [bytes] in the Application Monitor block, or increase the Background Stack in the Target Definition Block.

  • Idle stack margin violation

Monitoring IdleStackMinBytesFree in ‘System->Status->OS’ shows the cumulative minimum free bytes of allocated stack for the Idle Task. If this value dips below the established margin, the Application Monitor will halt your application. You can adjust Idle Stack Margin [bytes] in the Application Monitor block, or increase the Idle Stack in the Target Definition Block. In most scenarios the calibration protocol is running in the idle task.

  • Interrupt stack margin violation

Monitoring InterruptStackMinBytesFree in ‘System->Status->OS’ shows the cumulative minimum free bytes of allocated stack for Interupt Task(s). If this value dips below the established margin, the Application Monitor will halt your application. You can adjust Interrupt Stack Margin [bytes] in the Application Monitor block, or increase the Interrupt Stack in the Target Definition Block.

  • Heap margin violation

Monitoring PeakHeapBytesUsed in ‘System->Status->OS’ shows the cumulative peak usage of heap. If this value exceeds the heap allocation in the target definition block MINUS the Heap Margin [bytes] set in the Application Monitor block, the Application Monitor will halt your application. You can adjust Heap Margin [bytes] (smaller) or increase the heap allocation in the Target Definition Block.

  • Idle CPU margin violation

Monitor using ‘System->Performance->CPUIdlePcent’ which shows the amount of CPU time that is not in use by your application’s tasks. You can reduce the allowed margin (less CPU idle headroom), optimize your task(s) code, or reallocate functionality within tasks. For instance, if you are exceeding the CPU throughput due to a large FGND_RTI_PERIODIC task, you may look to move some functions to a slower task such as FGND_2XRTI_PERIODIC, FGND_5XRTI_PERIODIC or even into background tasks such as BGND_BASE_PERIODIC and BGND_BASEx2_PERIODIC. If reorganizing your application is not possible, you might use a MotoHawk Trigger Definition to slow the task down.

Further debugging task timing can be done using the following variables from ‘System->Performance’:

        • CPUTime_AppISR
        • CPUTime_Bgnd
        • CPUTime_CAN
        • CPUTime_FgndAngle
        • CPUTime_FgndTime
        • CPUTime_MIOS
        • CPUTime_Serial
        • CPUTime_TPU
        • CPUTime_TimerIS


  • OS error detected

This occurs when an operating system error has been detected. For further debugging you should inspect ‘System->Status->OS->LastOSError’. The values for this variable will vary with the target ECU, but may include:

      • EEDataDirSizeMisMatch
      • Requested TPU Func not in mask
      • Unable to allocate QSPI knock
      • Stack has overflowed!
      • TPU Limits not setup
      • TPU Mask Corrupt
      • Sequence Create with No Encoder
      • Illegal Sequence ISR
      • TPU Mask Version is insufficient
      • MUX PSP requested for 2-Stroke
      • Ext Flash Acc Denied
      • Ext Flash Erase Fail
      • Ext Flash Write Fail
      • Ext Flash Allign Error
      • Illegal Ext Flash Addr
      • Error: Write to non-existent Flash
      • Too many Logs want to be active
      • Bank Seq Destroy Problem
      • Transient Seq Destroy Problem
      • Transient Seq Update Problem
      • SPIEE System had a memory problem
      • Spent too long waiting for a sync return
      • TPUC Mask does not pair with TPUA/B mask
      • The Module Configuration was not available
      • Diagnostic Mux did not create
      • FGND Angle event queue overflow
      • FGND Time event queue overflow
      • EEPROM write to CAMDelay failed
      • SleepTask call from in ISR
      • Bad Kernel API call detected
      • Kernel Internal
      • SPIEE Device create
      • NAND Flash timeout on Write
      • NAND Flash timeout on Erase
      • NAND Flash WP
      • NAND Flash RDY/BUSYb
      • NAND Flash Access
      • NAND Flash Device
      • USB Core Stack Initialisation
      • USB Stack Assert
      • FP Divide by Zero
      • Unable to allocate requested memory on heap
      • Unable create Fgnd Angle task
      • FP Denormalized number
      • RPMVector Buffers Full
      • RPMVector Overrun
      • Failed to Write TPU Self Modify Parameter

Further debugging of these errors will depend on the error and may require further support from New Eagle. Actual error list will vary with ECU target.

Establishing Validation Confidence using the Application Monitor

Another use for the Application Monitor is to establish a safety margin for key operating parameters. Once established, these can be verified during system testing and validation. As an example, if your system requires a safety margin of 30% CPU utilization (e.g. system runs <70% CPU usage at all times) then you can set that in the application monitor and conduct your validation testing. After testing you have confidence that, for the areas of code executed as part of your test plan, you will not exceed the safety margin. You have the option of disabling the Application Monitor via calibration for production releases.


The Application Monitor provides a tool for investigating critical control software issues that would otherwise be very difficult to resolve. By properly configuring the Application Monitor you can avoid trial and error troubleshooting when things go wrong during application development and system testing.

This has been made into a PDF guide available here.

Posted in Software Development | Leave a comment

Working with S12 MotoHawk

This post provides some tips I’ve learned for working with S12 modules from the MotoHawk lineup.


The toolchain for the S12-based MotoHawk is different from all the other modules. For the S12, you will require FreeScale’s CodeWarrior compiler. This for-purchase compiler can be obtained online and generally you can get started right away using the 30-day trial feature. During the 30-day trial you will have what appears to be a full-functioning license. This trial allows you time to secure a full license or merely experiment. There are different versions of this compiler, please refer to the Freescale documentation to find the most suitable and compatible version of Codewarrior for your machine. While the other modules have the free compiler option of GCC, this does not apply to the S12 MotoHawk modules.

Note: After the 30-day trial is complete, there is a 32 KB compiler limit. This is too small for most applications and will result in a link error which manifests itself in an error during build that will look similar to below:

>>ERROR L1102: Out of allocation space in segment RAM_BLOCK0_SEG at address 0x3BFC

>>Error using ==> motocoder_codegen at 84


Memory Resources

One of the first issues you will discover upon attempting to build your MotoHawk model targeted to the S12 is that the base project, generated by the ‘motohawk_project’ script, does not compile! This is evidence of the memory constraints of the lower-cost module family. As a comparison, in the table below is a comparison of an S12 module to the 55xx 112-pin module.


Compared to the 55xx module, the S12 module has:

  • 6.25% of the FLASH
  • 12.25% of the RAM
  • 6.25% of the EEPROM

As you can imagine this can have significant bearing on your software design. Looking at the default memory allocations in the target definition block, we see:


Since these add up to 13.5K, which is larger than the 8K of RAM that is available on the S12 module, we know it won’t compile this way. These settings will vary based on your application’s profile, but recommended starting values might be:


These values add up to 4.75K which is just over half the total RAM for the module. These should be adjusted as needed by your application.




If you are curious what each of these ‘stacks’ are all about, here is some more information.


Target Selectionimage

Not all S12-based modules are listed in the MotoHawk Target Definition block. A part of the reason for that is the evolution of these modules over time which resulted in part number and name changes. This chart provides information about the evolution of SECMs.

Further, for certain targets you will have to select a target other than that listed on your module. The following cross reference (from the MotoHawk Help documentation) is helpful in selecting the proper option in the MotoHawk Target Definition block. In addition, something to double-check would be the ‘Memory Layout’ option just below the Target Selection. That option defaults to DEV so needs to be set properly according to your target.




Programming the module

If you would program these modules under conditions like the following, you would have to be aware that the module will have non-standard City IDs by default. These conditions are:

  • Programming the module for the very first time after purchasing it.
  • Using a boot harness to program the module.
  • Always until the City ID change has been made through a change in CAN settings in the model.


All this calls for setting up another MotoTune port to reflect the right City ID.

If you are using a boot harness then after flashing the module, you would have to switch over to a normal development or programming harness in order to access the application over MotoTune. The boot harness will for the module to stay in boot mode otherwise.

Another issue that will result from selecting a target which is different from the label on the module is a MotoTune error message that looks something like this:


If you have selected the proper target from the list above, it is safe to click on YES to program anyway. This will not affect the normal running of the program.

Controlled Shutdown – NonVolatile RAM

The Small Engine Control (SECM) S12 modules (ECM-0S12-024-0801, ECM-0S12-024-0802, ECM-0S12-024-0804, ECM-0S12-024-0502, ECM-0S12-024-05image03) do not have a KEYSWITCH input. As a result, these modules do not operate with a ‘controlled shutdown’. Normally, during a controlled shutdown software found within the ‘Main Power Relay Block’ will cause datastore values set as ‘NonVolatile’ to be written to the module’s EEPROM memory. Without a controlled shutdown, the application will have to store Nonvolatile data manually using the ‘MotoHawk NonVolatile Store’ block. Since the EEPROM memory has a limited write-cycle lifetime (approx 100,000 times), the application must issue the store command judiciously. As an example, issuing the command once per second would burn out the EEPROM in a day or so.

Boot Procedure

If you happen to program an invalid application into a module, or are otherwise unable to communicate with the module you may need to ‘boot’ the module to recover. The ‘boot’ procedure prevents the module from beginning execution of the user application on startup for some period of time – the processor is kept in the bootloader awaiting reprogramming commands. The S12 family of MotoHawk modules don’t all use the standard boot key that other modules do. Certain modules require a special ‘boot harness’ which provides a combination of I/O states that the module recognizes as a signal to stay in ‘boot’ mode.

SECM Boot Harness


GCM 24 Boot Harness


Application Monitorimage

The ‘MotoHawk Application Monitor’ sets up a monitor within your application that checks critical system parameters as your application executes.

While monitoring these parameters it will halt the application if usage exceeds certain thresholds you configure within the mask for this block. Although the application is halted when a threshold is exceeded, the MotoTune protocol handler should continue to execute meaning that you can inspect the state of the controller using MotoTune to determine what has occurred. The following MotoTune Display variables are useful in working with the App Monitor:


Configuring the Application Monitor for the S12 is done via parameters in the target definition block for most parameters. There is a separate block for the starvation timer. The parameters available are shown in the table below:


The App Monitor can stop your application for the following reasons:

  • App Monitor Notification Stop
  • Application Stopped (User Command)
  • Starvation timer margin violation
  • Heap margin violation
  • Idle stack margin violation
  • Interrupt stack margin violation
  • ApplicationInterruptTask stack margin violation
  • BGNDTask stack margin violation
  • SHUTDOWNTask stack margin violation
  • FGNDTask stack margin violation

When the application monitor stops your application for one of these reasons, it is because a condition has been detected that needs to be resolved in your software. Often times, all that is required is adjusting the stack sizes to better match your application, but for applications that are approaching the resource constraints of the module, this can involve tradeoffs and optimizations.

This has been made into a PDF guide at: here

Posted in Software Development | Leave a comment

PDC Sessions Collected

Here’s a nice compilation of the PDC 08 session list with links to the recordings. (I’ve found navigating through at www.microsoftpdc.com to be rather tedious).


Posted in Software Development | Leave a comment

Compiler as a Service



The real fun starts at 62:30.

Posted in Software Development | Leave a comment

Windows Azure

I’ve noticed a subtle change in the tech marketplace over the past few years. I believe the Operating System market has been / is fragmenting, statistics about the number of college students that are using Macs is pretty shocking to me. No one was using Macs when I was in college, I don’t recall seeing even one. These students are the next generation of computer users, and they are all computer users. Even though I don’t personally agree from a technical / use perspective, it appears Microsoft has made a major misstep with Vista. (I have been using it since some of the pretty early available MSDN betas.)  This has opened a door that I believe Microsoft would have rather had stayed closed. Along these lines, there is some pretty good movement with the open source OS platforms. Dell and others are selling machines with Ubuntu pre-installed as a general option. These things weren’t going on just a few years ago, or at least to any real degree. It was always mainly Microsoft. In addition, Microsoft’s other major franchise, the Office suite, has been challenged by other, often much cheaper or free, competition like Open Office, and Google Docs. What’s more, the Microsoft Zune, which I own and think is an awesome device,  hasn’t even really dented the mp3 player marketshare of Apple’s Ipod (last number I remember hearing was Zune = 3-5%, I might be wrong). The XBOX, although also very awesome, has been a real money looser (until lately?). Don’t get me wrong, they’re still making money hand over fist.

So I’ve been wondering what the future looks like for Microsoft. With the apparent fragmentation in the OS game, (which many will dispute I’m sure) it seems the ubiquity of the ‘Windows Desktop’ (call it whatever you want XP, Vista,  7), may have a limited future (perhaps 5-10 years still I think). Other players will probably come into this game in a non-trivial way. This concerns me because I’ve invested a ton of time over the years learning the Microsoft stack, the last few on .NET particularly. If .NET == ‘Windows Desktop’ then that investment looses value. (In this vane, I’m really glad to see things like Mono coming up which take .NET onto other platforms like Linux, etc. Also, glad that Silverlight is bringing the .NET skillset out to so many new places.) Recently, a major new future direction for Microsoft was announced at the PDC. They announced a new platform called ‘Windows Azure’.


While, from a cursory glance, this looks similiar to other platforms that have recently come out of Redmond (think WPF, WCF, WF….and on and on), I think there is something more to it. They are looking for their next franchise, Microsoft sees that its core franchises are, or will soon be, under major attack for the reasons mentioned above. The marketplace is simply evolving. We know how Microsoft made zillions with those francises, they sold licenses to run on-premise software. ‘Windows Desktop’ runs on your desktop machine, Office likewise. Individuals and businesses shelled out major money for the software that they would run.  Windows Azure is presented as an ‘Operating System for the Cloud’ – it doesn’t run on your machine (in deployment / real world). People (users) don’t generally pay for the software they run in the cloud. They pay for the utility they get. Think music you buy from Amazon, think photos you store online to share with your family, even think about paying your bills online. There’s software under there – you don’t pay for it as such but someone does. Further, there’s hardware under there. Amazon pays a ton, in hardware, management & power costs to make its marketplace available. Your bank pays a boatload for operating its datacenter. These costs are actually prohibitive in some cases for businesses of certain sizes. Its hard to scale and do so quickly when you need to (you get Digged or something).


Ok, back on point. So what is Windows Azure. Well, its a platform for doing these things. With Azure, it looks like Microsoft is starting in a new direction, one with many of the same facets of its massively successful ‘Windows Desktop’ franchise. ‘Windows Desktop’ has been successful not because it, itself, is that great, but largely due to the fact that it has been the choice platform for people who MAKE applicaitons. It is the ease of application development and therefore the diversity of said application base that has propelled ‘Windows Desktop’ for so long. Windows Azure looks to be largely the same thing in the new world of online apps and services. It is a platform that will seem familiar to the army of Microsoft developers that want / need to enter the ‘connected game’ in a big way. It may not even be the ‘best’ (some people are religious about Macs), Amazon has been doing similiar things, other people might have a ‘better’ platform, but what Microsoft brings is the developers. So how are they going to make their zillions off this platform like they did off the ‘Windows Desktop’? They have not announced exact details yet on the price structure, but it seems like they are going to be monetizing the hardware, the software and the management (which is also, in part, software.) These are all things you have to pay for anyway to get in the game – so why pay Microsoft? Well, some of these are hard – as I mentioned, its hard to scale quickly. Its hard to have reliable storage. You have to know things / hire people. This is expensive if you have to do it yourself – especially up front. You can pay as you go. Also advantageous for Microsoft here, as with ‘Windows Desktop’ is that there is lock-in. They offer the platform you build on. The platform isn’t just software anymore, its the whole scale of a datacenter. I was wondering how Microsoft was going to challenge the Googles of the world. Now we know.

Posted in Cool Tech, Software Development | Leave a comment