スパイス  組み込み制御装置の受注製作

ライブラリの導入
平成26年10月 7日

 MPLAB Harmonyの使い方(2)
 次には実際にプロジェクトを作成してみます。

    新規プロジェクトの作成
 MPLAB Xを立ち上げます。もし以前に使用していたプロジェクトがProjectウィンドウに表示されているなら、それらを全てクローズします。操作はFileメニューからClose ProjectまたはClose All Projectを選択します。
 次にFileメニューからNew Projectを選択します。

MPLAB EmbeddedのMPLAB Harmony Projectが選択された状態でNextボタンを押します。

Harmony PathにはMPLAB Harmonyをインストールしたディレクトリ名を入れます(v1_00サブディレクトリまで入力が必要)。
Project Location・Project Name・Configration Nemas・Target Deviceは適切に入力します。最後にFinishボタンを押してプロジェクトを作成します。

    MPLAB Harmony Configretion
 次にMPLAB Harmonyの中で使用する機能をConfigretionします。

最初ですので、コンフィグレーションビットの設定だけを行います。Device Configrationを開いて、上記のように設定します。
薄い青色部分が標準設定から変更した部分です。
PIC32USB基板(16MHz発信器搭載)の仕様から、 としてあります。

同様にSystem Servicesの中にあるDevice Control/Use Device System Service?のチェックを外します。
この操作は、最初は余計な処理が入らないようにするために必要です。

この状態でGenerateボタンを押すと、確認のウインドウが2画面出ますが肯定側(SaveoおよびConfigure)のボタンを押します。
このときのProjectのツリーを示します。これだけのファイルが自動生成されます。


それなりの量になりますが、個々のファイルの主要部分の抜粋を示します。
APP.H

#ifndef _APP_H
#define _APP_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "system_config.h"
#include "system_definitions.h"

typedef enum
{
        /* Application's state machine's initial state. */
        APP_STATE_INIT=0,
        /* TODO: Define states used by the application state machine. */
} APP_STATES;

typedef struct
{
    /* The application's current state */
    APP_STATES state;
    /* TODO: Define any additional data used by the application. */
} APP_DATA;

void APP_Initialize ( void );
void APP_Tasks ( void );

#endif /* _APP_H */
SYSTEM_CONFIG.H

#ifndef _SYSTEM_CONFIG_H
#define _SYSTEM_CONFIG_H

#define SYS_BUFFER  false
#define SYS_QUEUE   false

#endif // _SYSTEM_CONFIG_H
SYS_DEFINITIONS.H
#ifndef _SYS_DEFINITIONS_H
#define _SYS_DEFINITIONS_H

#include <stddef.h>

typedef struct
{

} SYSTEM_OBJECTS;

extern SYSTEM_OBJECTS sysObj;

#endif /* _SYS_DEFINITIONS_H */
SYS_COMMON.H

#ifndef _SYS_COMMON_H_
#define _SYS_COMMON_H_

#include <stdint.h>
#include "assert.h"

#ifdef __cplusplus
    extern "C" {
#endif

#ifndef SYS_ASSERT
    #define SYS_ASSERT(test,message)
#endif

#if defined(__PIC32MX__) || defined(__C30__)||defined(__XC32)
    #define MAIN_RETURN int
#else
    #define MAIN_RETURN void
#endif

#if defined(__PIC32MX__) || defined(__C30__)||defined(__XC32)
    #define MAIN_RETURN_CODE(c)     ((MAIN_RETURN)(c))
#else
    #define MAIN_RETURN_CODE(c)
#endif

typedef enum
{
    MAIN_RETURN_FAILURE     = -1,
    MAIN_RETURN_SUCCESS     = 0
} MAIN_RETURN_CODES;

typedef enum _SYS_TASKS_PRIORITIES
{
    // Invalid priority (can be used as a sentinel value)
    SYS_TASKS_PRIORITY_INVALID = 0,
    // High priority tasks are called every time through the loop
    SYS_TASKS_PRIORITY_HIGH,
    // Called at the medium priority interval.
    SYS_TASKS_PRIORITY_MEDIUM,
    // Called at the low priority interval.
    SYS_TASKS_PRIORITY_LOW
} SYS_TASKS_PRIORITY;

#ifdef __cplusplus
    }
#endif

#endif // _SYS_COMMON_H_
SYS_MODULE.H

#ifndef _SYS_MODULE_H
#define _SYS_MODULE_H

#include <stdint.h>
#include <stdbool.h>
#include "assert.h"
#include "system/common/sys_common.h"

