Notes about using the eCos RTOS. This discusses general eCos setup issues, OpenOCD + Olimex ARM-OCD-USB setup issues, and Atmel AT91SAM7 platform specifics for both 'S' and 'X' variants. Entry: Getting Started Date: Sat Jul 10 10:22:03 CEST 2010 A little history[2]. To get started, follow[1]. I'm using mirror: http://ftp.gwdg.de/pub/misc/sources.redhat.com/ecos Installing arm-eabi and i386 Ecos is mainly setup as a single application running on the target. GDB connects to the bootloader (RedBoot). The configtool gives library error: tom@zni:/opt/xc/ecos$ ecos-3.0/tools/bin/configtool ecos-3.0/tools/bin/configtool: error while loading shared libraries: libgtk-x11-2.0.so.0: cannot open shared object file: No such file or directory The library is in /usr/lib so probably some debian issue. Looks like it's the dreaded 64-bit library problem again. This worked: apt-get install ia32-libs-gtk In the 32-bit chroot it needs: apt-get install libstdc++5 Trying to build at91sam7x evaluation kit target following [3]. mkdir /tmp/ecos-arm cd /tmp/ecos-arm ecosconfig new at91sam7xek ecosconfig tree ecosconfig check make make tests This generates the file install/lib/libtarget.a Next: the hello world app[4]. hello.c: /* this is a simple hello world program */ #include int main(void) { printf("Hello, eCos world!\n"); return 0; } To compile: arm-eabi-gcc -g \ -I/tmp/ecos-arm/install/include \ hello.c \ -L/tmp/ecos-arm/install/lib \ -Ttarget.ld -nostdlib Here `arm-eabi-gcc' is in the path after sourcing /opt/xc/ecos/ecosenv.sh and the /tmp/ecos-arm directory is the toplevel build dir used above. The applications all seem to hang in some kind of wait loop in function: wait_pmc_sr_0 -- maybe simulating the target board doesn't work like that, and ecosconfig needs a different target, i.e. linux (Linux synthetic target). This gives the error: make[1]: Entering directory `/tmp/ecos-linux/services/memalloc/common/v3_0' i686-pc-linux-gnu-gcc -finline-limit=7000 -Wall -Wpointer-arith -Wundef -Woverloaded-virtual -Wno-write-strings -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -I/tmp/ecos-linux/install/include -I/opt/xc/ecos/ecos-3.0/packages/services/memalloc/common/v3_0 -I/opt/xc/ecos/ecos-3.0/packages/services/memalloc/common/v3_0/src -I/opt/xc/ecos/ecos-3.0/packages/services/memalloc/common/v3_0/tests -I. -Wp,-MD,heapgen.tmp -E /opt/xc/ecos/ecos-3.0/packages/services/memalloc/common/v3_0/src/heapgen.cpp -o heapgeninc.tcl make[1]: i686-pc-linux-gnu-gcc: Command not found See [5]: edit ecos.ecc and provide a user_value for CYGBLD_GLOBAL_PREFIX of "", and then rerun ecosconfig tree. Then starts building but runs into 64bit assembler problems: gcc -c -I/tmp/ecos-linux/install/include -I/opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0 -I/opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/src -I/opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/tests -I. -I/opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/src/ -finline-limit=7000 -Wall -Wpointer-arith -Wstrict-prototypes -Wundef -Wno-write-strings -g -O2 -ffunction-sections -fdata-sections -fno-exceptions -Wp,-MD,src/syscall-i386-linux-1.0.tmp -o src/hal_synth_i386linux_syscall-i386-linux-1.0.o /opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/src/syscall-i386-linux-1.0.S /opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/src/syscall-i386-linux-1.0.S: Assembler messages: /opt/xc/ecos/ecos-3.0/packages/hal/synth/i386linux/v3_0/src/syscall-i386-linux-1.0.S:386: Error: suffix or operands invalid for `push' So best to use 32bit chroot I guess. Ok, this works. mkdir /tmp/ecos-linux cd /tmp/ecos-linux ecosconfig new linux ecosconfig tree make make tests install/tests/kernel/v3_0/tests/bin_sem0 This gives: PASS: EXIT: [1] http://ecos.sourceware.org/getstart.html [2] http://en.wikipedia.org/wiki/ECos [3] http://ecos.sourceware.org/docs-3.0/user-guide/using-ecosconfig-on-linux.html [4] http://ecos.sourceware.org/docs-3.0/user-guide/building-and-running-sample-appliations.html [5] http://sourceware.org/ml/ecos-discuss/2001-09/msg00146.html [6] http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg09806.html Entry: eCos C/C++ mixing Date: Sat Jul 10 17:10:13 CEST 2010 packages/infra/v3_0/include/cyg_type.h: // __externC is used in mixed C/C++ headers to force C linkage on an external // definition. It avoids having to put all sorts of ifdefs in. #ifdef __cplusplus # define __externC extern "C" #else # define __externC extern #endif // Also define externC for now - but it is deprecated #define externC __externC Entry: Scheduler Date: Sat Jul 10 17:13:28 CEST 2010 At (very brief) first sight, eCos architecture seems to be quite straightforward monolithic C/C++ application. Code is grouped in ``packages'' that can be combined, checked by some dependency management. Some compile-time options are implemented using CPP macros. The more interesting questions are about events, tasks and state machines. Entry: eCos threads Date: Fri Aug 6 11:13:50 CEST 2010 Something doesn't work as I expect it. Calling cyg_thread_delay() called from the cyg_user_start() thread doesn't seem to work. Is the main thread a thread or something special? Indeed: it runs _before_ the scheduler is started. From [1]: ``When you return control from cyg_user_start(), cyg_start() will then invoke the scheduler, and any threads you created and resumed in cyg_user_start() will be executed.'' [1] http://ecos.sourceware.org/docs-1.1/ref/ecos-ref/system-startup-cyg-user-start.html Entry: eCos primitives for timers and queues Date: Wed Aug 11 14:39:05 CEST 2010 I need: - Code wake-up after time-out. - Message queues. For code wake-up it seems alarms[1] are the appropriate mechanism. cyg_alarm_create() cyg_alarm_initialize() Q: - can we create and destroy alarms easily? - how to behave inside an alarm handler? Apparently creation and enabling are expensive operations. (??) Anyways. The more pressing problem is to see what we can do inside. I get plenty of crashes trying to diag_printf from a handler. What stack does it run on actually? From [3] we get: ``The alarm function is invoked when a counter tick occurs, in other words when there is a call to cyg_counter_tick, and will happen in the same context. If the alarm is associated with the system's real-time clock then this will be DSR context, following a clock interrupt. If the alarm is associated with some other application-specific counter then the details will depend on how that counter is updated.'' What is allowed in the Deferred Service Routine (DSR) context? It seems we can't do much else than waking up a thread, i.e. using a condition variable[4]. [1] http://ecos.sourceware.org/docs-latest/user-guide/clocks-and-alarm-handlers.htlm [2] http://ecos.sourceware.org/docs-latest/ref/kernel.html [3] http://ecos.sourceware.org/docs-latest/ref/kernel-alarms.html [4] http://ecos.sourceware.org/docs-latest/ref/kernel-condition-variables.html Entry: Execution contexts in eCos Date: Thu Aug 12 10:50:24 CEST 2010 It seems there are 3 levels: ISR, DSR and thread. To communicate from DSR -> thread there are a couple of options: - condition variables - event flags - semaphores Entry: Blocking serial port input Date: Mon Sep 6 14:05:35 CEST 2010 How can we arrange to get woken up in a meaningful way when there is data available in the input buffer? I.e. wake up when an end-of-line character is received. This is possible, but using the TTY layer[1]. [1] http://digitais.ist.utl.pt/ec-sc/0405/docs/ecos-2.0b1/doc/html/ref/io-tty-driver.html Entry: Stack overflow detection Date: Thu Sep 9 11:10:05 CEST 2010 I thought there was some mechanism to check. Or is this only eCosPro? Entry: qemu + eCos Date: Sun Sep 19 22:14:13 CEST 2010 [1] http://www.codeconfidence.com/technote-0002.shtml [2] http://gitorious.org/qemu-at91sam7 Entry: AT91SAM7S-EK Date: Wed Feb 2 18:38:27 EST 2011 I've got it compiling and loading throug Olimex OCD[1], but I'm wondering how to figure out what the debug port and baud rate is. Tracing through the code I end up at: hal_diag.c : cyg_hal_plf_serial_putc() It writes to the base address 0xfffff200 + AT91_US_CSR (0x14) This seems to be the config value that sets it: # GDB serial port baud rate # This option controls the baud rate used for the GDB connection. # cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD { # Flavor: data user_value 9600 # value_source user # Default value: 38400 # Legal values: 9600 19200 38400 57600 115200 }; [1] entry://../electronics/20110202-122238 Entry: Synth target 64bit Date: Mon Feb 7 09:45:06 EST 2011 Building an eCos synth target program on 64 bit linux I get the following error message: /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgcc.a when searching for libgcc.a /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgcc.a when searching for libgcc.a /usr/bin/ld: cannot find libgcc.a collect2: ld returned 1 exit status make: *** [/home/tom/git-private/dbb_trailer/build/out/synth/test-spi] Error 1 According to [1] the fix is to "apt-get install g++-multilib" Verified: works. [1] http://blog.gnu-designs.com/fix-for-incompatible-libstdc-error-message Entry: eCos CVS Date: Mon Feb 7 12:16:43 EST 2011 Starting from scratch, I'd like to setup an eCos CVS build and a configuration for the Atmel AT91SAM7S256-EK board. cvs -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos login cvs -z3 -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos cd ecos mkdir build cd build ../configure make Trouble here is that host tools are necesary. I moved the ecos-cvs directory to the /opt/xc/ecos directory that contains the meta package which also contains the ecos-3.0 tree installed by ecos-install.tcl[2]. The ecos-cvs and ecos-3.0 look similar, except for the ecos-3.0/tools directory. The doc[1] says "The current set of sources in the CVS repository requires recent versions of the host-side configuration tools for correct operation." So, I'm using the ecosenv.sh from the distro with only the ecos-3.0 dir changed to ecos-cvs. mkdir /opt/xc/ecos/build_at91sam7sek cd /opt/xc/ecos/build_at91sam7sek ecosconfig new at91sam7xek ecosconfig tree make make tests [1] http://ecos.sourceware.org/anoncvs.html [2] http://ecos.sourceware.org/getstart.html Entry: Ecos multi build script Date: Mon Feb 7 13:23:06 EST 2011 Building different versions X different targets. [1] http://zwizwa.be/darcs/ecos/bin/ecos_build Entry: Ecos synthetic target Date: Mon Feb 7 14:43:32 EST 2011 Using the ecos_build[1] script building the synth target is: cd /opt/xc/ecos ./ecos_build cvs linux Note that the 3.0 build require the i686-pc-linux-gnu- prefixes, while 3.0.9 and current CVS no longer require them. Entry: OpenOCD AT91SAM7S Date: Mon Feb 7 15:27:05 EST 2011 Some gdb scripts here[1]. Maybe it needs some delays? debug_level 3 fast disable jtag_speed 200 jtag_nsrst_delay 200 jtag_ntrst_delay 200 script target/eir-sam7se512.cfg jtag_khz 6000 fast enable init debug_level 1 [1] http://embdev.net/topic/136198 Entry: Building Date: Mon Feb 7 16:58:54 EST 2011 This is the current configure syntax for building an eCos application. It needs to know the tool chan prefix, the insall dir with the libraries and includes, and the target specification (to set the linker flags). ../configure --cmdprefix=arm-eabi- --prefix=/opt/xc/ecos/build_3.0_at91sam7sek/install --target=eCos --enable-debug This could be simplified a bit as I have to look this up every time.. This builds (also tried with build_cvs_at91sam7sek, but the resulting binary refuses to load in OpenOCD: Info : accepting 'gdb' connection from 3333 Warn : acknowledgment received, but no packet pending Error: status register: 0x30005 Error: Lock Error Bit Detected, Operation Abort Error: failed erasing sectors 0 to 11 Error: flash_erase returned -902 Info : dropped 'gdb' connection The gdb console says: Error erasing flash with vFlashErase packet According to [1] it's the lock bits. Hmm.. I ran into this before on the other ARM board. (indeed: [2]) Why is it that it works fine for the ecospro 3.0.9 binaries, but not for the ecos 3.0 or ecos CVS ones? Let's objdump to compare the two binaries to see if there are different sections or addresses. tom@zoo:/tmp/check$ arm-eabi-objdump -h test-spi test-spi: file format elf32-littlearm Sections: Idx Name Size VMA LMA File off Algn 0 .rom_vectors 00000040 00110000 00110000 00008000 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .text 000091c4 00110040 00110040 00008040 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .rodata 00000af2 00119204 00119204 00011204 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .got 000000d0 00119cf8 00119cf8 00011cf8 2**2 CONTENTS, ALLOC, LOAD, DATA 4 .fixed_vectors 00000140 00200040 00200040 00018c20 2**5 CONTENTS, READONLY 5 .data 00000aa0 00200180 00119dc8 00018180 2**3 CONTENTS, ALLOC, LOAD, CODE 6 .bss 000053a5 00200c20 0011a868 00018c20 2**4 ALLOC 7 .ARM.attributes 0000002c 00000000 00000000 00018d60 2**0 CONTENTS, READONLY 8 .comment 00000cc4 00000000 00000000 00018d8c 2**0 CONTENTS, READONLY tom@zoo:/tmp/check$ arm-eabi-objdump -h demo demo: file format elf32-littlearm Sections: Idx Name Size VMA LMA File off Algn 0 .rom_vectors 00000040 00100000 00100000 00008000 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .text 0000d37c 00100040 00100040 00008040 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .rodata 000002ec 0010d3bc 0010d3bc 000153bc 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .fixed_vectors 00000140 00200040 00200040 000185a0 2**5 CONTENTS, READONLY 4 .data 0000041c 00200180 0010d6a8 00018180 2**2 CONTENTS, ALLOC, LOAD, DATA 5 .bss 000043a0 0020059c 0010dac4 0001859c 2**4 ALLOC 6 .ARM.attributes 0000002c 00000000 00000000 000186e0 2**0 CONTENTS, READONLY 7 .comment 000009ab 00000000 00000000 0001870c 2**0 CONTENTS, READONLY Indeed. For flash, `demo' starts at 00100000 while `test-spi' starts at `00110000'. This is probably reflected in the .ecc for each. Then it's probably the boot loader that's protected in the fresh AT91SAM7 board (SAM-BA). Looks like it's safe to remove it. (gdb) monitor flash info 0 #0 : at91sam7 at 0x00100000, size 0x00040000, buswidth 4, chipwidth 0 # 0: 0x00000000 (0x4000 16kB) protected # 1: 0x00004000 (0x4000 16kB) protected # 2: 0x00008000 (0x4000 16kB) not protected # 3: 0x0000c000 (0x4000 16kB) not protected # 4: 0x00010000 (0x4000 16kB) not protected # 5: 0x00014000 (0x4000 16kB) not protected # 6: 0x00018000 (0x4000 16kB) not protected # 7: 0x0001c000 (0x4000 16kB) not protected # 8: 0x00020000 (0x4000 16kB) not protected # 9: 0x00024000 (0x4000 16kB) not protected # 10: 0x00028000 (0x4000 16kB) not protected # 11: 0x0002c000 (0x4000 16kB) not protected # 12: 0x00030000 (0x4000 16kB) not protected # 13: 0x00034000 (0x4000 16kB) not protected # 14: 0x00038000 (0x4000 16kB) not protected # 15: 0x0003c000 (0x4000 16kB) not protected at91sam7 driver information: Chip is AT91SAM7S256 Cidr: 0x270d0940 | Arch: 0x0070 | Eproc: ARM7TDMI | Version: 0x000 | Flashsize: 0x00040000 Master clock (estimated): 48000 KHz | External clock: 18432 KHz Pagesize: 256 bytes | Lockbits(16): 2 0x0003 | Pages in lock region: 128 Securitybit: 0 | Nvmbits(2): 0 0x0 [1] http://embdev.net/topic/129413 [2] entry://../electronics/20100915-144730 Entry: SAM-BA Date: Mon Feb 7 19:09:56 EST 2011 So what's this SAM-BA bootloader about? It runs only under windows and doesn't seem to provide any extra value over a JTAG OCD with gdbserver. Seems to be mostly for serial value over an OCDport programming. [1] http://www.atmel.com/dyn/resources/prod_documents/doc6281.pdf Entry: Olimex ARM-OCD-USB, OpenOCD, eCos and the Atmel AT91SAM7S-EK Date: Tue Feb 8 10:31:42 EST 2011 Time to flesh out some ignorance and problems: A* Sometimes the DBGU console output stops working, i.e. for diag_printf. B* I do not know how to reset the board without performing a new "load" operation. C* It seems slow (3kb/sec) D* It doesn't recover well from USB unplug. (I sent an email to OpenOCD list [1]). E* The OCD device blinkgs green-yellow: successfully connected. F* Instead of switching to slow clock, what about dome delays after reset? G* Are there any publicly available SAM7-EK setups I'm missing? I ran into problem A* before but was able to avoid it only using "load" after a fresh start of the OCD, OpenOCD and the ARM board itself. Yesterday I erased the SAM-BA support from the flash so it might be related to that. First question: is there any setup necessary in eCos to make the DBGU output work properly? On the AT91 the DBGU-TX port is at PA10. Maybe it's simply switched off to make room for the other signal: NPCS2? Hmm.. Going from bad to worse. This is what I get starting OOCD: tom@zoo:~$ ocd.SAM7-H256 #!/bin/bash cat $0 SCRIPTS=/usr/local/share/openocd/scripts exec openocd \ --file $SCRIPTS/interface/arm-usb-ocd.cfg \ --file $SCRIPTS/target/sam7x256.cfg \ --file $0.cfg \ "$@" Open On-Chip Debugger 0.5.0-dev-00736-g75cdbff (2011-02-03-15:43) Licensed under GNU GPL v2 For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' srst_only srst_pulls_trst srst_gates_jtag srst_open_drain 300 kHz dcc downloads are enabled fast memory access is enabled force hard breakpoints Info : clock speed 300 kHz Info : JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) Info : Embedded ICE version 1 Info : sam7x256.cpu: hardware has 2 breakpoint/watchpoint units Info : JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset. target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x00100058 Warn : Bad value '00000001' captured during DR or IR scan: Warn : check_value: 0x00000009 Warn : check_mask: 0x00000009 Error: JTAG error while reading cpsr in procedure 'mww' And then I can't connect with gdb: Current directory is /home/tom/ubidata-tom/git/dbb_trailer/build/out/arm/ GNU gdb (eCosCentric GNU tools 4.3.2c) 6.8.50.20090630-cvs Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-eabi". For bug reporting instructions, please see: ... /home/tom/priv/git-private/ubidata-tom/tools/eCos.gdb:2: Error in sourced command file: Remote connection closed TOO MANY FAILURES !!! :) 1. it was working perfectly 2. I remove write protect on first 2 flash banks 3. it works 4. DBGU starts failing 5. JTAG starts failing is this an electrical problem? Hmm.. disconnecting the probe ground makes the above JTAG error go away. Reconnecting makes it re-appear. Tried twice. Disconnecting makes it fail first time, succeed 2nd time, 3rd time, fail 4th time. Lowering the initial JTAG clock further from 300 kHz to 100kHz seems to have fixed that problem. Then increasing the clock speed again before "load" makes it upload a little faster. I get to 8KB/sec at 6MHz. [1] https://lists.berlios.de/pipermail/openocd-development/2011-February/018057.html Entry: Restarting without reload Date: Tue Feb 8 12:54:10 EST 2011 (gdb) load Loading section .rom_vectors, size 0x40 lma 0x100000 Loading section .text, size 0xd198 lma 0x100040 Loading section .rodata, size 0x2f8 lma 0x10d1d8 Loading section .data, size 0x41c lma 0x10d4d0 Start address 0x100040, load size 55532 Transfer rate: 8 KB/sec, 7933 bytes/write. Now, how can we reset the target to start at 0x100040 again? Basicly the questions are: - How to reset the target's hardware state? - How to simply set IP? For ARM the registers are `r0' through `r13', `sp', `lr', `pc', and `cpsr'. So it's nit $ip, but $pc. This seems to work: (gdb) set $pc = 0x100040 So, how to perform a reset through OpenOCD? (gdb) mon reset halt JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) srst pulls trst - can not reset into halted mode. Issuing halt after reset. target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x00100058 This performs a reset, but doesn't set the PC. Setting it manually as above does enable to continue into the application. This only works at lower clock rates, so maybe some pause might be necessary? What does the line with "can not reset into halted mode" mean? Entry: Reset Date: Tue Feb 8 14:14:49 EST 2011 Not all resets are created equal[1]. For my reset it seems that the chip is running before it is halted. JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) srst pulls trst - can not reset into halted mode. Issuing halt after reset. target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x0010005c [1] http://openocd.berlios.de/doc/html/Reset-Configuration.html Entry: No debug output Date: Tue Feb 8 14:23:11 EST 2011 Let's trace this down. It writes to the base address 0xfffff200 + AT91_US_CSR (0x14) See page 18, section 9.1: System Controller Mapping. 0xFFFFF200 DBGU 0xFFFFF400 PIOA How to see which peripherals are enabled? 9 - RX 10 - TX PIO_PSR = ff9f8d9f 0=per, 1=pio PIO_OSR = 80000c08 PIO_ODSR = 80000c08 all the rest is 0 Entry: Erasing flash Date: Tue Feb 8 16:59:52 EST 2011 I'm suspecting some code gets executed that messes up the state, so start with fresh slate: (gdb) mon flash erase_check 0 (gdb) mon flash erase_address 0x100000 0x30000 Doesn't change anything... Entry: No DBGU output Date: Tue Feb 8 17:57:11 EST 2011 What could this be? What I need is a very simple, known working test application to show that it is physically working. Entry: Other AT91 board Date: Wed Feb 9 09:18:59 EST 2011 I tried on the other AT91 board and the behaviour is the same. When the app starts, the TX line gets asserted with 3.3V but it doesn't show any signal. The current hypothesis is that this is due to the "can not reset into halted mode. Issuing halt after reset." issue. However, resetting the device and letting the app run by itself creates the same problem. Entry: ecos configtool Date: Wed Feb 9 10:30:07 EST 2011 Problem: I don't know how to use this with several versions lying around. Apparently it is quite independent from the ecos versions themselves, so let's install the one from CVS[1]: cvs -z3 -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos-host/ Note that these look into the ../acsupport directory so the host/ dir needs to be inside the ecos/ dir from CVS. Just follow directions ;) [1] So, how to use it with different distributions? Hmm.. Different approach. Just run the 3.0 version that came with ecos-3.0. This already gives problems: ecos.ecc contains errors. Let's start from scratch. [1] http://www.ecoscentric.com/devzone/configtool.shtml Entry: From scratch AT91 Date: Wed Feb 9 10:50:01 EST 2011 To get a better understanding for the AT91, I'd like to look at a stand-alone example[1]. Problem here is toolchain: it seems to be setup differently than the eCos toolchain: "string.h" not found, and when I comment that out it hangs on trying to link with -lc. Is there some neutral point to start on linux? [1] http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html Entry: Issuing halt after reset Date: Wed Feb 9 13:22:02 EST 2011 So, I changed to a different OpenOCD config: BOARD=board/atmel_at91sam7s-ek.cfg # BOARD=target/sam7x256.cfg It seems to have some minor differences I don't understand, but it does seem to reset properly now, with PC= 0x00000000 (gdb) reset - Slowing down JTAG for reliable reset. 100 kHz - Resetting chip. JTAG tap: at91sam7s256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) srst pulls trst - can not reset into halted mode. Issuing halt after reset. target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x0010005c requesting target halt and executing a soft reset target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x00000000 - Switching to high speed JTAG. 6000 kHz When I flash the whole chip, it does seem to run for a while until it's halted after reset (up to 21c): JTAG tap: at91sam7s256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3) srst pulls trst - can not reset into halted mode. Issuing halt after reset. target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x0000021c requesting target halt and executing a soft reset target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x600000d3 pc: 0x00000000 There is a bit of jitter there: 238, 2c0, 2a8, 228, 238 [1] http://www.mail-archive.com/openocd-development@lists.berlios.de/msg14861.html Entry: eCos config Date: Wed Feb 9 14:04:34 EST 2011 I'm getting confused now. The 3.0 default config seems to have serial ports disabled: cdl_component CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0 { # This option is not active # The parent CYGPKG_IO_SERIAL_ARM_AT91 is not active ... } This is both in 3.0 and CVS version. Let's start at that point. How can I change this? Entry: Setting up redboot Date: Wed Feb 9 14:47:41 EST 2011 ecosconfig new at91sam7sek redboot # after this point I had an error: # C CYGPKG_DEVS_SPI_ARM_AT91, "requires" constraint not satisfied: CYGPKG_ERROR ecosconfig import ../ecos-3.0/packages/hal/arm/at91/at91sam7s/v3_0/misc/redboot_RAM.ecm # same error # didnt get here: ecosconfig tree make #-------------- Same for CVS version. Doesn't seem to be properly implemented. not used? [2] [1] http://www.ecoscentric.com/ecospro/doc.cgi/html/redboot-guide/rebuilding-redboot.html [2] http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg09953.html Entry: using ecosconfig Date: Wed Feb 9 14:54:07 EST 2011 How to add a package. First get a list, then add: ecosconfig list ecosconfig add So, in the default ecos.ecc for the at91sam7sek target, the following options are not active: - CYGPKG_IO_SERIAL_ARM_AT91 - CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0 However, in this[1] it is explained that CYGPKG_IO_SERIAL_ARM_AT91 is enabled automatically: ``There is a serial driver CYGPKG_IO_SERIAL_ARM_AT91 which supports both the Debug Unit and USART serial devices. The debug serial port at J3 and DTE port at J2 (connected to USART channel 0) can be used for communication. If the GDB stub ROM is installed, it uses the Debug Unit serial device only. The serial driver package is loaded automatically when configuring for the AT91SAM7S-EK target.'' So what's the deal? tom@zoo:/opt/xc/ecos/build_cvs_at91sam7sek$ ecosconfig add CYGPKG_IO_SERIAL_ARM_AT91 Package `CYGPKG_IO_SERIAL_ARM_AT91' is already loaded. Enough dabbling.. Where is the main documentation for ecosconfig? It's in the user guide[2], more specifically the configuration tool section[3]. What I'm looking for is the manual configuration[4] section. Running the gui tool: configtool $ECOS_REPOSITORY ecos.ecc [1] http://www.ecoscentric.com/ecospro/doc.cgi/html/ecospro-ref/arm-at91sam7sek.html [2] http://ecos.sourceware.org/docs-latest/user-guide/ecos-user-guide.html [3] http://ecos.sourceware.org/docs-latest/user-guide/the-ecos-configuration-tool.html [4] http://ecos.sourceware.org/docs-latest/user-guide/manual-configuration.html Entry: Reset init Date: Thu Feb 10 12:32:24 EST 2011 Check what the "Reset peripherals" is about. -> it corresponds to the other Segger init. $_TARGETNAME configure -event reset-init { soft_reset_halt # RSTC_CR : Reset peripherals mww 0xfffffd00 0xa5000004 # disable watchdog mww 0xfffffd44 0x00008000 # enable user reset mww 0xfffffd08 0xa5000001 # CKGR_MOR : enable the main oscillator mww 0xfffffc20 0x00000601 sleep 10 # CKGR_PLLR: 96.1097 MHz mww 0xfffffc2c 0x00481c0e sleep 10 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz mww 0xfffffc30 0x00000007 sleep 10 # MC_FMR: flash mode (FWS=1,FMCN=73) mww 0xffffff60 0x00490100 sleep 100 } Entry: More serial stuff Date: Thu Feb 10 13:09:29 EST 2011 [1] http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg09664.html Entry: Diagnostic LEDs on AT91SAM7S-EK Date: Thu Feb 10 13:38:32 EST 2011 The vectors.S code uses the "LED" macro. Why are my LEDs not lit? packages/hal/arm/arch/current/src/vectors.S Entry: Stepping through eCos boot Date: Thu Feb 10 13:43:48 EST 2011 To see what's going on, I'm stepping through the boot. The first interesting point is hal_plf_hardware_init() in at91sam7s_misc.c as that is where the PIO pins are set. Before running that function it might be best to dump the status registers first. (gdb) mon mdw 0xFFFFF200 0x80 0xfffff200: 00000000 00000000 00000000 00000000 00000000 40001818 00000000 00000000 0xfffff220: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff240: 270d0940 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff260: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff280: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff2a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff2c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff2e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000202 0xfffff300: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff320: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff340: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff360: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff380: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff3a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff3c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff3e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Hmm.. that's the wrong bunch. I need the PIO setup, not the DBGU setup. The config above doesn't change. However, when the line HAL_ARM_AT91_PIO_CFG(AT91_DBG_DTXD); was executed, the pin went from quiet (high z?) to (noisy ripple) 3.3V. The PIO registers after init are: (gdb) mon mdw 0xFFFFF400 0x80 0xfffff400: 00000000 00000000 ff9ff99f 00000000 00000000 00000000 00000000 00000000 0xfffff420: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff440: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff460: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff480: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff500: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff520: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff540: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff560: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000202 PIO registers after reset: (gdb) mon mdw 0xFFFFF400 0x80 0xfffff400: 00000000 00000000 ffffffff 00000000 00000000 00000000 00000000 00000000 0xfffff420: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff440: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff460: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff480: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff500: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff520: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff540: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff560: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000202 Enabling DTXD brings 0xfffff408 from ffffff9f -> fffffb9f DRXD -> fffff99f Just like expected: it resets bit 10 for TX and bit 9 for RX. The, explain the following: #ifdef CYGBLD_HAL_ARM_AT91_SERIAL_UART /* Enable peripheral clocks for USART 0 and 1 if they are to be used */ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, AT91_PMC_PCER_US0 | AT91_PMC_PCER_US1); #endif Anyways, continuing into the app the PIOs are set like this: (gdb) mon mdw 0xFFFFF400 0x80 0xfffff400: 00000000 00000000 ff9f8d9f 00000000 00000000 00000000 80000c08 00000000 0xfffff420: 00000000 00000000 00000000 00000000 00000000 00000000 80000c08 00000000 0xfffff440: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff460: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff480: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff4e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff500: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff520: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff540: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff560: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0xfffff5e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000202 0xfffff408 PIO_PSR bit10=1, bit9=0 That doesn't seem right: peripheral 10 inactive? Note that the other 2 status registers have a 1 in the bit10 position also: 0xfffff418 Output Status Register PIO_OSR 0xfffff438 Output Data Status Register PIO_ODSR Which means the port is an output and it's driven high. And, surprise, that's exactly what I'm seeing. So where is this value set then? So, I should be able to write to the PIO_PDR, PIO Disable Register to switch off the output and connect to peripheral: FFFFF404 <- 00000400 That didn't do the trick.. But it does look like this is the cause. Entry: When is the DBGU disabled? Date: Thu Feb 10 14:49:42 EST 2011 cyg_hal_invoke_constructors() One of the constructs modifies (gdb) mon mdw 0xFFFFF408 0xfffff408: ff9f8d9f Before that it is (gdb) mon mdw 0xFFFFF408 0xfffff408: ff9ff99f Ok, it happens during init of the SPI bus. Run till exit from #0 _GLOBAL__I.32000_spi_at91_init.cxx () at /opt/xc/ecos/ecos-cvs/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx:68 cyg_hal_invoke_constructors () at /opt/xc/ecos/ecos-cvs/packages/hal/arm/arch/current/src/hal_misc.c:212 So, when running up to (gdb) thbreak cyg_hal_invoke_constructors I can call a function that writes to the debug output, and the data show up on the line. HA! Entry: Why does SPI init disable DBGU? Date: Thu Feb 10 15:12:46 EST 2011 I think this is because of NPCS2 which is shared with DBGU. However, it uses those lines as just IO lines, not the SPI peripheral. in spi_at91.c: cyg_spi_at91_bus_init): spi_at91_init_bus(): // Put SPI chip select pins in IO output mode for(ctr = 0;ctr<4;ctr++) { if(spi_bus->cs_en[ctr]) { HAL_ARM_AT91_GPIO_CFG_DIRECTION(spi_bus->cs_gpio[ctr],AT91_PIN_OUT); HAL_ARM_AT91_GPIO_SET(spi_bus->cs_gpio[ctr]); } } So the configuration can be modified to pick any pin for chip select. I guess this just needs to not use NPCS2(DTXD) and NPCS1(DRXD). Note that the other two are shared with the other two serial ports. Ok, now I got some weird behaviour blocking in cyg_hal_plf_serial_getc(). Maybe some rom monitor remnant. cyg_hal_diag_mangler_gdb_flush() I think it's this one: CYGDBG_HAL_DIAG_TO_DEBUG_CHAN By defaut it enables the GDB mangler. Ok, so I can set the baud rates of the 3 different serial ports. Now is one of them the DBGU, or does that need to be set separately? Entry: Hooking up the SPI flash Date: Fri Feb 11 06:30:33 EST 2011 Looks like the best way to go is to use NPCS0 for chip select. Connections: VSS(GND) VDD(3V3) SI SO SCK RST#(3V3) reset disabled WP#(3V3) write protect disabled On the AT91SAM7S: Is there a way to make this compatible with some existing pinouts? Entry: Uploading elf through OpenOCD (not GDB) Date: Sat Feb 12 11:22:17 EST 2011 On the OpenOCD console (telnet localhost 4444) > flash write_image erase /home/tom/libprim/build_ecos_at91sam7sek/cell/cell 0 elf flash write_image erase /home/tom/libprim/build_ecos_at91sam7sek/cell/cell 0 elf auto erase enabled wrote 131072 bytes from file /home/tom/libprim/build_ecos_at91sam7sek/cell/cell in 15.150150s (8.449 KiB/s) Entry: TTY, SERIAL, DIAG Date: Wed Feb 16 15:41:59 EST 2011 I'm completely confused now... There seem to be several layers of serial drivers on eCos for the AT91: Hardware serial drivers: CYGPKG_IO_SERIAL_ARM_AT91 CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0-2 CYGPKG_IO_SERIAL_TTYDIAG CYGPKG_IO_SERIAL_TTY0-3 CYGPKG_IO_SERIAL_TERMIOS CYGPKG_IO_SERIAL_TERMIOS0-3 CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD * What is the difference between all these and the simple diag_* polling input/output? * How do you enable just the debug IO in polling mode, and set the baud rate? From what I tried, enabling all of them will link multiple consumers to the DBGU port. Entry: Configtool: adding new packages Date: Thu Feb 17 12:09:09 EST 2011 The configtool itself is quite straightforward. To add a new package to the repository, use the following approach: - Create a directory structure in the package/ tree. Look at other packages to see how this is done. This needs at least a cdl file, and possibly an include file (inl). - Update the packages/ecos.db file, adding a `package' element that points to the cdl. Problem: it tells me that I need to pick a new hardware template to add/remove hardware packages. What's that about? Trying manually with ecosconfig: ecosconfig add CYGPKG_DEVS_FLASH_SST_25VFXXX ecosconfig add CYGPKG_IO_FLASH [1] http://ecos.sourceware.org/docs-latest/user-guide/config-tool-updating-configuration.html Entry: HAL_WRITE_UINT32 and volatile Date: Thu Feb 17 18:46:53 EST 2011 In eCos, volatile pointers are abstracted by the following macros: #define HAL_READ_UINT32( _register_, _value_ ) \ ((_value_) = *((volatile CYG_WORD32 *)(_register_))) #define HAL_WRITE_UINT32( _register_, _value_ ) \ (*((volatile CYG_WORD32 *)(_register_)) = (_value_)) Entry: Managing versions and platforms in eCos Date: Fri Feb 18 12:36:46 EST 2011 I have currently 4 different versions and 4 different platforms. This is a complete mess. I need a simple makefile that has as input: - eCos config file - ecos source - ecos tools and will build the libtarget.a specifically for that particular application. It seems to make more sense anyway to have one ecc per app, instead of sharing a pre-built libtarget.a using many apps. Entry: Adding hardware packages. Date: Mon Feb 21 10:01:59 EST 2011 After adding a new driver package to ecos.db and trying to add it to my .ecc. the error message in configtool is: Add and remove hardware packages by selecting a new hardware template. From [1]: You are not allowed to add hardware packages to a target. The AT91 eth driver would not work with the PID, since it is for the on chip ethernet you find in the AT91SAM7 devices. This is one reason adding hardware packages are not allowed! It seems that one needs to explicitly create a new hardware template. Let's have a look at the AT91SAM7S-EK BSP. The following is the haredware package and probably not the template. tom@zoo:/opt/xc/ecos/ecos-cvs/packages$ find -name '*at91sam7sek*' ./hal/arm/at91/at91sam7sek ./hal/arm/at91/at91sam7sek/current/cdl/hal_arm_at91sam7sek.cdl ./hal/arm/at91/at91sam7sek/current/src/at91sam7sek_misc.c So, when you do "ecosconfig new ", what is the parameter? Q: Where are hardware templates stored? From here[2] it seems to be in the ecos.db file. In ecos-cvs this is: target at91sam7sek { alias { "Atmel AT91SAM7SEK evaluation board" at91_at91sam7sek } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_AT91 CYGPKG_HAL_ARM_AT91SAM7 CYGPKG_HAL_ARM_AT91SAM7SEK CYGPKG_IO_SERIAL_ARM_AT91 CYGPKG_DEVS_FLASH_AT91 CYGPKG_IO_SPI CYGPKG_DEVS_SPI_ARM_AT91 CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE CYGPKG_DEVS_USB_AT91 } description " The at91sam7sek target provides the packages needed to run eCos on an Atmel AT91SAM7S-EK evaluation board." } So the proper way is then to create a new hardware target. Note: don't add any comments inside a target definition! It doesn't seem to be supported. Probably the same for the whole ecos.db file. After adding the new driver it is now present in the ecc, but greyed out. Q: What does it mean when an option is greyed out in configtool? The problem was an unnecessary "active-if" in the CDL. [1] http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg06458.html [2] http://www.alteraforum.com/forum/showthread.php?t=13765 Entry: Ecos CDL : dependencies. Date: Mon Feb 21 12:03:09 EST 2011 Q: How are dependencies expressed? Q: What's the difference between "active-if" and "parent"? Entry: ecos source file naming conventions Date: Tue Feb 22 15:59:22 EST 2011 Looking at the .cdl for the dataflash driver, there is a `compile' line that mentions only one file. What about the other file devs_flash_atmel_dataflash_flash_dev_funs.c ? compile devs_flash_atmel_dataflash.c I suspect that a component can only be a single file. Let's look at the docs[1]. Nope, it can be multiple files just fine. [1] http://ecos.sourceware.org/docs-latest/cdl-guide/ref.compile.html Entry: Duct-tape programming Date: Wed Feb 23 10:40:02 EST 2011 I know, complaining is easy. However, the CDL in ecos is quite ad-hoc. From[1]: A magically-named calculated configuration option of the form CYGPKG__TESTS lists the test cases. [1] http://ecos.sourceware.org/docs-latest/cdl-guide/package.contents.html#PACKAGE.TESTS Entry: Ecos build system woes: BEWARE: header files are copied! Date: Wed Feb 23 12:04:01 EST 2011 Note that when developing on ecos, the header files get copied into the build directory only once when the build tree is constructed! If you make any changes in the header files, they won't show up until you recreate the build tree. This can lead to confusioin when editing the ecos source tree. Note that I'm not talking about the _generated_ header files in pkgconf, for which the problem is of course obvious. I'm sufficiently ennoyed by this to see if it is fixable. First, it's not a script. Its a C++ program in the host tools repository: tools/configtool/standalone/common/ecosconfig.cxx My guess is the tree is built in the cmd_tree() method in tools/configtool/standalone/common/cdl_exec.cxx This then calls generate_build_tree() in tools/configtool/common/common/build.cxx Yeah.. I'm not going to mess with that! Entry: eCos magic Date: Wed Feb 23 12:42:24 EST 2011 A generalzing, ranting remark.. eCos seems to contain a lot of "magic". Now, that's fine if you know how this works, but it's a nightmare to learn as there are no explicit pointers in the code for this.. Entry: Building ecos Date: Fri Feb 25 10:01:57 EST 2011 An ecos build is parameterized by: - ecos.ecc configuration - ecos source tree - toolchain (path + name prefix) The application is parameterized by: - ecos install tree (libtarget.a + include/) - toolchain Entry: SAM7X-EK and eCos LwIP ethernet Date: Fri Feb 25 22:45:41 EST 2011 In theory it should be supported[1]. Running the udpecho demo I get this on the console: NOTAPPLICABLE: It was running in simple mode. Apparently sequential mode doesn't fit in the 128k RAM. Trying httpd_simple instead, I get an error message that there's no link. Indeed, hub light is not on. INFO: INFO: AT91_ETH: Initialising @ fffdc000 AT91_ETH: Installing Interrupts on IRQ 16 AT91_ETH - Warning! ESA unknown AT91_ETH: 12:34:56:78:9a:bc AT91_ETH: No Link INFO: INFO: Replugging helped: et0: IP: 192.168.6.102 Submask: 255.255.255.0 Gateway: 192.168.6.1 However, it doesn't like nmap: cannot allocate pbuf to receive packet Using just the browser on http://192.168.6.102/ works: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO: eCos - HTTP test server running on lwIP Version: 1.3.2 (release) Requests: 1 [1] http://sourceware.org/ml/ecos-discuss/2010-01/msg00057.html Entry: CYG_HAL_TABLE_ENTRY Date: Fri Mar 4 10:10:59 EST 2011 As seen in i.e. the `CYG_FLASH_DRIVER' macro. This uses a nice trick, where the data is put into a raw linker section. #ifndef CYG_HAL_TABLE_ENTRY #define CYG_HAL_TABLE_ENTRY( _name ) \ CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data") \ CYGBLD_ATTRIB_USED #endif Entry: USB Serial Date: Sun Mar 6 08:18:45 EST 2011 I tried the usb serial echo example and it seems to work fine, after changing the ecos config to take on the USB ID 05f9:ffff specified in drivers/usb/serial/generic.c it works. The ACM driver gives trouble: [7615997.068502] usb 1-4.4.2: new full speed USB device using ehci_hcd and address 50 [7615997.182791] usb 1-4.4.2: New USB device found, idVendor=ffff, idProduct=0001 [7615997.182808] usb 1-4.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [7615997.182810] usb 1-4.4.2: Product: eCos USB Serial Device [7615997.182812] usb 1-4.4.2: Manufacturer: eCos [7615997.188623] cdc_acm 1-4.4.2:1.0: Zero length descriptor references [7615997.188627] cdc_acm: probe of 1-4.4.2:1.0 failed with error -22 Apparently this is known[1] since its creation in 2008 but not fixed yet. Looking at the driver in linux/drivers/usb/class/cdc-acm.c : acm_probe(), this is because: (struct usb_interface *)->altsetting->extralen == 0 The (struct usb_interface *)->altsetting->extra buffer does seem to be defined. What it expects if this buffer is not empty is: 1 -> USB_DT_CS_INTERFACE 2 -> type This seems to be a bunch of data we don't need. What is the absolute minimum to support? It seems that USB_CDC_UNION_TYPE is important. Looking in the CDC spec[2], CDC120-20101103-track.pdf page 17, the "Union Functional Descriptor" (06h) is mentioned. On page 19 this is further explained. The linux datastructure is: /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ struct usb_cdc_union_desc { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bMasterInterface0; __u8 bSlaveInterface0; /* ... and there could be other slave interfaces */ } __attribute__ ((packed)); [1] http://sourceware.org/ml/ecos-patches/2008-06/msg00000.html [2] http://www.usb.org/developers/devclass_docs/CDC1.2_WMC1.1_012011.zip Entry: Racket eCos Date: Fri Mar 25 14:10:41 EDT 2011 For a project I'm working on some filesystem code which is incredibly hard to test properly. What I'd like to do is to functionalize the code and run it inside of a test harnass. It would be nice to do this in a scripting langauge that allows a functional approach, and can run properly in gdb. Entry: Weird gdb/openocd problem Date: Wed Apr 20 19:30:24 EDT 2011 Running on zoo (real amd64, 64bit Debian) I can "load" code without trouble from gdb connecting to OpenOCD. On ubit (virtual kvm, 32bit Debian) I can't: everything seems to go well but the flash is simply not written nor erased. Same behaviour if OpenOCD is running on zoo, and I connect from ubit. Using "flash write_image" from OpenOCD seems to work on ubit. It seems this would be GDB then. Both are running the same version except for host config options: ubit: This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-eabi". zoo: This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-eabi". Weird.. Wait I did read something about XML support for the memory map. That might be it: memory treated as RAM? warning: Can not parse XML memory map; XML support was disabled at compile time 0x00000000 in ?? () 6000 kHz (gdb) On zoo: (gdb) info mem Using memory regions provided by the target. Num Enb Low Addr High Addr Attrs 0 y 0x00000000 0x00100000 rw nocache 1 y 0x00100000 0x00140000 flash blocksize 0x4000 nocache 2 y 0x00140000 0x100000000 rw nocache while on ubit they are not defined. How to enable XML support? EDIT: make sure libexpat1-dev is installed; it will be used automatically. Entry: ecosconfig Date: Thu May 26 18:21:35 CEST 2011 Trying to figure out how to use ecosconfig to build a new .ecc without using the graphical editor. There seems to be no easy way to go backward from .ecc to find out what's different with the template defaults. The .ecc file by itself is a total horror to read. Some notes: 1. The "target" is defined in packets/ecos.db in a "target" form. It includes a list of (hardware) packages that make up the low-level support for a particular board. It is not possible to add hardware packages to an existing configuration in configtool, but it seems to be possible to do this using ecosconfig? 2. The "template"[1] is a collection of packages that can be loaded on top of a "target" collection. Templates can be found in the packets/templates directory. A template can have a version, but a target doesn't seem to have one. I don't understand this non-orthogonality of target/template distinctions. Maybe there are some internals that require this but it looks odd on the outside. I understand that you want to separate hardware from software config, but what I don't see is why these two "collections of packages" need to have a different mechanism: targets are defined in packages/ecos.db using a different syntax than the ECC, while templates use ECC syntax. And both are different from a third syntax: CDL. [1] http://ecos.sourceware.org/docs-3.0/cdl-guide/overview.html#CONCEPTS.TERMINOLOGY.TEMPLATE Entry: How to diff two eCos configuration files? Date: Fri May 27 13:27:30 CEST 2011 A simple way is to canonicalize (serialize + sort) and perform a linear diff. The simplest way to go seems to be to use: ecosconfig --config= export to convert a (verbose) config file to a minimal config file. Entry: Once cable: console over JTAG? Date: Fri May 27 17:12:29 CEST 2011 I'd like to eliminate the TTL serial port connection and get a console over the JTAG connection. Does this exist already? From here[1] it's mentioned to use "grmon to get a console over AHBJTAG". EDIT: when GDB is waiting for an event from the gdbserver, i.e. during "continue", it will print messages to the console. (Try this: login to the OpenOCD telnet port and type "bp" : the GDB window also echos the response.) Maybe it's possible to write to some register that is accessible to the JTAG? I.e. the only thing it needs to do is to receive a signal, the rest can be halt,read_mem,continue. [1] http://tech.groups.yahoo.com/group/leon_sparc/message/19137 Entry: AT91SAM7 and OpenOCD Date: Sat May 28 11:18:30 CEST 2011 I keep experiencing problems. Once issue that pops up regularly is slow download speed (1 kByte/sec). Out of reset the controller runs at 32kHz so that might explain why it takes long to respond, or why it doesn't like a fast JTAG clock for sending the reset command. Entry: eCos linker section magic Date: Sun May 29 12:38:10 CEST 2011 Problem: the macro CYG_FLASH_DRIVER works in app code, but not in driver code (as part of libtarget.a). Find out why. Eventually, this expands to an lvalue (_name == cyg_flashdev): #ifndef CYG_HAL_TABLE_ENTRY #define CYG_HAL_TABLE_ENTRY( _name ) \ CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data") \ CYGBLD_ATTRIB_USED #endif I'm assuming the linker only takes that section from the app, not the library? __attribute__((section (.ecos.table.cyg_flashdev.data))) __attribute__((used)) Is this documented somewhere? I can't find anything... The relative line in target.ld seems to be: KEEP(*( SORT (.ecos.table.*))) ; This then uses the lexical order of .begin .data .extra .finish to delimit the section. A neat trick, but quite obscure! See also [1]. [1] http://www.cygwin.com/ml/ecos-discuss/2003-07/msg00086.html Entry: eCos trouble Date: Fri Jun 3 12:29:30 CEST 2011 The same problem occurs with CVS ecos too. I've looked at GCC but the trouble is probably binutils. # Broken: one$ dpkg -l binutils => 2.21.51.20110523-1 # OK: ubit$ dpkg -l binutils => 2.20.1-16 Let's see if first upgrading then downgrading works. [1] http://ecos.sourceware.org/ml/ecos-discuss/2011-06/msg00010.html Entry: DCC diag Date: Fri Jun 3 17:58:46 CEST 2011 In OpenOCD it's possible to enable linux-style DCC messages (Linux:CONFIG_DEBUG_ICEDCC) from target while it's running using the following command: target_request debugmsgs charmsg -- For eCos there is already a driver in the AT91 HAL. Add these to the eCos config file: # Enable the Debugger Communication Channel for sending console # messages over JTAG to OpenOCD while target is running. cdl_option CYGBLD_HAL_ARM_AT91_DCC { user_value 1; } # To make sure that the diag calls go to the correct channel, some # config options are necessary. It seems simplest to just add an # extra channel. # Add room for extra channel: (i.e. 3 is the default) cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS { user_value 4; } # Link DCC com to last channel cdl_option CYGBLD_HAL_ARM_AT91_DCC_CHANNEL { user_value 3; } # Route diag output to DCC channel. cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL { user_value 3; } Entry: Hacking the OpenOCD DCC console channel Date: Fri Jun 3 22:45:19 CEST 2011 The big disadvantage is that by default, the OpenOCD polling is slow. Changing polling_interval in target/target.c doesn't seem to speed it up. Maybe it should be done differently: perform a local poll whenever there is serial data coming, such that at least a burst of characters is displayed at a proper speed. The OpenOCD command above is defined in ./target/target_request.c:261:COMMAND_HANDLER(handle_target_request_debugmsgs_command) add_debug_msg_receiver() This eventually enables a call arm7_9_handle_target_request() A timer callback is added in arm7_9_init_arch_info() through the call: return target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target); However this function is called only once every 100ms, and not once every 1 ms as requested by that function. From sprinking some printfs, it looks like initiall, the function does get called fast, but then it resets.. Ok, there's another timeout for the server.c server_loop() which is hardcoded to 100ms. Setting this to 1 ms speeds up the console to a usable setting. It's not ideal. The interface itself can be quite fast. What about this: if a byte is received over the DCC, a tight loop is started that polls the DCC faster until it times out. This way it should be possible to at least speed up longer messages. Well, I tried it and running at JTAG=3MHz and 1 ms polling interval there seems to be little difference between running a tight loop and the default behaviour. That's 3000 JTAG clocks per transferred character. Why is it so high? It's probably pre/postamble. Like the DCC transfers, it might be possible to setup comm once per packet, but this requires buffering on the target side. Looks like the current setup which gets to about 9600 baud equivalent is good enough. Entry: Using the DCC channel Date: Fri Jun 10 16:56:15 CEST 2011 So, see previous post. DCC output console seems to work. Next: input. Is there anything like diag_read()? I think I ran into this before and had to hack it a bit. The other problem: while the eCos side seems to work, does OpenOCD transfer keystrokes to the DCC? I didn't see anything like that in the code, so maybe it doesn't? Entry: eCos serial ports Date: Fri Jun 10 21:32:32 CEST 2011 So, how do serial ports work in eCos? First, at the lowest level, there is the devtab. The one on my SAM7S board has the following entries: (gdb) p __DEVTAB__[0] $3 = {name = 0x1105e0 "/dev/ser0", dep_name = 0x0, handlers = 0x2005e8, init = 0x1009f4 , lookup = 0x10084c , priv = 0x200358, status = 4097} entry name dep_name handlers init lookup priv status -------------------------------------------------------------------------------------------------------- 0 /dev/ser0 0x0 0x2005e8 at91_serial_init at91_serial_lookup 0x200358 4097 1 /dev/ser1 0x0 0x2003f0 2 /dev/ser2 0x0 0x200488 3 /dev/ttydiag /dev/haldiag 0x200620 tty_init tty_lookup 0x202178 4 /dev/tty0 /dev/ser0 0x202184 5 /dev/tty1 /dev/ser1 0x202190 6 /dev/tty2 /dev/ser2 0x20219c 7 /dev/tty3 /dev/ser3 0x2021a8 8 /dev/haldiag 0x0 0x2005e8 haldiag_init 0x0 0x20063c From the code pointers it seems there are 3 different kinds. First, let's eliminate tty. Is this necessary? What does it do? Line editor and stuff? Let's RTFM[1]. So, there are indeed 2 kinds: raw and tty. For now it's probably safe to ignore the tty's as they seem to be a simple wrapper around the other sers. Physically, the AT91SAM7S/X has 2 UARTs + DBGU = 3 serial ports total. The normal UARTs work differently from the DBGU (they have handshake + clock lines). Q: CYGPKG_IO_SERIAL_ARM_AT91_SERIAL[012] These are 3 serial ports by default named /dev/ser[012]. Is the DBGU included here? I don't see it here: packages/devs/serial/arm/at91/current/src/at91_serial.c Q: CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL Q: /dev/haldiag That name is not configurable. Its devtab entry is defined in packages/hal/arm/at91/var/current/src/hal_diag.c ( Silly: I was using a faulty "rw" open mode. All works with "a+". ) On my AT91SAM7S-EK with DCC diag enabled: /dev/ser0 AT91 UART0 /dev/ser1 AT91 UART1 (probably) /dev/ser2 AT91 DBGU UART /dev/haldiag DCC debug channel Going through the driver code I did not find any special handling of the DBGU uart which didn't make sense until I saw this: *** packages/hal/arm/at91/at91sam7s/current/include/plf_io.h at91_serial.c: #define AT91_USART0 0xFFFC0000 #define AT91_USART1 0xFFFC4000 // Define USART2 to be the debug UART. It is similar enough to a USART // that both the hal_diag and interrupt driven driver will work. // However trying to change parity, start/stop bits etc will not work. #define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG #define AT91_USART2 AT91_DBG *** packages/hal/arm/at91/var/current/include/var_io.h: #ifndef AT91_DBG #define AT91_DBG 0xFFFFF200 #endif [1] http://ecos.sourceware.org/docs-3.0/ref/io-serial-driver-details.html [2] http://www.ecoscentric.com/ecospro/doc.cgi/html/ref/arm-at91-serial-uart.html Entry: Size of eCos Date: Sat Jun 11 17:08:34 CEST 2011 My next experiment is to run the new CELL VM from libprim on the AT91SAM7S-EK to get an idea of speed and memory use. At this point it looks like this, which is not unsubstantial at all. 0 .rom_vectors 00000040 1 .text 0001bf10 114448 2 .rodata 00000df0 3568 3 .fixed_vectors 00000140 4 .data 000008fc 5 .bss 00004a60 19040 Note that a VM can already take much of the responsabilities of a system, and eCos probably isn't as lean as it could be due to some of the abstraction layers in there. As a rule of thumb, enabling -Os should about halve the size. Quick patching it in install/include/pkgconf/ecos.mak Ha, I just noticed that I'm not using the ecos build flags in libprim. Hmm, with an -Os build it's still quite a lot: .text 00016a74 After enabling the -ffunction-sections -fdata-sections CFLAGS, the size increased slightely to around 00018000. Due to a bug in the configure script the linker flag -Wl,--gc-sections did not come through. With that enabled the size is now back to 00010490. Entry: eCos includes Date: Sun Jun 12 18:33:26 CEST 2011 It seems that both .S files and .ldi files use preprocessor #include statements to gather config data. [1] http://sourceware.org/ml/ecos-discuss/2001-07/msg00781.html Entry: eCos and stdint.h Date: Mon Jun 20 16:20:41 CEST 2011 This change triggered an error that __THROW is redefined: +#include #include #include #include #include [1] http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg11595.html Entry: Trouble with JTAG clock Date: Wed Jun 22 03:00:38 CEST 2011 If I read correctly, the macro __main_clock_init__ in: packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h Will switch the clock back to slow clock for a bit, which might be the reason why the JTAG gets messed up for single stepping through that region for clocks higher than say 10 kHz. Looks like this is eCosPro 3.0.9 only, for eCos it has been fixed[1]. Anyways, stepping through this clock switching code at 100kHz still works, though 1000kHz doesn't. The following gdb command is quite convenient: define vstepi stepi x/10i $pc-8 end [1] http://www.mail-archive.com/ecos-patches@ecos.sourceware.org/msg01790.html Entry: Interrupts Date: Tue Jul 19 14:55:11 CEST 2011 eCos has 2 interrupt APIs: kernel[1] and HAL[2]. The ref doc warns that HAL should be used to make sure that drivers work in single-threaded mode without the multitasking kernel compiled in. See "Description" in [1]. [1] http://ecos.sourceware.org/docs-latest/ref/kernel-interrupts.html [2] http://ecos.sourceware.org/docs-latest/ref/hal-interrupt-handling.html Entry: Serial port Date: Tue Jul 19 15:15:51 CEST 2011 To declare the "class" that implements serial port access the macro SERIAL_FUNS is used. It is documented in [1]. SERIAL_FUNS(l, putc, getc, set_config, start_xmit, stop_xmit) [1] http://ecos.sourceware.org/docs-latest/ref/io-how-to-write-a-driver.html#IO-HOW-TO-WRITE-SERIAL-INTERFACE-DRIVER Entry: Platform defines Date: Wed Aug 10 10:18:58 CEST 2011 I'm using this to make small platform-dependent escapes: #ifdef CYGHWR_HAL_ARM_AT91_AT91SAM7 Where is this defined? Hmm.. can't get that to work any longer.. This one is in pkgconfig/system.h: #ifdef CYGPKG_HAL_ARM_AT91 Entry: Synthetic target serial port Date: Mon Sep 12 13:33:38 EDT 2011 The simplest way to get data in/out is to use a serial port. To connect a synthetic target serial port to a linux pty, use the following approach. 1. Make sure that ecosynth is compiled. Call the following from an empty build dir: $ECOS/packages/hal/synth/arch/v3_0_9/host/configure && make 2. The synth binary needs to find ecosynth. It will traverse the PATH environment variable and look for: #define MAKESTRING1(a) #a #define MAKESTRING2(a) MAKESTRING1(a) #define AUXILIARY "../libexec/ecos/hal/synth/arch/" MAKESTRING2(CYGPKG_HAL_SYNTH) "/ecosynth" WTF.. It would be simpler to have a direct plug: --- a/src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/src/synth_intr.c +++ b/src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/src/synth_intr.c @@ -763,6 +763,27 @@ synth_start_auxiliary(void) } found = 0; + + // Find the auxilary using an explicit location. + for (i = 0; (0 == found) && (0 != cyg_hal_sys_environ[i]); i++) { + const char *var = cyg_hal_sys_environ[i]; + if (('E' == var[0]) && + ('C' == var[1]) && + ('O' == var[2]) && + ('S' == var[3]) && + ('Y' == var[4]) && + ('N' == var[5]) && + ('T' == var[6]) && + ('H' == var[7]) && + ('=' == var[8])) { + char *src = var + 9; + char *dst = filename; + while(*src) { *dst++ = *src++; } + found = 1; + } + } + + while (!found && ('\0' != *path)) { // for every entry in the path char *tmp = AUXILIARY; Anyways.. This workaround seems to be ok: cd $SYNTH_HOST_TOOLS mkdir -p libexec/ecos/hal/synth/arch/v3_0_9 && \ ln -s ../../../../../../ecosynth libexec/ecos/hal/synth/arch/v3_0_9 Then use this to run the app: PATH=$SYNTH_HOST_TOOLS/libexec ./app --io 3. Make sure that ecosynth finds the .tcl script. It looks in LIBEXECDIR/ecos/PKG_INSTALL/ecosynth.tcl as seen from ecosynth.c: // The various core Tcl scripts are installed in the same // directory as ecosynth. The Tcl script itself will check whether // there is a newer version of itself in the source tree and // switch to that instead. assert((strlen(LIBEXECDIR) + strlen(PKG_INSTALL) + 20) < _POSIX_PATH_MAX); strcpy(ecosynth_tcl_path, LIBEXECDIR); strcat(ecosynth_tcl_path, "/ecos/"); strcat(ecosynth_tcl_path, PKG_INSTALL); strcat(ecosynth_tcl_path, "/ecosynth.tcl"); Where are these symbols defined? A grep leads to: $ grep -re LIBEXECDIR * src/host_tools/synth/Makefile: -DLIBEXECDIR=\"$(libexecdir)\" \ src/synth_host_tools/Makefile: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/host/ecosynth.c: assert((strlen(LIBEXECDIR) + strlen(PKG_INSTALL) + 20) < _POSIX_PATH_MAX); src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/host/ecosynth.c: strcpy(ecosynth_tcl_path, LIBEXECDIR); src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/host/ecosynth.c: Tcl_SetVar(interp, "synth::_ecosynth_libexecdir", LIBEXECDIR, TCL_GLOBAL_ONLY); src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/host/Makefile.am: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/hal/synth/arch/v3_0_9/host/Makefile.in: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/devs/eth/synth/ecosynth/v3_0_9/host/Makefile.am: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/devs/eth/synth/ecosynth/v3_0_9/host/Makefile.in: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/devs/framebuf/synth/v3_0_9/host/Makefile.am: -DLIBEXECDIR=\"$(libexecdir)\" \ src/ecos/ecos-3.0.9/packages/devs/framebuf/synth/v3_0_9/host/Makefile.in: -DLIBEXECDIR=\"$(libexecdir)\" \ [synth_fixes] tom@ubit:~/ecos_trailer$ It looks like this is in the configuration of the host tools: libexecdir = $(exec_prefix)/libexec Solution: set configure option --exec_prefix=.... 4. serial.tcl is not there. Is it no longer supported? Starting from http://www.cygwin.com/ml/ecos-discuss/2005-12/msg00012.html I googled for ecos-discuss/2005-12/msg00012.html and got to http://www.mail-archive.com/ecos-discuss@ecos.sourceware.org/msg06420.html which points to: http://www.xylanta.com/WordPress/?page_id=21 http://www.xylanta.com/Content/Downloads/eCos/synthserial-030826.tgz Link is fixed now. Entry: cscope eCos Date: Mon Sep 19 10:14:21 EDT 2011 I'd like to setup cscope for an application that uses eCos. This boils down to setting some paths correctly. One question: how to just load cscope.out ? Entry: pkgconf Date: Tue Oct 4 17:31:31 EDT 2011 The idea is that all that's configured in the .ecc will end up in a header file under install/include/pkgconf directory. The CDL sets the name of this directory. Is the name of this header file derived from the package name? I.e. I have here: cdl_package CYGPKG_IO_SERIAL_NXP_SPI_SC16IS install/include/pkgconf/io_serial_nxp_spi_sc16is.h But there's no mention of that .h file in the cdl nor the ecos.db so I'm assuming it's generated. Entry: 4 Control levels: VSR - ISR - DSR - Thread Date: Tue Oct 11 22:37:39 EDT 2011 A good place to start is probably [1]. ISR: Runs with interrupts disabled, or only hi-pri IEN. Can interrupt kernel calls and therefore cannot call most. DSR: Runs with interrupts enabled. Does not interrupt scheduler. Can make certain rescheduling calls like signalling condition variable, posting mutex. THR: Wait on mutex, condition variable. [1] http://ecos.sourceware.org/docs-latest/ref/devapi-device-driver-interface-to-the-kernel.html Entry: Driver API Date: Tue Oct 11 23:16:33 EDT 2011 eCos has a separate driver API [1] that works both in kernel and non-kernel environments. One thing that struck me is that semaphores are not mentioned in the cyg_drv_* API. Googling for it I find this [2]: While there is no technical reason for not using a counting semaphore in a DSR, there is no support for counting semaphores in the driver API. The main reason for this is that properly written device drivers should be able to work even when the eCos kernel is absent. To support this there is a non-kernel implementation of the API in hal/common/current/src/drv_api.c. It's a lot easier to implement mutexes and condition variables in such an environment that more complex synchronization mechanisms. Mutexes and condition variables are also the best minimal synchronization primitives, since the effect of any other primitive can be duplicated with them. [1] http://ecos.sourceware.org/docs-latest/ref/devapi-device-driver-interface-to-the-kernel.html [2] http://www.cygwin.com/ml/ecos-discuss/2001-12/msg00077.html Entry: eCos interrupt dispatching Date: Wed Oct 19 16:42:01 EDT 2011 Starting from Will Wagner's email[1], have a look at at91_misc.c packages/hal/arm/at91/var/current/src/at91_misc.c The handler sys_irq_handler() seems to return things like: CYGNUM_HAL_INTERRUPT_PITC CYGNUM_HAL_INTERRUPT_DEBUG CYGNUM_HAL_INTERRUPT_RTTC CYGNUM_HAL_INTERRUPT_PMC CYGNUM_HAL_INTERRUPT_MC CYGNUM_HAL_INTERRUPT_WDTC CYGNUM_HAL_INTERRUPT_RSTC CYGNUM_HAL_INTERRUPT_NONE So it looks like the return value of an interrupt is a dispatch point. Maybe it makes more sense to look at the implementation of the interrupt dispatch mechanism. The constants here are defined in packages/hal/arm/at91/at91sam7/v3_0_9/include/hal_platform_ints.h My guess is that the size of the interrupt table is then derived from these here: #define CYGNUM_HAL_ISR_MIN 0 #define CYGNUM_HAL_ISR_MAX 38 After some assembly code, in intr.cxx the method interrupt_end() handles the isr_ret return value. I can't make much sense of that. Let's read the manual[2]. From reading this, it's not only possible to do this kind of decoding in an ISR, but it seems that it is the point of separating VSR (system vectors) and ISRs (decoded from VSRs). The ISR tables are referenced in hal_inter.h: ( packages/hal/arm/arm9/at91rm9200/v3_0_9/include/var_ints.h ) externC CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; externC CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; externC CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; These tables are used in: HAL_INTERRUPT_DETACH HAL_INTERRUPT_ATTACH HAL_INTERRUPT_IN_USE However, I still don't get the following: - What are the valid return values for ISR routines. - Why do the ordinary return values (CYG_ISR_HANDLED | CYG_ISR_CALL_DSR) not clash with the ISR numbers? In kapi.h is defined: enum cyg_ISR_results { CYG_ISR_HANDLED = 1, /* Interrupt was handled */ CYG_ISR_CALL_DSR = 2 /* Schedule DSR */ }; It's actually different code. The code in at91_misc.c is different: it's not an ISR but something that runs before that. hal_default_irq_vsr -> hal_IRQ_handler() -> sys_irq_handler() Former is in vectors.S ( packages/hal/arm/arch/v3_0_9/src/vectors.S ) So, what I understand is that the ARM has only 2 "real" vectors: FIQ and IRQ. For the IRQ, the interrupt controller needs to be interrogated to see which source it was.. // The layout of these pointers should match the vector table above since // they are copied in pairs. .global vectors vectors: UNMAPPED_PTR(reset_vector) // 0x20 PTR(undefined_instruction) // 0x24 PTR(software_interrupt) // 0x28 PTR(abort_prefetch) // 0x2C PTR(abort_data) // 0x30 .word 0 // 0x34 PTR(IRQ) // 0x38 PTR(FIQ) // 0x3c #ifdef CYGSEM_HAL_ARM_PID_ANGEL_BOOT PTR(start) // This is copied to 0x28 for bootup // 0x40 #endif See here for an alternative explanation of ARM exceptions[3]. [1] http://ecos.sourceware.org/ml/ecos-discuss/2011-10/msg00008.html [2] http://ecos.sourceware.org/docs-latest/ref/hal-interrupt-handling.html [3] http://www.ethernut.de/en/documents/arm-exceptions.html Entry: ecos build system Date: Wed Oct 26 10:17:07 EDT 2011 Tried again last night to get an ecos system working from scratch but failed. What I want to do is the following: - start from a checkout of ecos-build and let it extract current cvs and tools. - use my "application" build system. Maybe it's best to put the application build system in the ecos-build project, and just keep the C files in a separate repo that depends on ecos-build. Current problem: where to get tools archive? Maybe I should just tar it up.. Check this out: http://ecos.sourceware.org/ecos/ecos-install.db This makes me point to here for one possible place to download the tools. I'm adding this to upstream dir. ftp://ecos.sourceware.org/pub/ecos/gnutools/i386linux/ecoscentric-gnutools-arm-eabi-20081213-sw.i386linux.tar.bz2 Next: where to ecosconfig and configtool come from? I found them in cvs/host/tools Ok, fixed that. These are now working again: http://zwizwa.be/darcs/ecos # examples http://zwizwa.be/git/ecos-build # build system Entry: AT91 GPIO interrupts Date: Thu Oct 27 12:45:37 EDT 2011 Problem: there is only one interrupt vector per PIO controller (32 pins). The AT91SAM7X has two controllers. Needed: demultiplex interrupts for individual pins such that each pin as a separate vector (or a subset of pins can be associated to vectors). Possibly add edge polarity filtering too. Let's start with the simplest part: set a breakpoint in the AT91 interrupt dispatcher and see from there. The modification to the code needs to be made in this file: packages/hal/arm/at91/var/*/src/at91_misc.c However, the defines to support an extra vector needs to be done somewhere else, in a more specific file: packages/hal/arm/at91/at91sam7/*/include/hal_platform_ints.h Need to add something like this below. Though the file above is probably not wat we need. I saw a different file that has a different definition for CYGNUM_HAL_ISR_MAX. // For GPIO interrupt demultiplexing #define CYGNUM_HAL_NB_GPIO 4 /* Make this configurable */ #define CYGNUM_HAL_GPIO_BASE 32 #define CYGNUM_HAL_GPIO0 (CYGNUM_HAL_GPIO_BASE + 0) #define CYGNUM_HAL_GPIO1 (CYGNUM_HAL_GPIO_BASE + 1) #define CYGNUM_HAL_GPIO2 (CYGNUM_HAL_GPIO_BASE + 2) #define CYGNUM_HAL_GPIO3 (CYGNUM_HAL_GPIO_BASE + 3) #define CYGNUM_HAL_ISR_MAX (31 + CYGNUM_HAL_NB_GPIO) Make sure to pick the section: #if defined(CYGHWR_HAL_ARM_AT91SAM7S) || defined(CYGHWR_HAL_ARM_AT91SAM7X) I fixed at91_misc.c like this. At the end of hal_IRQ_handler() #if CYGINT_HAL_ARM_AT91_GPIO_INTERRUPT if ((irq_num == CYGNUM_HAL_INTERRUPT_PIOA) || (irq_num == CYGNUM_HAL_INTERRUPT_PIOB)) { irq_num = pio_irq_handler(irq_num); } #endif Then a draft implementation of the dispatching function: int pio_irq_handler(int pio_irq_num) { // FIXME: remove hack! return CYGNUM_HAL_INTERRUPT_GPIO0; } To make it work for my current code (IRQ of SC16IS driver) I probably need to add some enable code. I.e. what does it mean to umask this interrupt? I assume that cyg_drv_interrupt_create() doesn't do anything with the interrupt number except for recording it, and all the machine logic is in cyg_drv_interrupt_unmask(), which seems to defer to HAL_INTERRUPT_UNMASK(), which is implemented by hal_interrupt_unmask() in at91_misc.c, so we have to add something there too. HAL_ARM_AT91_GPIOX_CFG_INTERRUPT(pin, enable) PA29 needs: - peripheral disable / PIO enable: PIO_PER - interrupt enable HAL_ARM_AT91_GPIO_CFG_INTERRUPT The PIO_PER is written from: HAL_ARM_AT91_GPIOX_CFG_DIRECTION HAL_ARM_AT91_GPIO_CFG_DIRECTION Even after this I still don't get any PIO interrupts: int pin = 29; HAL_ARM_AT91_GPIO_CFG_PULLUP(pin, AT91_PIN_PULLUP_DISABLE); HAL_ARM_AT91_GPIO_CFG_DIRECTION(pin, AT91_PIN_IN); HAL_ARM_AT91_GPIO_CFG_INTERRUPT(pin, true); HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, 1 << CYGNUM_HAL_INTERRUPT_PIOA); It's probably time to start reading some documentation. Let's see which hal_ functions need to be implemented. I quickly tried with FIQ again, and it seems that the code above that enables the port as input doesn't actually disable FIQ. What seems to happen is that the interrupt routine keeps being called, so it seems as if the interrupt is not acknowledged. How to "ack" a GPIO interrupt? Maybe read from the registers? Looks like PIO_ISR needs to be read. Indeed, that did it. Now we have a problem: the AT91_PIO_ISR read can have multiple interrupt flags set, but we ack all of them when reading. Trouble is in the pio_irq_handler() we can only raise one ISR, not a bunch.. How to retrigger? I sent a message to the eCos list: http://www.cygwin.com/ml/ecos-discuss/2011-10/msg00021.html I might have a hack though: Perform a read from the ports and try to figure out if there were any changes, i.e. do the change detect in software. If so, then trigger just one, but leave the ISR un-acked. Repeat until there are no detections in software. When done, read out the ISR and check if the number of interrupts matches. When can this go wrong? It should work reliably with level-triggered interrupts.. Though edge triggering might miss a pulse in software edge detection. However, this should be able to support a single edge interrupt. Entry: AT91 GPIO interrupts - alternative approach Date: Sun Oct 30 11:56:14 EDT 2011 Entry: #ifdef vs #if Date: Mon Oct 31 13:11:03 EDT 2011 In a CDL, does cdl_component correspond to an #ifdef or an #if? Indeed it seems so. Entry: Condition Variables : cyg_cond_wait() Date: Fri Nov 4 11:47:53 EDT 2011 For a brief general explanation on condition variables, see wikipedia[2]. The eCos implementation is quite standard. See docs[1]. In general it works like this. A condition variable is protected by a mutex to guarantee atomitcity of the variable access, and to guarantee that a condition can be signalled inside a critical section. // RECEIVER LOCK() WHILE(check_variable()) { WAIT() // UNLOCK, WAIT, LOCK } // SENDER LOCK() change_variable() SIGNAL() UNLOCK() The WAIT() operation needs to unlock the resource before blocking to allow senders to perform a signal. The WHILE loop is necessary because there might be more than one thread waiting on a condition. Even while receiving a signal (a wake-up call) there is no guarantee about the *semantics* of the data that is protected by the lock, because another thread might have woken up before us and changed the data before we get woken up. The sender side is simpler. SIGNAL or BROADCAST wake up one or more threads that are waiting for the condition variable. It's not necessary to do this inside the critical section, but often useful to do so to atomically change the protected data before signalling. [1] http://ecos.sourceware.org/docs-latest/ref/kernel-condition-variables.html [2] http://en.wikipedia.org/wiki/Monitor_(synchronization)#Blocking_condition_variables Entry: eCos board support: how to add an _init() method? Date: Sun Nov 13 09:10:47 EST 2011 How can you add an init method to a board support package? I currently have board-specific code added to hal_hardware_init() in the at91_misc.c file from the at91 variant HAL. How is this code registered? In the following file I find somethings useful ./at91sam7/v3_0_9/include/plf_io.h:237: //---------------------------------------------------------------------- // The platform needs this initialization during the // hal_hardware_init() function in the varient HAL. #ifndef __ASSEMBLER__ extern void hal_plf_hardware_init(void); #define HAL_PLF_HARDWARE_INIT() \ hal_plf_hardware_init() #ifdef CYGHWR_HAL_ARM_AT91SAM7X extern void hal_plf_eth_init(void); #define HAL_PLF_ETH_INIT() \ hal_plf_eth_init() #endif #endif //__ASSEMBLER__ Igoring that __ASSEMBLER__ part, depending on whether the CYGHWR_HAL_ARM_AT91SAM7X option is defined, a macro HAL_PLF_ETH_INIT() is defined. Where is that called? It's in the variant hal file's hal_hardware_init(): #ifdef CYGPKG_DEVS_ETH_ARM_AT91 #ifdef HAL_PLF_ETH_INIT HAL_PLF_ETH_INIT(); #endif #endif This is a bit of spaghetti isn't it? Entry: Embedding Lua in eCos Date: Thu Jan 12 16:30:13 EST 2012 Compiling was quite straightforward, it's very clean C. First problem though is reliance on FILE (fopen/fread) for getting scripts in, but this doesn't seem to be mapped to files on synthetic target. Doesn't seem to be supported. I see 2 approach that might work: - hack ecos to support linux files on the device layer - catch all Lua calls to fopen/fread/fclose/... and redirect to synth_* The latter seems simplest. EDIT: This works well. I needed to wrap the following calls to get to a basic REPL (ilua) and load/save of files: synth_FILE *synth_stdin; synth_FILE *synth_stdout; synth_FILE *synth_stderr; synth_FILE *synth_fopen(const char *path, const char *mode); int synth_fclose(synth_FILE *sf); int synth_getc(synth_FILE *sf); size_t synth_fread(void *_buf, size_t size, size_t nmemb, synth_FILE *sf); int synth_feof(synth_FILE *sf); int synth_ferror(synth_FILE *sf); size_t synth_fwrite(const void *_buf, size_t size, size_t nmemb, synth_FILE *sf); int synth_fflush(synth_FILE *sf); void synth_clearerr(synth_FILE *sf); char *synth_fgets(char *s, int size, synth_FILE *sf); int synth_vfprintf(synth_FILE *sf, const char *format, va_list argptr); int synth_fprintf(synth_FILE *sf, const char *format, ...); These are left unimplemented in the first pass, but stubs where necessary for compilation/linking: int synth_fgetc(synth_FILE *stream); synth_FILE *synth_freopen(const char *path, const char *mode, synth_FILE *stream); synth_FILE *synth_tmpfile(void); int synth_fscanf(synth_FILE *stream, const char *format, ...); int synth_ungetc(int c, synth_FILE *stream); int synth_fseek(synth_FILE *stream, long offset, int whence); long synth_ftell(synth_FILE *stream); int synth_setvbuf(synth_FILE *stream, char *buf, int mode, size_t size); int synth_fputs(const char *s, synth_FILE *stream); [1] http://heavycoder.com/tutorials/lua_embed.php