How to mount a SD card as USB mass storage and run own program in parallel

Discussion about writing software for VS1005 and the VSOS Operating System. Also posts about VS1005-related hardware design and device drivers should be posted here.
johns
User
Posts: 9
Joined: Mon 2016-04-04 23:42

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by johns » Fri 2016-05-27 18:07

Wow sounds like I stumbled on something strange :?

I am using the VLSI breakout board with power supplied by USB. Is there a way I can send files through these forums in a private message? I looked around and cannot find the option.

tanuki
User
Posts: 13
Joined: Sun 2015-08-23 15:36

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by tanuki » Sun 2016-05-29 15:04

Hi Panu

I finally found time to try out the usbmsc driver. On my set up, the driver works perfect when i add it to the config file: the SD Card is detected properly as mass storage. Thanks again!

Now I want to add it to my existing application, the use case is quite basic:
  • On power up, start usbmsc if USB supply is detected (and mount SD Card as USB mass storage)
  • On any button press, remove usbmsc and run my application using USB power (and play files from SD Card)
  • In case of no USB power, directly run my application
You recommended in your previous post the function CreateTaskAndStack(), I was also thinking on functions like loadLibrary() and dropLibrary(). But I'm struggling because I'm missing the overview on how to add and remove tasks properly and there are open questions like 'how much stack does usbmsc need'?" :roll: .

Can you please provide me a code snippet how to mount and unmount the usbmsc driver for the use case mentioned above? And what is the recommended way to start my own application (available as ap3 file based on an endless loop)?

Thanks for your help!

User avatar
Panu
VLSI Staff
Posts: 2562
Joined: Tue 2010-06-22 13:43

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by Panu » Tue 2016-05-31 8:43

Hi!

I'll look into both topics soon enough, but for the coming week at least I'm 100% occupied on another engineering issue, which I'm trying to solve. I hope I'll get it done soon.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

tanuki
User
Posts: 13
Joined: Sun 2015-08-23 15:36

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by tanuki » Sun 2016-10-23 16:07

Hello VLSI team
I hope you had a good summer, too!
I still got the issue how i should run/drop the usbmsc to show the content of an SD card on USB. As i understand, the usbmsc needs exclusive access to SDSD, so i should not access any files while the usb mass storage is active. To be able to operate my device powered from USB, i want to drop usbmsc as soon as a button is pressed.

Below a code snippet, the problem is as far as i understand that usbmsc does not return.

Code: Select all

  /*
  *  detect USB supply and start mass storage service if powered from USB
  */
  GpioSetAsInput(PINDEF_POWER_DETECTUSB);
  if(GpioReadPin(PINDEF_POWER_DETECTUSB))
  {
    u_int16 *usbmscLib = NULL;
    usbmscLib = LoadLibraryP("usbmsc", "E");
    
    if(usbmscLib){
      RunLoadedFunction(usbmscLib, ENTRY_MAIN, (int)"E");
      
      do{
        newEvent = Button_getEvents();
      }while(newEvent == buttonEvents_noEvent);  // exit as soon as a button is pressed
      
      DropLibrary(usbmscLib);
    }
  }
  //...continue with regular program

You had a proposal to use CreateTaskAndStack(), which presumably runs it in parallel. But its is way beyond my skills to use this properly. Could you please make an example how to start and stop usbmsc as a parallel process?

Thanks a lot!

User avatar
Panu
VLSI Staff
Posts: 2562
Joined: Tue 2010-06-22 13:43

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by Panu » Mon 2016-10-24 12:08

Hi!

Ok, here goes nothing... :D

I very quickly adapted the USBMSC program to make new program USBMSCD. When started from the command line with a drive letter, it increments its own reference count so that it stays in memory. Then it starts a new task for the function UsbMainLoop, with task name "USBD". It then exits from main to the command line, leaving the UsbMainLoop running in the background.

I wrote some extra code to main() to control its own reference count, so that the program can decide itself whether it wants to stay resident or not. Without such code you'd have to use DRIVER +USBMSCD D and DRIVER -USBMSCD to load or unload it. Now there's a little friendlier command line interface:

If the program is called without parameters, or with something other than a letter from A to Z, it decreases its own reference count to 1. This causes the USBMSCD library to be dropped after returning to main. This causes a call to fini(). Fini() sets an internal variable usbTaskRunning to PLEASE_STOP (-1). UsbMainLoop() detects this, ends and returns. Then fini() returns also and the program is finally cleared away from memory.

Here's the source code of main.c in case you want to point out something:

Code: Select all

#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include "usbmsc.h"
#include <taskandstack.h>
#include <kernel.h>

u_int16 *self; //ptr to our own loaded library
s_int16 usbTaskRunning;

//Set absolute location of AddTask in VS1005G ROM. Another option would be to include rom1005g.o in linking.
CHIPSPECIFIC (VS1005G) LINK_ABS (AddTask,36693)


