平成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発信器搭載)の仕様から、
- 外部発信器を使用し、前段分周4・PLL15倍・後段分周2の30MHz動作
- 周辺クロック分周なし
- WDT禁止
- ICDデバッグ有効
- その他の主要な機能は基本的に禁止
としてあります。
同様に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ファイルの翻訳結果からライブラリの使い方を吸収する必要があります。