Systemライブラリは、時刻取得、遅延処理、割込制御、スリープ、電源状態、リセットなど分類するほどのないものを集めた雑多なライブラリだ。
そして重要な機能も持っている。Arduino風のメイン・ルーチンを提供しloop()処理から戻ってくるとバックグラウンド処理を行う。IEEE802.15.4プロトコル・スタックなどがバックグラウンド処理を必要とするためだ。
【Arduino風のメイン・ルーチン】
だいぶシンプルになったというか見慣れたコードが一番な気がするかも...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* * device.hは複数のインクルードファイルをまとめたインクルード。 */ #include "device.h" /* * wakeup()はウェイクアップ起動時にsetup()より前に呼びされる。 * 必要なければ関数自体を記述しなくて良い。 */ void wakeup(void) { } void setup(void) { } void loop(void) { /* * バックグラウンド処理を行うために短時間でリターンすること。 * 長時間ループするようなときはyield()を呼び出すことで * バックグラウンド処理を行うことも出来る。 */ } |
【ライブラリ】
※未説明のインクルードが含まれていることに注意!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/* device.h - Device includes for NXP-JN516x Copyright (c) 2022 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #pragma once #include <jendefs.h> #include <AppHardwareApi.h> #include <MicroSpecific.h> #include "system.h" #include "clock.h" #include "sysctrl.h" #include "rndgen.h" #include "pulscounter.h" #include "watchdog.h" #include "ticktimer.h" #include "waketimer.h" #include "timer.h" #include "flash.h" #include "eeprom.h" #include "gpio.h" #include "analog.h" #include "adc.h" #include "comparator.h" #include "infrared.h" #include "uart.h" #include "spi.h" #include "wire.h" #include "wpan.h" #include "alarm.h" #include "debug.h" |
※未説明のメソッドが含まれていることに注意!
MAdc::handle();
WPan::handle();
Watchdog::reset();
SysCtrl::begin();
Watchdog::begin();
WakeTimer::begin();
Analog::begin();
EEPRom::begin();
AlarmTimer.begin();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
/* system.h - System Library for NXP-JN516x Copyright (c) 2022 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #pragma once #include <jendefs.h> #include <AppHardwareApi.h> extern void yield0(void); extern void yield(void); extern void empty(uint32 u32Device, uint32 u32ItemBitmap); class System { public: static uint32 micros(void); static uint64 micros64(void); static void delayMicroseconds(uint32 us) __attribute__((noinline,optimize(0))); static void delayMicroseconds64(uint64 us) __attribute__((noinline,optimize(0))); static void delay(uint32 ms) __attribute__((noinline,optimize(0))); static uint32 firstBit(uint32 n) __attribute__((optimize(1))); static uint32 firstBit64(uint64 n) __attribute__((optimize(1))); static uint32 lastBit(uint32 n) __attribute__((optimize(1))); static uint32 lastBit64(uint64 n) __attribute__((optimize(1))); static void enableInterrupts(void) __attribute__((optimize(1))); static void disableInterrupts(void) __attribute__((optimize(1))); static uint32 disableAndSaveInterrupts(void) __attribute__((optimize(1))); static void restoreInterrupts(uint32 save) __attribute__((optimize(1))); static void interruptPriority(uint16 u16Mask, uint8 u8Level) __attribute__((optimize(1))); static void cpuDoze(void) __attribute__((optimize(1))); typedef enum { SLEEP_OSCON_RAMON = E_AHI_SLEEP_OSCON_RAMON, // 32Khz Osc on and Ram On SLEEP_OSCON_RAMOFF = E_AHI_SLEEP_OSCON_RAMOFF, // 32Khz Osc on and Ram off SLEEP_OSCOFF_RAMON = E_AHI_SLEEP_OSCOFF_RAMON, // 32Khz Osc off and Ram on SLEEP_OSCOFF_RAMOFF = E_AHI_SLEEP_OSCOFF_RAMOFF, // 32Khz Osc off and Ram off SLEEP_DEEP = E_AHI_SLEEP_DEEP, // Deep Sleep } SLEEP; static void sleep(SLEEP mode); static void protocolPower(bool enable); typedef enum { POWER_SLEEP_WAKEUP = 1 << 0, // Device has completed a sleep-wake cycle POWER_SLEEP_RAM = 1 << 1, // RAM contents were retained during sleep POWER_ANALOG = 1 << 2, // Analogue power domain is switched on POWER_PROTOCOL = 1 << 3, // Protocol logic is operational POWER_WATCHDOG = 1 << 7, // Watchdog caused last device restart POWER_CLOCK_32K = 1 << 10, // 32kHz clock is ready POWER_DEEP_SLEEP = 1 << 11, // Device has just come out of Deep Sleep mode } POWER; // bit combination static POWER powerStatus(void); static void reset(void); // Number of NVM location from which word is to be read: 0, 1, 2 or 3 static void writeNVData(uint8 u8Location, uint32 u32WriteData); // Number of NVM location from which word is to be read: 0, 1, 2 or 3 static uint32 readNVData(uint8 u8Location); static void setStackOverflow(bool_t bStkOvfEn, uint32 u32Addr); static void debugger(bool enable, bool location); static void storeDebug(uint32 *pRegStorage); static void restoreDebug(uint32 *pRegStorage); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
/* system.cpp - System Library for NXP-JN516x Copyright (c) 2022 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <muldiv.h> #include <MicroSpecific.h> #include "system.h" #include "ticktimer.h" uint32 System::micros(void) { return (uint32)TickTimer::micros64(); } uint64 System::micros64(void) { return TickTimer::micros64(); } void System::delayMicroseconds(uint32 us) { uint32 t = micros(); while (micros() - t + 100 < us) yield(); while (micros() - t < us) continue; } void System::delayMicroseconds64(uint64 us) { uint64 t = micros64(); while (micros64() - t + 100 < us) yield(); while (micros64() - t < us) continue; } void System::delay(uint32 ms) { delayMicroseconds64(MulDiv::mulu32u32(ms, 1000U)); } uint32 System::firstBit(uint32 n) { asm volatile ("b.ff1 %0, %1" : "=r" (n) : "r" (n)); return n; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wreturn-type" uint32 System::firstBit64(uint64 n) { asm volatile ("b.mov r5, r3"); asm volatile ("b.ff1 r3, r4"); asm volatile ("b.bne r3, r0, L_firstBit64_1"); asm volatile ("b.ff1 r3, r5"); asm volatile ("b.beq r3, r0, L_firstBit64_1"); asm volatile ("b.addi r3, r3, 32"); asm volatile ("L_firstBit64_1:"); } uint32 System::lastBit(uint32 n) { asm volatile ("b.bitrev r3, r3"); asm volatile ("b.ff1 r3, r3"); asm volatile ("b.beq r3, r0, L_lastBit_1"); asm volatile ("b.addi r5, r0, 33"); asm volatile ("b.sub r3, r5, r3"); asm volatile ("L_lastBit_1:"); } uint32 System::lastBit64(uint64 n) { asm volatile ("b.addi r5, r0, 65"); asm volatile ("b.bitrev r3, r3"); asm volatile ("b.ff1 r3, r3"); asm volatile ("b.bne r3, r0, L_lastBit64_1"); asm volatile ("b.bitrev r3, r4"); asm volatile ("b.ff1 r3, r3"); asm volatile ("b.beq r3, r0, L_lastBit64_2"); asm volatile ("b.addi r5, r0, 33"); asm volatile ("L_lastBit64_1:"); asm volatile ("b.sub r3, r5, r3"); asm volatile ("L_lastBit64_2:"); } #pragma GCC diagnostic pop void System::enableInterrupts(void) { MICRO_ENABLE_INTERRUPTS(); } void System::disableInterrupts(void) { MICRO_DISABLE_INTERRUPTS(); } uint32 System::disableAndSaveInterrupts(void) { uint32 save; MICRO_DISABLE_AND_SAVE_INTERRUPTS(save); return save; } void System::restoreInterrupts(uint32 save) { MICRO_RESTORE_INTERRUPTS(save); } void System::interruptPriority(uint16 u16Mask, uint8 u8Level) { vAHI_InterruptSetPriority(u16Mask, u8Level); } void System::cpuDoze(void) { vAHI_CpuDoze(); } void System::sleep(SLEEP mode) { vAHI_Sleep((teAHI_SleepMode)mode); } void System::protocolPower(bool enable) { vAHI_ProtocolPower(enable); } System::POWER System::powerStatus(void) { return (POWER)u16AHI_PowerStatus(); } void System::reset(void) { vAHI_SwReset(); } void System::writeNVData(uint8 u8Location, uint32 u32WriteData) { vAHI_WriteNVData(u8Location, u32WriteData); } uint32 System::readNVData(uint8 u8Location) { return u32AHI_ReadNVData(u8Location); } void System::setStackOverflow(bool_t bStkOvfEn, uint32 u32Addr) { vAHI_SetStackOverflow(bStkOvfEn, u32Addr); } void System::debugger(bool enable, bool location) { vAHI_SetJTAGdebugger(enable, location); } void System::storeDebug(uint32 *pRegStorage) { vAHI_StoreDebug(pRegStorage); } void System::restoreDebug(uint32 *pRegStorage) { vAHI_RestoreDebug(pRegStorage); } /* JN516x Main Routine */ #include "device.h" #if defined __cplusplus #define APPSTART extern "C" PUBLIC #else #define APPSTART PUBLIC #endif extern void wakeup(void) __attribute__((weak)); extern void setup(void); extern void loop(void); extern void empty(uint32 u32Device, uint32 u32ItemBitmap) __attribute__((noinline,optimize(1))); void empty(uint32 u32Device, uint32 u32ItemBitmap) { (void)u32Device; (void)u32ItemBitmap; /* No processing. for wakeup */ } void yield0(void) { MAdc::handle(); WPan::handle(); Watchdog::reset(); } void yield(void) { if (Task::yield()) yield0(); } static void init(void) { u32AHI_Init(); u32AppQApiInit(0, 0, 0); SysCtrl::begin(); Watchdog::begin(); WakeTimer::begin(); TickTimer::begin(); Analog::begin(); EEPRom::begin(); AlarmTimer.begin(); Task::begin(); } APPSTART void AppColdStart(void) { init(); setup(); while (1) { loop(); yield(); } } APPSTART void AppWarmStart(void) { if (wakeup) wakeup(); AppColdStart(); } |
次回は、Arduino風のGPIOライブラリを説明予定。
【関連投稿】
NXP JN516X (TWELITE) をプログラミングする(開発環境の構築)
NXP JN516X (TWELITE) をプログラミングする(メイン・ルーチン)
NXP JN516X (TWELITE) をプログラミングする(TICKTIMER)
NXP JN516X (TWELITE) をプログラミングする(UART)
NXP JN516X (TWELITE) をプログラミングする(SYSTEM)
NXP JN516X (TWELITE) をプログラミングする(GPIO)
NXP JN516X (TWELITE) をプログラミングする(TIMER)
NXP JN516X (TWELITE) をプログラミングする(ALARM)
NXP JN516X (TWELITE) をプログラミングする(WAKETIMER)
NXP JN516X (TWELITE) をプログラミングする(WATCHDOG)
NXP JN516X (TWELITE) をプログラミングする(I2C)
NXP JN516X (TWELITE) をプログラミングする(SPI)
NXP JN516X (TWELITE) をプログラミングする(ADC)
NXP JN516X (TWELITE) をプログラミングする(COMPARATOR)
NXP JN516X (TWELITE) をプログラミングする(CLOCK)
NXP JN516X (TWELITE) をプログラミングする(BROWNOUT)
NXP JN516X (TWELITE) をプログラミングする(PULSCOUNTER)
NXP JN516X (TWELITE) をプログラミングする(INFRARED)
NXP JN516X (TWELITE) をプログラミングする(RANDOM-GENERATOR)
NXP JN516X (TWELITE) をプログラミングする(FLASH)
NXP JN516X (TWELITE) をプログラミングする(EEPROM)
NXP JN516X (TWELITE) をプログラミングする(WPAN)
NXP JN516X (TWELITE) をプログラミングする(Eclipse-CDT+MWSTAGE)
NXP JN516X (TWELITE) をプログラミングする(乗算と除算)
NXP JN516X (TWELITE) をプログラミングする(マルチタスク)
NXP JN516X (TWELITE) をプログラミングする(フラッシュ・プログラマー)
NXP JN516X (TWELITE) をプログラミングする(OTA UPDATE)
NXP JN516X (TWELITE) をプログラミングする(TWELITE CUE/MC3630)
NXP JN516X (TWELITE) をプログラミングする(LED)
NXP JN516X (TWELITE) をプログラミングする(AES)
NXP JN516X (TWELITE) をプログラミングする(Downloads)