ioresult main(char *parameters) {
	int newDevice = parameters ? (*parameters & ~0x20) : 0;
	int i=0;
	while(1) { //Find our own library reference
		self = loadedLib[i++]; //for each loaded library
		if (self[2] == (u_int16)main) break; //if library main entry is our main function, then break.
	}
	self[1]++; //increase our reference count so we are not dropped from memory even if we are started from the commmand line

	if (newDevice>='A' && newDevice<='Z') {
		newDevice -= 'A';
		usbDisk = vo_pdevices[newDevice];
		usbTaskRunning = IS_RUNNING;
		CreateTaskAndStack(UsbMainLoop, "USBD", 512, 10); 
	} else {
		self[1]=1; //set our own ref count to 1 so we are dropped from memory when main returns (DropLibrary will call fini()).
	}
}


void fini(void) {
	printf("USBD:Exiting\n");
	usbTaskRunning = PLEASE_STOP;
	while (usbTaskRunning != NOT_RUNNING) {
		Delay(10); //wait for USB task to finish
	}
}
And here's an example run of the driver:
S:>usbmscd d
USB publishing disk SD/SD Card.
S:>
[SD card is now visible in the PC]
S:>cd ::
Currently installed system devices are:
- D: 922M SD/SD Card, handled by FAT.
- S: 1920K SPI Flash c814, handled by FAT.
S:>
S:>usbmscd
USBD:Exiting
[SD card is now removed from the PC]
S:>
Good Luck!
I had to add a Delay(1) call to the UsbMainLoop to make it give CPU time to the other tasks. I don't really know if the USB loop likes running that way, but it seems to work. No guarantees! :D

Oh, and hardware locking is not used, although it really should be. You've been warned! Don't try to do anything else with the USB while this program is running.

-Panu
Attachments
arch-usbmscd-2016-10-24-12-56-USBD.zip
Experimental USB MSC background daemon
(19.6 KiB) Downloaded 62 times
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

User avatar
Panu
VLSI Staff
Posts: 2562
Joined: Tue 2010-06-22 13:43

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by Panu » Mon 2016-10-24 12:35

Ok, tested it myself... works but is kind of slow.

I made a new version, this one is faster (it calls Delay less often) and I also removed the ramdisk functionality to save some memory.

Please tell me how it works, I'm interested myself :D It's quite fun really, for example I was able to start playing an MP3 song while it was still being copied from the PC.

Oh, one more thing; as I tried to play the MP3, I found that the ROM version of SetClockSpeed, which the USBMSCD calls, unfortunately switches off the analog output as a side effect. That should be fixed in the source code, but I just reactivated the DAC and drivers by running "ybitset fecb,6" and "ybitset fecb,3".

-Panu
Attachments
arch-usbmscd-2016-10-24-13-33-faster1.zip
(18.3 KiB) Downloaded 83 times
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

tanuki
User
Posts: 13
Joined: Sun 2015-08-23 15:36

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by tanuki » Sun 2016-10-30 23:56

Hi Panu

Thanks for your support! On my setup, the usbmscd works on the usb side as good as the original driver. I get some 'Data fail' messages on the UART, but i can see the files of the SD card, so far so good. But when i call dropLibrary(), i still got the SD card connected over USB. As you mentioned, it sometimes manages to play a part of the song, but the processor seems too busy with the USB for a proper operation.

As far as i understand, the function fini was not executed so tried to call it directly with the command

Code: Select all

RunLoadedFunction(usbmscLib, ENTRY_FINI, 0);
And this way it works: the USB disk disapears and the rest of the program runs as before. But it seems the library is still loaded.

Can you drop usbmscd using dropLibrary() on your place?

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by mar_tin » Tue 2018-03-13 14:33

I tried USBMSCD driver, it shows contents of the SD Card, can read/write from the PC. But I can not use AUODAC s with it. If I use AUODAC s in config file, I just get buzzing noise on the output and no sound when I use playfile or playdir in the VSOS Shell.

But when I comment AUODAC out, I can play files with no problem. I guess it should not work like this...?

Another thing is that USBMSC does not work at all for me, always returns the same error. Am I missing some dependent driver for USBMSC?

Code: Select all

Driver: USBMSC... E: Symbol _RingBufCopyjZC (CRC32 222a86d1) not found.
1 fatal errors. Stop.
Working with kernel 3.54 on VS1005 Dev Board

User avatar
Panu
VLSI Staff
Posts: 2562
Joined: Tue 2010-06-22 13:43

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by Panu » Tue 2018-03-13 20:07

Hi!

I think this problem comes from a recent modification of VSIDE that we made.. please see the instructions here: viewtopic.php?f=13&t=2203&p=11642#p11642 and please report if they were useful or not :)

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to mount a SD card as USB mass storage and run own program in parallel

Post by mar_tin » Wed 2018-03-14 12:18

Hi Panu, thank you for the link, sorry that I missed that thread.

Rebuilding the drivers with some minor changes by the instruction did not help at all.

According to the instructions I would expect those two drivers act up exactly vice-versa, because even the the log says that I'm running "VSOS 3.53 build Mar 08 2018 14:39:06", which I built from " VSOS_354g_IntFlash" package (I did not correct the version number). And I took all possible drivers from the "VSOS_354_RootAndLibrariesSourceCode\root\SYS", except for the USBMSCD.

I will try to reflash the kernel from prebuilt package, just to be sure. Alternatively I could try the older version of kernel and/or IDE.

- Martin

Post Reply