Add a field programmatically to a custom entity
You'll need to define a field and an field instance in your module's .install file. The function can either be in hook_enable() or hook_install(). The field will provide the name of the field and some default settings. The field instance can be seen  as the link between the field and the entity you want to place the field on.

The format of the settings differs per field type (a text field has a maximum length, an entity reference field can define the selectable bundle(s), etc). Often the available settings are explained in the module's hook_field_info implementation. For core fields these can be found on the following page: 7 functions implement hook_field_info().
For non-core fields the settings are likely to be explained in the hook_field_info implementation as well, for example entityreference_field_info().

The process Drupal follows when registering a field is as follows:

The field is registered in the field api first, with it's default settings (the settings as defined in hook_field_info()). But your module can override them in the settings array of your field_create_field function. So that the field with your name will have by default your settings. Other values such as cardinality (how many values can the field hold) and translatability can be defined as well. See the detailed information on field_create_field() for all values.

From there the field is attached to the entity and it's bundle by means of a field instance. This instance defines which field should be attached to which entity and bundle. Here the settings can be overridden once more for this specific fields implementation on this specific entity. You can also select the widget here; the way the field is to be selected. Modules define their widgets in hook_field_widget_info(), available widgets for core fields can be found here: 7 functions implement hook_field_widget_info(). For a textfield you would use the widget text_textfield, for an image you can use image_image, for a non-core module you'll need to lookup the available widgets yourself in the hook_field_widget_info() implementation. 
For a full lis tof all properties you can set on field instances, see field_create_instance().

Image field example

function mymodule_enable() {
  // Check if our field is not already created.
  if (!field_info_field('my_image')) {
    $field = array(
      'field_name' =&gt; 'my_image',
      'type' =&gt; 'image',
      'locked' =&gt; TRUE, // Settings can not be changed
      'settings' =&gt; array(
        'no_ui' =&gt; TRUE, // Field is not visible in field UI and can only be instantiated programmatically.
      ),
    );
    field_create_field($field);

    // Create the instance on the bundle.
    $instance = array(
      'field_name' =&gt; 'my_image',
      'entity_type' =&gt; 'my_entity',
      'bundle' =&gt; 'my_entity_bundle', // If your entity does not have bundles, this is the same as the entity type.
      'label' =&gt; 'Featured image',
      'required' =&gt; TRUE, // Field must have a value.
      'widget' =&gt; array(
        'type' =&gt; 'image_image',
      ),
    );
    field_create_instance($instance);
  }
}


Entity reference example

function mymodule_enable() {

  // Create an entityreference field.
  $field = array(
    'field_name' =&gt; 'my_entityreference',
    'type' =&gt; 'entityreference',
    'settings' =&gt; array(
      'target_type' =&gt; 'my_other_entitytype',
    ),
    'cardinality' =&gt; 1, // Field may only have one value.
    'translatable' =&gt; FALSE,
  );
  field_create_field($field);

  $instance = array(
    'field_name' =&gt; 'my_entityreference',
    'entity_type' =&gt; 'my_entitytype',
    'bundle' =&gt; 'my_entitytype_bundle',
    'label' =&gt; 'Reference to my_other_entitytype',
    'required' =&gt; TRUE,
    'widget' =&gt; array(
      'type' =&gt; 'options_select',
    ),
  );
  field_create_instance($instance);
}