Skip to content

Getting Started

Michael Koval edited this page Jan 19, 2011 · 25 revisions

Getting Started

Note
This guide assumes that you have already have installed Hax and all of its dependencies. If you have not yet done so, please consult the [[installation instructions|Installation]] before attempting to follow this tutorial.

By the end of this tutorial you will have a simple “hello world” program running on the architecture of your choice.

The main() Function

Begin by creating a directory named HelloWorld for your first project and navigate into the empty directory:

$ mkdir HelloWorld 
$ cd HelloWorld

In C and C++, every valid program must contain a single function called main that serves as the entry point for the program. Because the Vex microcontrollers do not run an operating system (much unlike a desktop computer), it is crucial that we never return from this function. Additionally, the master-slave architecture of the microcontrollers demand that a great deal of bookkeeping takes place on a regular basis (every ~18.5 ms).

Thankfully, all of this bookkeeping requires only a few functions calls and is taken care of entirely by HAX. Create a new file named program.c and add the following contents using a text editor of your choice:

__noreturn 
void main(void) {
	arch_init_1();
	init();
	arch_init_2();

	for (;;) {
		if (do_slow_loop()) {
			arch_loop_1();
			loop();
			arch_loop_2();
		} 
		arch_spin();
		spin();
	}
}

Now, lets walk through this code line by line. We begin by calling three functions to initialize the hardware:

arch_init_1();
init();
arch_init_2();

The first of these functions, arch_init_1(), must be the first function call in main() and handles all hardware configuration that must occur immediately upon the microcontroller starting up. Next, represented by the init() function call, resides any user initialization code. Finally, the initialization is concluded with a call to arch_init_2(). Initialization must occur in this order for the microcontroller to behave as expected.

Upon completing initialization, the program then enters an infinite loop which runs all of the user code. The bulk of the the user code should reside in the slow loop, which occurs approximatelye very 18.5 ms, or when do_slow_loop() returns true:

if (do_slow_loop()) {
	arch_loop_1();
	loop();
	arch_loop_2();
} 

Following the same scheme as initialization, arch_loop_1() and arch_loop_2() should be called respectively before and after the user code (represented here as loop()). Because this pair of functions handles communication with the master processor, it is crucial that the user code does not take more than ~18.5 ms to run. Unless there is a compelling reason for part of the user code to run faster than the slow loop, it should go here.

Everything inside the infinite loop that is not in the slow loop is referred to as the fast loop. This code executes as quickly has hardware allows and should be limited to only code that needs this property:

arch_spin();
spin();

Following the same convention as above, arch_spin() is a HAX function that handles necessary bookkeeping and spin() is a place-holder for user code in the fast loop. This sample, minus the placeholder functions, serves as a basic framework for any program you choose to write using HAX.

Program Logic

With the necessary boilerplate behind us, we will fill in init(), loop(), and spin() to write a simple program that controls Motor 2 using the left analog joystick on the operator interface. Add the following to program.c:

#include <stdint.h>
#include <stdio.h>
#include <hax.h>

void init(void)
{
	printf("Initialization Complete\n");
}

void loop(void)
{
	int8_t stick = oi_group_get(OI_JOY_L_Y(1));
	motor_set(IX_MOTOR(2), stick);
	printf("Motor #2 <= %d\n", stick);
}
	
void spin(void) {}

Here you can see that oi_analog_get() is a function that returns the value of an analog stick on the operator interface and motor_set() controls a motor directly connected to the microcontroller. Both of these functions accept an index argument that is generated with the an architecture-specific macro. In this case, OI_JOY_L_Y(1) refers to the y-axis of the left analog stick on the first operator interface and IX_MOTOR(2) refers to the motor plugged into port 2 on the microcontroller. This indexing scheme is universal across HAX and you can read more about it in the "Indexing" section of the [[API Reference]].

Program Configuration

In addition to the source code, HAX requires one project-specific configuration file called prog_conf.h in the base directory of your project. This file is primarily for advanced users and for future expansion and is out of the scope of this guide. For a minimal installation, create the file prog_conf.h and enter the following contents:

#ifndef CONFIG_H_
#define CONFIG_H_

#define PROG_ANALOG_IN_NUM 16
#define WARN(...)

#endif

Building and Transfering

As is traditional for most UNIX-based projects, HAX uses GNU Make as its build system. Because cross-compiling code for a microcontroller is typically so difficult, much of the process is automated by HAX. As the user, all you must do is create a file named Makefile in your project directory and add the following contents:

arch   = cortex
prog   = HelloWorld
serial = /dev/USB0
SOURCE = program.c

include HAX_PATH/build.mk

The arch variable, set to either cortex or pic determines which architecture we are building for. In the final stage of the build, the prog variable is used to set the name of the output binary. This binary is then transfered to the microcontroller over the orange programming cable identified by the serial port set in the serial variable. Finally, SOURCE should be set to a space-delimited list of the user’s source files (in this case only program.c).

With the necessary configuration options set, we simply include HAX’s global Makefile and let it handle the remainder of the build. Note that you must replace HAX_PATH in the above code with the actual path to the base directory of your HAX download (for example ~/hax). Now you can safely build your project using make: commands:

$ make 
CC program.c 
CC HAX_PATH/arch_cortex/hax.c 
...
LD HelloWorld-cortex.elf
BIN HelloWorld-cortex.elf

If this builds with no errors, congratulations: you have written your first program using HAX. Make sure your microcontroller is on and connected to your computer with the orange programming cable. Press the button on the programming cable to put the microcontroller into programming mode and use the following command to transfer the program:

$ make install

Moving Forward

Now that you have successfully downloaded your first program, you should take a look at the [[API Reference]] to familiarize yourself with HAX’s functionality. If you would like additional code examples consult the skel, test, and comp2010 directories in your local Hax installation.

Clone this wiki locally