#ifdef __cplusplus
    extern "C" {
#endif

typedef unsigned short int SYS_MODULE_INDEX;

typedef uintptr_t SYS_MODULE_OBJ;

#define SYS_MODULE_OBJ_INVALID      ((SYS_MODULE_OBJ) -1 )
#define SYS_MODULE_OBJ_STATIC       ((SYS_MODULE_OBJ) 0 )

typedef enum
{
    // Indicates that a non-system defined error has occurred.  The caller
    // must call the extended status routine for the module in question to
    // identify the error.
    SYS_STATUS_ERROR_EXTENDED   = -10,
    /*An unspecified error has occurred.*/
    SYS_STATUS_ERROR            = -1,
    // The module has not yet been initialized
    SYS_STATUS_UNINITIALIZED    = 0,
    // An operation is currently in progress
    SYS_STATUS_BUSY             = 1,
    // Any previous operations have succeeded and the module is ready for
    // additional operations
    SYS_STATUS_READY            = 2,
    // Indicates that the module is in a non-system defined ready/run state.
    // The caller must call the extended status routine for the module in
    // question to identify the state.
    SYS_STATUS_READY_EXTENDED   = 10
} SYS_STATUS;

#define SYS_MODULE_POWER_OFF        0
#define SYS_MODULE_POWER_SLEEP      1
#define SYS_MODULE_POWER_IDLE_STOP  2
#define SYS_MODULE_POWER_IDLE_RUN   3

#define SYS_MODULE_POWER_RUN_FULL   15

typedef union
{
    uint8_t         value;
    struct
    {
        // Requested power state
        uint8_t     powerState  : 4;
        // Module-definable field, module-specific usage
        uint8_t     reserved    : 4;
    }sys;
} SYS_MODULE_INIT;

void SYS_Initialize( void *data );
void SYS_Tasks ( void );
typedef SYS_MODULE_OBJ (* SYS_MODULE_INITIALIZE_ROUTINE) ( const SYS_MODULE_INDEX index,
                                                           const SYS_MODULE_INIT * const init );
typedef void (* SYS_MODULE_REINITIALIZE_ROUTINE) ( SYS_MODULE_OBJ object,
                                                   const SYS_MODULE_INIT * const init );
typedef void (* SYS_MODULE_DEINITIALIZE_ROUTINE) (  SYS_MODULE_OBJ object );
typedef SYS_STATUS (* SYS_MODULE_STATUS_ROUTINE) (  SYS_MODULE_OBJ object );
typedef void (* SYS_MODULE_TASKS_ROUTINE) ( SYS_MODULE_OBJ object );

typedef struct
{
    // Pointer to the module's "Tasks" routine
    SYS_MODULE_TASKS_ROUTINE            pTasksFunction;
    // Tasks type (polled/interrupt)
    bool                                intModule;
} SYS_MODULE_TASKS_DATA;

typedef struct
{
    // Pointer to the module's initialization routine
    SYS_MODULE_INITIALIZE_ROUTINE       pModuleInitialize;
    /*Pointer to the module's reinitialization routine*/
    SYS_MODULE_REINITIALIZE_ROUTINE     pModuleReinitialize;
    /*Pointer to the module's deinitialization routine*/
    SYS_MODULE_DEINITIALIZE_ROUTINE     pModuleDeinitialize;
    // Pointer to the module's status routine
    SYS_MODULE_STATUS_ROUTINE           pModuleStatus;
    // Pointer to the module's "Tasks" routine
    SYS_MODULE_TASKS_DATA               *pTasksData;
    // Pointer to the module's init data table
    SYS_MODULE_INIT                    *pModuleInitData;
    // Index to the module instance
    SYS_MODULE_INDEX                    index;
    // Number of tasks supported by this module
    unsigned int                        tasksNum;
} SYS_MODULE_INTERFACE;

typedef struct
{
    // Module interface (function pointers, index, etc)
    SYS_MODULE_INTERFACE    interface;
    // Object handle obtained from initialization call
    SYS_MODULE_OBJ          object;
    // Requested module priority (identifies "Tasks" interval)
    SYS_TASKS_PRIORITY      priority;
    // Number of intervals (of the module priority) before calling this
    // module's "Tasks" routine.
    unsigned int            count;
} SYS_MODULE_DATA;

#ifdef __cplusplus
    }
#endif

#endif // _SYS_MODULE_H
SYS.H

#ifndef _SYS_H
#define _SYS_H

#include "system/common/sys_common.h"
#include "system/common/sys_module.h"

#endif // _SYS_H
 ここから.cファイルですが、app.cのみ自動生成されたファイルに追加していあります。追加部分は太字で示します。
単純にDポートの出力を1周期単位が分かるように変化させています。
app.c

#include "app.h"
#include "xc.h"

APP_DATA appData;

void APP_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    appData.state = APP_STATE_INIT;
    
    /* TODO: Initialize your application's state machine and other
     * parameters.
     */
    LATD=0;
    TRISD=0;
}

