/* * TOPPERS ECHONET Lite Communication Middleware * * Copyright (C) 2014-2017 Cores Co., Ltd. Japan * * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * */ /* * サンプルプログラム(1)の本体 */ #include #include #include #include #include #include "t_stdlib.h" #include "syssvc/syslog.h" #include "kernel_cfg.h" #include "diskio.h" #include "sdfs.h" #include "ff.h" gpio_t ins; sdfs_t sdfs; #define WP() false extern FATFS RomDisk; extern unsigned char RamDisk[SZ_RAMDISK * 1024]; bool_t romdisk_init(); int mruby_arduino_init() { int result = -1; /* SD_CD */ gpio_init_in(&ins, P7_8); /* SDカードを初期化 */ sdfs_init(&sdfs, P8_5, P8_6, P8_3, P8_4, "sd"); SD_begin(); FIL fd; UINT rlen = 0; memset(&fd, 0, sizeof(fd)); if (f_open(&fd, "1:/httpd-fs.bin", FA_OPEN_EXISTING | FA_READ) == FR_OK) { f_read(&fd, RamDisk, SZ_RAMDISK * 1024, &rlen); f_close(&fd); if (romdisk_init()) result = 0; } if (result == 0) { syslog(LOG_NOTICE, "ramdisk ok!"); } else { syslog(LOG_NOTICE, "ramdisk ng!"); } arduino_init(); return result; } bool_t romdisk_init() { DSTATUS dst; FRESULT res; if (RomDisk.fs_type != 0) return true; if ((dst = ramdisk_initialize()) != RES_OK) { return false; } if ((res = f_mount(&RomDisk, "0:", 1)) != FR_OK) { return false; } return true; } DSTATUS disk_initialize(BYTE pdrv) { switch (pdrv) { case 0: return ramdisk_initialize(); case 1: return sdfs_initialize(&sdfs); } return STA_NOINIT; } DSTATUS disk_status(BYTE pdrv) { switch (pdrv) { case 0: return ramdisk_get_status(); case 1: return sdfs_status(&sdfs); } return STA_NOINIT; } DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) { switch (pdrv) { case 0: return ramdisk_read(buff, sector, count); case 1: return sdfs_read(&sdfs, buff, sector, count); } return RES_PARERR; } DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) { switch (pdrv) { case 0: return ramdisk_write(buff, sector, count); case 1: return sdfs_write(&sdfs, buff, sector, count); } return RES_PARERR; } DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) { switch (pdrv) { case 0: return RES_PARERR; /* ramdisk_ioctl(cmd, buff); */ case 1: switch(cmd) { case CTRL_SYNC: return sdfs_sync(&sdfs); case GET_SECTOR_COUNT: return sdfs_sectors(&sdfs); case GET_BLOCK_SIZE: *((DWORD*)buff) = 1; // default when not known return RES_OK; } } return RES_PARERR; } void sdfs_cychdr(intptr_t exinf) { BYTE s; s = sdfs._is_initialized; if (WP()) /* Write protected */ s |= STA_PROTECT; else /* Write enabled */ s &= ~STA_PROTECT; if (gpio_read(&ins)) /* Card is in socket */ s &= ~STA_NODISK; else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); sdfs._is_initialized = s; } static int lock[TNUM_TSKID]; static int stack_pos[TNUM_TSKID]; void __malloc_lock(struct _reent *a) { ID tskid; ER ret; int count, sp; ret = get_tid(&tskid); if (ret != E_OK) { /*syslog(LOG_DEBUG, "get_tid %s", itron_strerror(ret));*/ Asm("bkpt #0"); } Asm("mov %0, sp" : "=r"(sp) :); if ((stack_pos[tskid - 1] == 0) || (stack_pos[tskid - 1] < sp)) stack_pos[tskid - 1] = sp; count = ++lock[tskid - 1]; if (count != 1) return; ret = wai_sem(SEM_MALLOC); if (ret != E_OK) { /*syslog(LOG_DEBUG, "wai_sem %s", itron_strerror(ret));*/ Asm("bkpt #0"); } } void __malloc_unlock(struct _reent *a) { ID tskid; ER ret; int count; ret = get_tid(&tskid); if (ret != E_OK) { /*syslog(LOG_DEBUG, "get_tid %s", itron_strerror(ret));*/ Asm("bkpt #0"); } count = --lock[tskid - 1]; if(count != 0) return; ret = sig_sem(SEM_MALLOC); if (ret != E_OK) { /*syslog(LOG_DEBUG, "sig_sem %s", itron_strerror(ret));*/ Asm("bkpt #0"); } } // Provide implementation of _sbrk (low-level dynamic memory allocation // routine) for GCC_ARM which compares new heap pointer with MSP instead of // SP. This make it compatible with RTX RTOS thread stacks. // Linker defined symbol used by _sbrk to indicate where heap should start. int __end__; uint32_t __HeapLimit; // Turn off the errno macro and use actual global variable instead. #undef errno int errno; static unsigned char* heap = (unsigned char*)&__end__; // Dynamic memory allocation related syscall. caddr_t _sbrk(int incr) { unsigned char* prev_heap = heap; unsigned char* new_heap = heap + incr; if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ errno = ENOMEM; return (caddr_t)-1; } heap = new_heap; return (caddr_t) prev_heap; } void reset_heap() { // .data extern uint8_t __malloc_av_[0x408]; extern uint8_t __malloc_sbrk_base[0x4]; extern uint8_t __malloc_trim_threshold[0x4]; // .bss extern uint8_t __malloc_top_pad[0x4]; extern uint8_t __malloc_current_mallinfo[0x28]; extern uint8_t __malloc_max_sbrked_mem[0x4]; extern uint8_t __malloc_max_total_mem[0x4]; // extern void *__etext; extern void *__data_start__; int offset = (int)&__etext - (int)&__data_start__; __malloc_lock(_REENT); memcpy(__malloc_av_, &__malloc_av_[offset], sizeof(__malloc_av_)); memcpy(__malloc_sbrk_base, &__malloc_sbrk_base[offset], sizeof(__malloc_sbrk_base)); memcpy(__malloc_trim_threshold, &__malloc_trim_threshold[offset], sizeof(__malloc_trim_threshold)); memset(__malloc_top_pad, 0, sizeof(__malloc_top_pad)); memset(__malloc_current_mallinfo, 0, sizeof(__malloc_current_mallinfo)); memset(__malloc_max_sbrked_mem, 0, sizeof(__malloc_max_sbrked_mem)); memset(__malloc_max_total_mem, 0, sizeof(__malloc_max_total_mem)); heap = (unsigned char*)&__end__; __malloc_unlock(_REENT); } void exit(int return_code) { Asm("bkpt #0"); reset_heap(); ext_tsk(); for(;;); }