Executive summary: It was a hardware problem.
In a previous blog post I mentioned that reading an SD Card didn’t work for me when using NuttX. So, I started a long debugging session again but I couldn’t find anything that could point to something wrong.
I then switched between the AgonLight and the Z20X computer and I noticed that the error message was different. While Agonlight returned error code 19 (No such device
), the Z20X returned error code 22 (Invalid argument
). This meant, NuttX did find an SD Card on the Z20X but for some reason, it didn’t find it on the AgonLight.
Time to switch on logging again. This time I limited logging to the file system and SPI. Only to find out NuttX crashed immediately. Luckily, after a bit of experimenting, I found that SPI logging on its own did work. I’ll leave the file system logging failure for a future date.
With SPI logging on, there was a clear difference between the AgonLight and the Z20X:
AgonLight
nsh> frequency: 400000
mode: 0
ERROR: spi_waitspif returned -5
ERROR: spi_transfer returned -5
ERROR: SPI timed out
ERROR: spi_waitspif returned -116
ERROR: spi_transfer returned -116
ERROR: SPI timed out
...
ERROR: spi_waitspif returned -116
ERROR: spi_transfer returned -116
ERROR: SPI timed out
ERROR: spi_waitspif returned -116
ERROR: spi_transfer returned -116
NuttShell (NSH) NuttX-9.1.1
nsh>
Z20X
nsh> frequency: 400000
mode: 0
cmd: 00ff resp: 80000
cmd: 00ff resp: 80000
...
cmd: 00ff resp: 80000
cmd: 00ff resp: 80000
frequency: 18432000
cmd: 00ff resp: 80000
NuttShell (NSH) NuttX-9.1.1
nsh>
That’s a clear difference and again indicating to something seriously wrong with the AgonLight hardware I have.
Interesting to note is that NuttX starts initialising the SPI interface at a low frequency (in this case 400 kHz) and only when all is well, switches to full speed, in this case 18.432 MHz.
At this point I remembered I already had trouble with this AgonLight. A few weeks before trying out NuttX, I installed the most recent MOS and VDP releases. But the board behaved very unstable, typically when the SD Card (SPI interface) was accessed. Not having much time at that moment, I didn’t investigate further. Now, the loggings which NuttX generated seemed to point to a hardware SPI issue as well.
Switching to the AgonLight2
Luckily, just a few weeks ago, I had ordered an AgonLight2 from Olimex including the case (which, I only later discovered, doesn’t have an opening for the ZDI cable at the side of the case :-(
Loading the same binary on the AgonLight2 quickly confirmed that the original AgonLight indeed has a problem since the AgonLight2 completed its SPI setup without any problems.
Finding the SD Card
The available devices can be found by listing the /dev
directory like so:
nsh> ls /dev
/dev:
console
mmcsd0
null
ttyS0
Next to the console
(which is actually the serial port on UART1
) we see mmcsd0
appearing as well which is our SD Card.
Trying to mount the SD Card
The SD card (mmcsd0
) can be mounted (to the /mnt
directory I created first) with the following NSH mount command:
nsh> mkdir /mnt
nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard
nsh: mount: mount failed: 22
nsh>
However, even with a confirmed working SPI interface, I still couldn’t mount the SD Card (error 22, which is Invalid argument
).
Then I had another one of those light bulb moments. What if I used NuttX itself to format the SD Card? No sooner said than done I tried the following command:
nsh> mkfatfs -F 32 /dev/mmcsd0
Waited a little bit and the nsh>
prompts appears again without errors!
I then examined the SD Card with my Linux PC:
Hmm. There is still something odd going on. Only 6.1 GByte seems to be available of the 32 GByte SD Card. Despite that, I had no problems to copy a few files and create new directories on the SD Card.
Popping the filled in SD Card back into the AgonLight2 we give it another try to mount the SD Card:
Executing an ls /dev
gives us the available devices:
nsh> ls /dev
/dev:
console
mmcsd0
null
ttyS0
nsh>
Let’s create a mounting point:
nsh> mkdir /mnt
nsh>
Mount the block device mmcsd0
(aka the SD Card):
nsh> mount -t vfat /dev/mmcsd0 /mnt
nsh>
Show the directory listing of /mnt
:
nsh> ls /mnt
/mnt:
folder.jpg
nuttx-9.1.1.txt
dir1/
nsh>
Yes, everything I copied from my Linux PC is there.
Let’s move to /mnt
nsh> cd /mnt
nsh>
Check the content of dir1
:
nsh> ls dir1
/mnt/dir1:
DISCLAIMER-WIP
INVIOLABLES.txt
LICENSE
NOTICE
README.txt
ReleaseNotes
nsh>
Dump the content of a text file to the terminal with the built in cat
command:
nsh> cat nuttx-9.1.1.txt
NuttX-9.1.0 Release Notes -------------------------
* Major Changes to Core OS:
* New Features:
- PR-977 PR-987 PR-998 PR-995 PR-997 PR-1007 Thread Local Storage (TLS)
is now a required feature and used by all architectures
There is detailed information on the implementation and how this
impacts errno specifically in the Wiki article: Userspace errno and
TLS
- PR-957 PR-947 PR-963 PR-969 Provide nx_ versions of many functions
that are used internally to avoid disrupting errno in userspace
- PR-965 PR-980 PR-984 ioctl is now always in the variadic form.
Syscalls in KERNEL builds are also more efficient with this as well now.
Previously the ioctl prototype was normally defined as:nsh>
nsh>
Everything works as expected!
So everything is right now?
Let’s check the available free disk space with the built in df
command:
nsh> df
Block Number
Size Blocks Used Available Mounted on
1728069632 1761935360 -33226752 -972750848 �����~�
���� avoP� Bl 0 0 0 -973078528 (null)
nsh>
Hmm, that doesn’t look good. Remember the 6.1 GByte size on a 32 GByte SD Card earlier? Those problems might be related. At this moment I have 2 theories that can explain that:
-
The code can’t handle such large SD Cards. That could definitely be true in the past where drivers were limited to 4 GByte max in size. Unfortunately, finding small SD Cards is hard these days.
-
More likely is that code somewhere is assuming an
int
to be 32 bits. On the eZ80, using the Zilog ZDS II toolchain, this is not true and anint
is only 24 bits. Hence a very high chance that variables overflow and give garbage numbers as we see with thedf
command.
I’ll look into this further at a later time when I have some more free time again.
PS I did contact Bernardo Kastrup to inform about the hardware issue I found with the original AgonLight. Just in case others might experience problems in the same area.
The code
What I did was simply downloading the source code tarballs for both nuttx and apps of version 9.1.1.
After extracting both tarballs, I initialized a git repo of it. Then I created my own branch ccc_dev_branch
and used this branch to check in all my small modifications that lead to a NuttX that can compile, and finally works on the eZ80, under wine on Linux using the official ZDS II tools from Zilog.
You can find the git repo here.
Disclaimer
Although I verified the build on 2 separate PC’s (but using the same Manjaro Linux Distro) I can’t guarantee it will work for everyone. I guess, the best I can say in such circumstances is: It works on my computer: ¯\\_(ツ)_/¯