Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/flickernoise
base: bf1a502
...
head fork: m-labs/flickernoise
compare: 2d5c99e
  • 8 commits
  • 8 files changed
  • 0 commit comments
  • 3 contributors
1  .gitignore
View
@@ -3,3 +3,4 @@ src/obj
doc/handbook.aux
doc/handbook.log
doc/handbook.pdf
+TAGS
15 flash/flash.sh
View
@@ -1,21 +1,22 @@
-#!/bin/sh
+#!/bin/bash
set -e
ADDRESS=0x920000
-if [ "$1" == "rescue" ]; then
+if [ "$1" == "rescue" ] || [ "$2" == "rescue" ]; then
ADDRESS=0x2E0000
fi
-TARGET=flickernoise.fbiz
-if [ "$2" == "nocompress" ]; then
- TARGET=flickernoise.fbi
+TARGET=flickernoise.fbi
+if [ "$2" == "compress" ] || [ "$1" == "compress" ] ; then
+ TARGET=flickernoise.fbiz
fi
make -C ../src bin/${TARGET}
BATCH_FILE=`mktemp`
cat > ${BATCH_FILE}<<EOF
+
cable milkymist
detect
instruction CFG_OUT 000100 BYPASS
@@ -27,7 +28,11 @@ detectflash 0
endian big
flashmem ${ADDRESS} ../src/bin/${TARGET} noverify
pld reconfigure
+
EOF
jtag -n ${BATCH_FILE}
+more ${BATCH_FILE}
rm -f ${BATCH_FILE}
+
+echo "Done"
8 src/Makefile
View
@@ -13,7 +13,7 @@ OBJDIR=obj
BINDIR=bin
# base
-OBJS=version.o shellext.o sysconfig.o config.o fb.o input.o keymap.o fbgrab.o shortcuts.o osc.o png.o flashvalid.o main.o
+OBJS=yaffs.o version.o shellext.o sysconfig.o config.o fb.o input.o keymap.o fbgrab.o shortcuts.o osc.o png.o flashvalid.o main.o
# GUI
OBJS+=messagebox.o filedialog.o resmgr.o guirender.o performance.o cp.o keyboard.o ir.o audio.o midi.o oscsettings.o dmxspy.o dmxdesk.o dmx.o videoin.o rsswall.o patcheditor.o monitor.o firstpatch.o filemanager.o sysettings.o about.o patchpool.o flash.o shutdown.o
@@ -68,9 +68,13 @@ $(BINDIR)/flickernoise.fbiz: $(BINDIR)/flickernoise.lzma
load: $(BINDIR)/flickernoise.bin
cp $< /var/lib/tftpboot/boot.bin
+flash:
+ (cd ../flash && ./flash.sh rescue)
+ (cd ../flash && ./flash.sh)
+
clean:
rm -f $(BINDIR)/flickernoise $(BINDIR)/flickernoise.bin
rm -f $(BINDIR)/flickernoise.lzma $(BINDIR)/flickernoise.fbi $(BINDIR)/flickernoise.fbiz
rm -f $(POBJS)
-.PHONY: clean load
+.PHONY: clean load flash
1  src/flash.c
View
@@ -28,7 +28,6 @@
#include <bsp/milkymist_flash.h>
#include <curl/curl.h>
-#include <curl/types.h>
#include <curl/easy.h>
#include <mtklib.h>
4 src/flashvalid.c
View
@@ -99,7 +99,7 @@ int flashvalid_application(const char *filename)
}
length = 0;
- crc = crc32(0L, Z_NULL, 0);
+ crc = z_crc32(0L, Z_NULL, 0);
while(1) {
r = read(fd, buf, sizeof(buf));
@@ -108,7 +108,7 @@ int flashvalid_application(const char *filename)
return FLASHVALID_ERROR_IO;
}
if(r == 0) break;
- crc = crc32(crc, buf, r);
+ crc = z_crc32(crc, buf, r);
length += r;
}
7 src/main.c
View
@@ -46,9 +46,10 @@
#include <rtems/rtems_bsdnet.h>
#include <rtems/ftpd.h>
#include <rtems/telnetd.h>
-#include <yaffs.h>
+#include <yaffs/rtems_yaffs.h>
#include <curl/curl.h>
+#include "yaffs.h"
#include "version.h"
#include "videoinreconf.h"
#include "shellext.h"
@@ -295,8 +296,8 @@ rtems_telnetd_config_table rtems_telnetd_config = {
const rtems_filesystem_table_t rtems_filesystem_table[] = {
{ RTEMS_FILESYSTEM_TYPE_IMFS, IMFS_initialize },
{ RTEMS_FILESYSTEM_TYPE_DOSFS, rtems_dosfs_initialize },
- { RTEMS_FILESYSTEM_TYPE_NFS, rtems_nfsfs_initialize },
- { "yaffs", yaffs_initialize },
+ { RTEMS_FILESYSTEM_TYPE_NFS, rtems_nfs_initialize },
+ { RTEMS_FILESYSTEM_TYPE_YAFFS, yaffs_initialize },
{ NULL, NULL }
};
371 src/yaffs.c
View
@@ -0,0 +1,371 @@
+/*
+ * Flickernoise
+ * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/seterr.h>
+#include <rtems/userenv.h>
+#include <bsp/milkymist_flash.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <yaffs/rtems_yaffs.h>
+#include <yaffs/yaffs_packedtags2.h>
+
+#include "yaffs.h"
+
+#define MAXIMUM_YAFFS_MOUNTS 2
+
+struct yaffs_softc {
+ struct yaffs_dev *dev;
+ dev_t flashdev;
+ unsigned int size;
+ unsigned int blocksize;
+ rtems_yaffs_os_handler free_os_context;
+};
+
+/* WARNING: Those I/O helpers:
+ * - do not open or close the device
+ * - set iop to NULL
+ * The device driver must be able to support this.
+ */
+
+static rtems_status_code my_ioctl(dev_t dev, int request, void *p)
+{
+ rtems_libio_ioctl_args_t args;
+
+ args.iop = NULL;
+ args.command = request;
+ args.buffer = p;
+ return rtems_io_control(rtems_filesystem_dev_major_t(dev), rtems_filesystem_dev_minor_t(dev), &args);
+}
+
+static rtems_status_code my_read(dev_t dev, void *buffer, int len, int offset)
+{
+ rtems_libio_rw_args_t args;
+
+ args.iop = NULL;
+ args.offset = offset;
+ args.buffer = buffer;
+ args.count = len;
+ args.flags = 0;
+ return rtems_io_read(rtems_filesystem_dev_major_t(dev), rtems_filesystem_dev_minor_t(dev), &args);
+}
+
+static rtems_status_code my_write(dev_t dev, const void *buffer, int len, int offset)
+{
+ rtems_libio_rw_args_t args;
+
+ args.iop = NULL;
+ args.offset = offset;
+ args.buffer = (void *)buffer;
+ args.count = len;
+ args.flags = 0;
+ return rtems_io_write(rtems_filesystem_dev_major_t(dev), rtems_filesystem_dev_minor_t(dev), &args);
+}
+
+/* Flash access functions */
+
+#define NOR_CHUNK_DATA_SIZE 512
+#define NOR_CHUNK_TAGS_SIZE 16
+#define NOR_CHUNK_WHOLE_SIZE (NOR_CHUNK_DATA_SIZE+NOR_CHUNK_TAGS_SIZE)
+
+static unsigned int chunk_address(struct yaffs_dev *dev, int c)
+{
+ struct yaffs_softc *sc = (struct yaffs_softc *)dev->driver_context;
+ unsigned int chunks_per_block = dev->param.chunks_per_block;
+ return sc->blocksize*(c/chunks_per_block)
+ + NOR_CHUNK_WHOLE_SIZE*(c%chunks_per_block);
+}
+
+static int write_chunk_tags(struct yaffs_dev *dev, int nand_chunk, const u8 *data, const struct yaffs_ext_tags *tags)
+{
+ struct yaffs_softc *sc = (struct yaffs_softc *)dev->driver_context;
+ unsigned int address;
+
+ //printf("%s %d (data=%p tags=%p)\n", __func__, nand_chunk, data, tags);
+ address = chunk_address(dev, nand_chunk);
+ if(data)
+ my_write(sc->flashdev, data, NOR_CHUNK_DATA_SIZE, address);
+ if(tags) {
+ struct yaffs_packed_tags2_tags_only x;
+ yaffs_pack_tags2_tags_only(&x, tags);
+ my_write(sc->flashdev, &x, NOR_CHUNK_TAGS_SIZE, address+NOR_CHUNK_DATA_SIZE);
+ }
+ return YAFFS_OK;
+}
+
+static int read_chunk_tags(struct yaffs_dev *dev, int nand_chunk, u8 *data, struct yaffs_ext_tags *tags)
+{
+ struct yaffs_softc *sc = (struct yaffs_softc *)dev->driver_context;
+ unsigned int address;
+
+ //printf("%s %d (data=%p tags=%p)\n", __func__, nand_chunk, data, tags);
+ address = chunk_address(dev, nand_chunk);
+ if(data)
+ my_read(sc->flashdev, data, NOR_CHUNK_DATA_SIZE, address);
+ if(tags) {
+ struct yaffs_packed_tags2_tags_only x;
+ my_read(sc->flashdev, &x, NOR_CHUNK_TAGS_SIZE, address+NOR_CHUNK_DATA_SIZE);
+ yaffs_unpack_tags2_tags_only(tags, &x);
+ }
+ return YAFFS_OK;
+}
+
+static int bad_block(struct yaffs_dev *dev, int blockId)
+{
+ struct yaffs_ext_tags tags;
+ int chunk_nr;
+
+ chunk_nr = blockId * dev->param.chunks_per_block;
+
+ read_chunk_tags(dev, chunk_nr, NULL, &tags);
+ tags.block_bad = 1;
+ write_chunk_tags(dev, chunk_nr, NULL, &tags);
+
+ return YAFFS_OK;
+}
+
+static int query_block(struct yaffs_dev *dev, int blockId, enum yaffs_block_state *state, u32 *seq_number)
+{
+ struct yaffs_ext_tags tags;
+ int chunk_nr;
+
+ *seq_number = 0;
+
+ chunk_nr = blockId * dev->param.chunks_per_block;
+
+ read_chunk_tags(dev, chunk_nr, NULL, &tags);
+ if(tags.block_bad)
+ *state = YAFFS_BLOCK_STATE_DEAD;
+ else if(!tags.chunk_used)
+ *state = YAFFS_BLOCK_STATE_EMPTY;
+ else if(tags.chunk_used) {
+ *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
+ *seq_number = tags.seq_number;
+ }
+
+ return YAFFS_OK;
+}
+
+static int erase(struct yaffs_dev *dev, int blockId)
+{
+ struct yaffs_softc *sc = dev->driver_context;
+
+ my_ioctl(sc->flashdev, FLASH_ERASE_BLOCK, (void *)(blockId*sc->blocksize));
+
+ return YAFFS_OK;
+}
+
+static int initialise(struct yaffs_dev *dev)
+{
+ return YAFFS_OK;
+}
+
+static int mount_sema_created;
+static rtems_id mount_sema;
+static struct yaffs_softc *current_mounts[MAXIMUM_YAFFS_MOUNTS];
+
+static void unmount_handler(struct yaffs_dev *dev, void *os_context)
+{
+ struct yaffs_softc *softc = dev->driver_context;
+ int i;
+
+ rtems_semaphore_obtain(mount_sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+
+ for(i=0;i<MAXIMUM_YAFFS_MOUNTS;i++) {
+ if(current_mounts[i] == softc) {
+ current_mounts[i] = NULL;
+ break;
+ }
+ }
+
+ softc->free_os_context(dev, os_context);
+ free(softc);
+ free(dev);
+
+ rtems_semaphore_release(mount_sema);
+}
+
+static int flush_task_running;
+static rtems_id flush_task_id;
+
+static rtems_task flush_task(rtems_task_argument argument)
+{
+ int i;
+ struct yaffs_softc *sc;
+ rtems_yaffs_default_os_context *os_context;
+
+ while(1) {
+ rtems_task_wake_after(10*100);
+ rtems_semaphore_obtain(mount_sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ for(i=0;i<MAXIMUM_YAFFS_MOUNTS;i++) {
+ sc = current_mounts[i];
+ if(sc != NULL) {
+ os_context = sc->dev->os_context;
+ os_context->os_context.lock(sc->dev, os_context);
+ yaffs_flush_whole_cache(sc->dev);
+ os_context->os_context.unlock(sc->dev, os_context);
+ }
+ }
+ rtems_semaphore_release(mount_sema);
+ }
+}
+
+int yaffs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry, const void *data)
+{
+ int i;
+ int index;
+ struct yaffs_dev *dev;
+ struct yaffs_param *param;
+ struct yaffs_softc *softc;
+ rtems_yaffs_default_os_context *os_context;
+ struct stat st;
+ rtems_yaffs_mount_data md;
+ rtems_status_code sc1, sc2;
+ int r;
+
+ if(!mount_sema_created) {
+ sc1 = rtems_semaphore_create(
+ rtems_build_name('Y', 'A', 'F', 'M'),
+ 1,
+ RTEMS_LOCAL
+ | RTEMS_BINARY_SEMAPHORE
+ | RTEMS_INHERIT_PRIORITY
+ | RTEMS_PRIORITY,
+ 0,
+ &mount_sema
+ );
+ if(sc1 != RTEMS_SUCCESSFUL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ mount_sema_created = 1;
+ }
+
+ rtems_semaphore_obtain(mount_sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ index = -1;
+ for(i=0;i<MAXIMUM_YAFFS_MOUNTS;i++) {
+ if(current_mounts[i] == NULL) {
+ index = i;
+ break;
+ }
+ }
+ rtems_semaphore_release(mount_sema);
+ if(index == -1) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ dev = malloc(sizeof(struct yaffs_dev));
+ if(dev == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ memset(dev, 0, sizeof(struct yaffs_dev));
+
+ softc = malloc(sizeof(struct yaffs_softc));
+ if(softc == NULL) {
+ errno = ENOMEM;
+ free(dev);
+ return -1;
+ }
+ softc->dev = dev;
+
+ if(stat(mt_entry->dev, &st) < 0) {
+ errno = EIO;
+ free(softc);
+ free(dev);
+ return -1;
+ }
+ softc->flashdev = st.st_rdev;
+ sc1 = my_ioctl(softc->flashdev, FLASH_GET_SIZE, &softc->size);
+ sc2 = my_ioctl(softc->flashdev, FLASH_GET_BLOCKSIZE, &softc->blocksize);
+ if((sc1 != RTEMS_SUCCESSFUL)||(sc2 != RTEMS_SUCCESSFUL)) {
+ errno = EIO;
+ free(softc);
+ free(dev);
+ return -1;
+ }
+
+ os_context = malloc(sizeof(rtems_yaffs_default_os_context));
+ if(os_context == NULL) {
+ errno = ENOMEM;
+ free(softc);
+ free(dev);
+ return -1;
+ }
+ r = rtems_yaffs_initialize_default_os_context(os_context);
+ if(r == -1) {
+ free(os_context);
+ free(softc);
+ free(dev);
+ return -1;
+ }
+ softc->free_os_context = os_context->os_context.unmount;
+ os_context->os_context.unmount = unmount_handler;
+
+ /* set parameters */
+ dev->driver_context = softc;
+ dev->os_context = os_context;
+ dev->read_only = 0;
+
+ param = &(dev->param);
+ param->name = mt_entry->dev;
+
+ param->start_block = 0;
+ param->end_block = softc->size/softc->blocksize - 1;
+ param->chunks_per_block = softc->blocksize/NOR_CHUNK_WHOLE_SIZE;
+ param->total_bytes_per_chunk = NOR_CHUNK_WHOLE_SIZE;
+ param->n_reserved_blocks = 5;
+ param->n_caches = 15;
+ param->inband_tags = 1;
+ param->is_yaffs2 = 1;
+ param->no_tags_ecc = 1;
+
+ /* set callbacks */
+ param->write_chunk_tags_fn = write_chunk_tags;
+ param->read_chunk_tags_fn = read_chunk_tags;
+ param->bad_block_fn = bad_block;
+ param->query_block_fn = query_block;
+ param->erase_fn = erase;
+ param->initialise_flash_fn = initialise;
+
+ md.dev = dev;
+ r = rtems_yaffs_mount_handler(mt_entry, &md);
+ if(r == -1) {
+ errno = ENOMEM;
+ softc->free_os_context(dev, os_context);
+ free(softc);
+ free(dev);
+ return -1;
+ }
+
+ current_mounts[index] = softc;
+ if(!flush_task_running) {
+ sc1 = rtems_task_create(rtems_build_name('F', 'L', 'S', 'H'), 220, 256*1024,
+ RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR,
+ 0, &flush_task_id);
+ assert(sc1 == RTEMS_SUCCESSFUL);
+ sc1 = rtems_task_start(flush_task_id, flush_task, 0);
+ assert(sc1 == RTEMS_SUCCESSFUL);
+ flush_task_running = 1;
+ }
+
+ return 0;
+}
23 src/yaffs.h
View
@@ -0,0 +1,23 @@
+/*
+ * Flickernoise
+ * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __YAFFS_H
+#define __YAFFS_H
+
+int yaffs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry, const void *data);
+
+#endif /* __YAFFS_H */

No commit comments for this range

Something went wrong with that request. Please try again.