/* * Start closing connection. */ static int NutPppClose(NUTFILE * fp) { PPPDCB *dcb = fp->nf_dev->dev_dcb; IpcpClose(fp->nf_dev); _close(dcb->dcb_fd); if (dcb->dcb_user) NutHeapFree(dcb->dcb_user); if (dcb->dcb_pass) NutHeapFree(dcb->dcb_pass); NutHeapFree(fp); return 0; }
/*! * \brief Unmount a previously mounted partition. * * Applications should not directly call this function, but use the high * level stdio routines for closing a previously opened file. * * \return 0 on success, -1 otherwise. */ static int At91MciUnmount(NUTFILE * nfp) { int rc = -1; if (nfp) { MCIFCB *fcb = (MCIFCB *) nfp->nf_fcb; if (fcb) { rc = fcb->fcb_fsdev->dev_ioctl(fcb->fcb_fsdev, FS_VOL_UNMOUNT, NULL); NutHeapFree(fcb); } NutHeapFree(nfp); } return rc; }
/*! * \brief Initialize the RTC in LPC 17xx controller * * \return 0 on success or -1 in case of an error. * */ static int Lpc17xxRtcInit(NUTRTC *rtc) { rtc->dcb = NutHeapAllocClear(sizeof(lpc17xx_rtc_dcb)); if (rtc->dcb == NULL) { return -1; } if (NutRegisterIrqHandler(&sig_RTC, Lpc17xxRtcInterrupt, rtc) != 0) { NutHeapFree(rtc->dcb); return -1; } /* Set up clock and power for RTC module */ SysCtlPeripheralClkEnable(CLKPWR_PCONP_PCRTC); /* Clear all register to be default */ LPC_RTC->ILR = 0x03; LPC_RTC->CCR = 0x00; LPC_RTC->CIIR = 0x00; LPC_RTC->AMR = 0xFF; LPC_RTC->CALIBRATION = 0x00; /* enable RTC (run) */ LPC_RTC->CCR |= RTC_CCR_CLKEN; ((lpc17xx_rtc_dcb *)rtc->dcb)->flags = 0x00000000; rtc->alarm = NULL; NutIrqEnable(&sig_RTC); return(0); }
int NutDestroyTwiBus( NUTTWIBUS *bus) { if (bus->bus_icb) { NutHeapFree( bus->bus_icb); } return 0; }
/*! * \brief Release a network buffer structure. * * Returns all memory previously allocated by a * network buffer to the available heap space. * * \param nb Points to an existing network buffer * structure, previously allocated by * NutNetBufAlloc(). * * \return 0 if successfull or -1 if the structure * contains previously released memory space. */ int NutNetBufFree(NETBUF * nb) { if(nb) { NutNetBufAlloc(nb, nb->nb_flags, 0); if (NutHeapFree(nb)) { return -1; } } return 0; }
/*! * \brief Process elapsed timers. * * This routine is called during context switch processing. * Applications should not use this function. */ void NutTimerProcessElapsed(void) { NUTTIMERINFO *tn; uint32_t ticks; uint32_t ticks_new; // calculate ticks since last call ticks = NutGetTickCount(); ticks_new = ticks - nut_ticks_resume; nut_ticks_resume = ticks; // process timers while (nutTimerList && ticks_new){ tn = nutTimerList; // subtract time if (ticks_new < tn->tn_ticks_left) { tn->tn_ticks_left -= ticks_new; ticks_new = 0; } else { ticks_new -= tn->tn_ticks_left; tn->tn_ticks_left = 0; } // elapsed if (tn->tn_ticks_left == 0){ // callback if (tn->tn_callback) { (*tn->tn_callback) (tn, (void *) tn->tn_arg); } // remove from list nutTimerList = nutTimerList->tn_next; if (nutTimerList) { nutTimerList->tn_prev = NULL; } if ((tn->tn_ticks_left = tn->tn_ticks) == 0) { #ifdef NUTDEBUG if (__os_trf) fprintf(__os_trs, " TIM %p free NutTimerProcessElapsed\n", tn); #endif NutHeapFree(tn); } else { // re-insert #ifdef NUTDEBUG if (__os_trf) fprintf(__os_trs, " TIM %p reinsert NutTimerProcessElapsed\n", tn); #endif NutTimerInsert(tn); } } } }
/*! * \brief Write argument list to a stream using a given format. * * Similar to vfprintf() except that the format string is located in * program memory. * * \param stream Pointer to a previously opened stream. * \param fmt Format string in program space containing conversion * specifications. * \param ap List of arguments. * * \return The number of characters written or a negative value to * indicate an error. */ int vfprintf_P(FILE * stream, PGM_P fmt, va_list ap) { int rc; char *rp; size_t rl; rl = strlen_P(fmt) + 1; if ((rp = NutHeapAlloc(rl)) == 0) return -1; memcpy_P(rp, fmt, rl); rc = _putf(_write, stream->iob_fd, rp, ap); NutHeapFree(rp); return rc; }
/*! * \brief Initialize the segmented buffer. * * \param size Number of bytes to allocate for the global buffer. * In systems with banked memory this parameter is * ignored and all banked memory is occupied for the * global buffer. In systems without banked memory, * the specified number of bytes is taken from heap * memory. * * \return Pointer to the first buffer segment or null on failures. */ char *NutSegBufInit(size_t size) { #if NUTBANK_COUNT segbuf_start = (char *)(NUTBANK_START); segbuf_end = (char *)(NUTBANK_START) + NUTBANK_SIZE; segbuf_total = (uint32_t) NUTBANK_COUNT *(uint32_t) NUTBANK_SIZE; #else if (size == 0) size = NutHeapAvailable() / 2; if (segbuf_start) { NutHeapFree(segbuf_start); } if ((segbuf_start = NutHeapAlloc(size)) != NULL) segbuf_end = segbuf_start + size; segbuf_total = size; #endif return NutSegBufReset(); }
int NutTraceInit(int size, char mode) { if (!trace_isinit) { // start timer1 at CPU frequency/8 and register interrupt service routine outb(TCCR1B, 2); NutRegisterIrqHandler(&sig_OVERFLOW1, NutTraceTimer1IRQ, 0); sbi(TIMSK, TOIE1); trace_isinit = 1; } if (size==0) { size = TRACE_SIZE_DEFAULT; } if (size != trace_size) { // current buffer is not of size that is wanted if (trace_items != 0) { // but memory is already allocated -> free old buffer NutHeapFree(trace_items); } // allocate buffer trace_items = (t_traceitem *)NutHeapAlloc(size * sizeof(t_traceitem)); if (trace_items == 0) { // failed return trace_size = 0; } else { trace_size = size; } } // if (mode == TRACE_MODE_OFF) { // // if terminal-cmd "trace size <val>" is called trace is started in // // default mode // mode = TRACE_MODE_DEFAULT; // } trace_mode = mode; NutTraceClear(); return trace_size; }
static void NutNetBufFreeData(NBDATA * nbd) { NutHeapFree(nbd->vp); nbd->vp = 0; nbd->sz = 0; }
/*! * \brief Mount a partition. * * Nut/OS doesn't provide specific routines for mounting. Instead routines * for opening files are used. * * Applications should not directly call this function, but use the high * level stdio routines for opening a file. * * \param dev Pointer to the MMC device. * \param name Partition number followed by a slash followed by a name * of the file system device. Both items are optional. If no * file system driver name is given, the first file system * driver found in the list of registered devices will be * used. If no partition number is specified or if partition * zero is given, the first active primary partition will be * used. * \param mode Opening mode. Currently ignored, but * \code _O_RDWR | _O_BINARY \endcode should be used for * compatibility with future enhancements. * \param acc File attributes, ignored. * * \return Pointer to a newly created file pointer to the mounted * partition or NUTFILE_EOF in case of any error. */ static NUTFILE *At91MciMount(NUTDEVICE * dev, CONST char *name, int mode, int acc) { int partno = 0; int i; NUTDEVICE *fsdev; NUTFILE *nfp; MCIFCB *fcb; DOSPART *part; MCIFC *ifc = (MCIFC *) dev->dev_icb; FSCP_VOL_MOUNT mparm; if (At91MciDiscover(ifc)) { errno = ENODEV; return NUTFILE_EOF; } /* Parse the name for a partition number and a file system driver. */ if (*name) { partno = atoi(name); do { name++; } while (*name && *name != '/'); if (*name == '/') { name++; } } #ifdef NUTDEBUG printf("['%s'-PART%d]", name, partno); #endif /* * Check the list of registered devices for the given name of the * files system driver. If none has been specified, get the first * file system driver in the list. Hopefully the application * registered one only. */ for (fsdev = nutDeviceList; fsdev; fsdev = fsdev->dev_next) { if (*name == 0) { if (fsdev->dev_type == IFTYP_FS) { break; } } else if (strcmp(fsdev->dev_name, name) == 0) { break; } } if (fsdev == 0) { #ifdef NUTDEBUG printf("[No FSDriver]"); #endif errno = ENODEV; return NUTFILE_EOF; } if ((fcb = NutHeapAllocClear(sizeof(MCIFCB))) == 0) { errno = ENOMEM; return NUTFILE_EOF; } fcb->fcb_fsdev = fsdev; /* Initialize MMC access mutex semaphore. */ NutEventPost(&mutex); /* Read MBR. */ if (At91MciReadSingle(ifc, 0, fcb->fcb_blkbuf)) { NutHeapFree(fcb); return NUTFILE_EOF; } /* Read partition table. */ part = (DOSPART *) & fcb->fcb_blkbuf[DOSPART_SECTORPOS]; for (i = 1; i <= 4; i++) { if (partno) { if (i == partno) { /* Found specified partition number. */ fcb->fcb_part = *part; break; } } else if (part->part_state & 0x80) { /* Located first active partition. */ fcb->fcb_part = *part; break; } part++; } if (fcb->fcb_part.part_type == PTYPE_EMPTY) { NutHeapFree(fcb); return NUTFILE_EOF; } if ((nfp = NutHeapAlloc(sizeof(NUTFILE))) == 0) { NutHeapFree(fcb); errno = ENOMEM; return NUTFILE_EOF; } nfp->nf_next = 0; nfp->nf_dev = dev; nfp->nf_fcb = fcb; /* * Mount the file system volume. */ mparm.fscp_bmnt = nfp; mparm.fscp_part_type = fcb->fcb_part.part_type; if (fsdev->dev_ioctl(fsdev, FS_VOL_MOUNT, &mparm)) { At91MciUnmount(nfp); return NUTFILE_EOF; } return nfp; }