void APP_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            LATD=0xffff;
            LATD=0;
            break;
        }

        /* TODO: implement your application state machine.*/

        /* The default state should never be executed. */
        default:
        {
            /* TODO: Handle error in application's state machine. */
            break;
        }
    }
}
main.c

#include <stddef.h>                     // Defines NULL
#include <stdbool.h>                    // Defines true
#include <stdlib.h>                     // Defines EXIT_FAILURE
#include "system/common/sys_module.h"   // SYS function prototypes

int main ( void )
{
    /* Initialize all MPLAB Harmony modules, including application(s). */
    SYS_Initialize ( NULL );

    while ( true )
    {
        /* Maintain state machines of all polled MPLAB Harmony modules. */
        SYS_Tasks ( );
    }
    /* Execution should not come here during normal operation */
    return ( EXIT_FAILURE );
}
system_init.c

#include "system_config.h"
#include "app.h"
#include "system_definitions.h"


/*** DEVCFG0 ***/
#pragma config DEBUG =      ON
#pragma config ICESEL =     ICS_PGx2
#pragma config PWP =        0xff
#pragma config BWP =        OFF
#pragma config CP =         OFF

/*** DEVCFG1 ***/
#pragma config FNOSC =      PRIPLL
#pragma config FSOSCEN =    OFF
#pragma config IESO =       OFF
#pragma config POSCMOD =    HS
#pragma config OSCIOFNC =   OFF
#pragma config FPBDIV =     DIV_1
#pragma config FCKSM =      CSDCMD
#pragma config WDTPS =      PS1048576
#pragma config FWDTEN =     OFF

/*** DEVCFG2 ***/
#pragma config FPLLIDIV =   DIV_4
#pragma config FPLLMUL =    MUL_15
#pragma config FPLLODIV =   DIV_2
#pragma config UPLLIDIV =   DIV_12
#pragma config UPLLEN =     OFF

/*** DEVCFG3 ***/
#pragma config USERID =     0xffff
#pragma config FSRSSEL =    PRIORITY_7
#pragma config FMIIEN =     OFF
#pragma config FETHIO =     OFF
#pragma config FCANIO =     OFF
#pragma config FUSBIDIO =   OFF
#pragma config FVBUSONIO =  OFF


// *****************************************************************************
// Section: Library/Stack Initialization Data
// *****************************************************************************/

// *****************************************************************************
// Section: Driver Initialization Data
// *****************************************************************************

// *****************************************************************************
// Section: System Data
// *****************************************************************************
/* Structure to hold the object handles for the modules in the system. */
SYSTEM_OBJECTS sysObj;

// *****************************************************************************
// Section: Module Initialization Data
// *****************************************************************************

// *****************************************************************************
// Section: Static Initialization Functions
// *****************************************************************************

// *****************************************************************************
// Section: System Initialization
// *****************************************************************************

void SYS_Initialize ( void* data )
{
    /* Core Processor Initialization */
    /* System Services Initialization */    
    /* Initialize Drivers */
    /* Initialize System Services */
    /* Initialize Middleware */
    /* Initialize the Application */
    APP_Initialize();
}
sysytem_interrupt.c

#include <xc.h>
#include <sys/attribs.h>
#include "app.h"
#include "system_definitions.h"

// *****************************************************************************
// Section: System Interrupt Vector Functions
// *****************************************************************************
 
sysytem_tasks.c

#include "system_config.h"
#include "system_definitions.h"
#include "app.h"

// *****************************************************************************
// Section: System "Tasks" Routine
// *****************************************************************************

void SYS_Tasks ( void )
{
    /* Maintain the state machines of all library modules executing polled in
    the system. */
    /* Maintain system services */
    /* Maintain Device Drivers */
    /* Maintain the application's state machine. */
    APP_Tasks();
} 

 これが最小のプロジェクトであろうと思います。
MPALB Harmony Configratorの選択画面で機能を追加すると、その機能に対応した初期化関数や割り込み処理ルーチンなどが上記の自動生成ファイル内に追加されていきます。

 今回は正しくコンパイルが通って実行できることの確認が目的です。このプログラムを実行時の出力波形を示します。

 30MHzで動作している筈ですが、実際にはROMアクセス時のウエイト数設定がリセット時の7クロックになったままなので非常に低速な動作になっています。信号のH期間は33ns x 8(1+7)クロックで264nsになります。波形は計算値と一致します。最小限のプロジェクトはこれで正しいと思われます。

 後は個々のライブラリを追加しながら動作を確認するか、Helpファイルの翻訳結果からライブラリの使い方を吸収する必要があります。

目次へ  前へ  次へ