Strange get_usb_power inconsistency - page 2 - Script Writing - CHDK Forum supplierdeeply

Strange get_usb_power inconsistency

  • 19 Replies
  • 7114 Views
Re: Strange get_usb_power inconsistency
« Reply #10 on: 21 / June / 2010, 14:25:01 »
Advertisements
Quote
Have you observed every output pulse from the micro-controller on an oscilloscope?

I have.  They're on the mark and consistent widths (unfortunately!).

Quote
Have you tried Lua? Perhaps it works better than uBasic for something like this?

No, as Microfunguy said I'm using SDM for various reasons and it doesn't support Lua.

The strange thing is that the same hardware configuration with a very simplified script like:

Code: [Select]
:main
a = 0
do
a = get_usb_power
sleep_for 45
until (a > 0)
cls
print "  time: ", a
goto "main

Will print out nice accurate pulse measurements.  What is it about the complexity of the script that is affecting the accuracy of get_usb_power?  Is a larger script demanding more processing time, resulting in the camera 'skipping' USB pulse width increments within my_kbd_read_key() (which is where the width count is accumulated)?

Another interesting facet is that if I increase the delay time in the USB measurement loop in the complex script, say to 350ms, the results of get_usb_power get more accurate.

Re: Strange get_usb_power inconsistency
« Reply #11 on: 21 / June / 2010, 16:28:06 »
Let us see how all of this works ....

In main.c, createHook creates physw_hook.

(I am not sure how 'hooks' work).

physw_hook runs mykbd_task().

How often is that function called ?

mykbd_task() does something with a new stack (what?) and calls mykbd_task_proceed().

mykbd_task_proceed() runs in an endless loop while physw_status is true.
(maybe physw_status is only false when you turn the camera off ? )

Every ten milliseconds, wrap_kbd_p1_f() is called which calls my_kbd_read_keys().
That calls kbd_process() and if a script is running, process_script() is called to process any stack operations.
ubasic_run() is then called to execute  the next uBasic line with line_statement()
------------------------------------------------------------------------------------------------------------
SDM has an option to speed-up operation by processing up to five lines per 10msec tick.
That value is set with a script command but by default is one.
Some commands are exempt from this option (they have yield=1 in ubasic.c statement().
------------------------------------------------------------------------------------------------------------

The line tokens are then scanned, labels skipped and statement() executed.
factor() returns the USB pulse-width value from get_usb_power(0).

On returning to my_kbd_read_keys(), if a USB V+ is present a counter is incremented.
If a voltage is not present but the count is non-zero, usb_power is set to that value and the counter reset to zero.

The uBasic command get_usb_power(0)  returns the value of usb_power and then sets it to zero.


« Last Edit: 21 / June / 2010, 17:41:47 by Microfunguy »

*

Offline reyalp

  • ******
  • 14080
Re: Strange get_usb_power inconsistency
« Reply #12 on: 22 / June / 2010, 04:28:04 »
In main.c, createHook creates physw_hook.

(I am not sure how 'hooks' work).

physw_hook runs mykbd_task().
How often is that function called ?
Once, at startup.

Quote
mykbd_task() does something with a new stack (what?) and calls mykbd_task_proceed().
Since scripting and other stuff needs a bigger stack than the default canon stack for this task, it makes a new one. This isn't actually needed on dryos cams, since we can re-write the original CreateTask call to have as big a stack as we want (see sd990 and d10, doing it this way saves a couple KB of memory)
Quote

mykbd_task_proceed() runs in an endless loop while physw_status is true.
(maybe physw_status is only false when you turn the camera off ? )
physw_run, not physw_status.
Quote
Every ten milliseconds, wrap_kbd_p1_f() is called which calls my_kbd_read_keys().
because sleep() yields control to other tasks on the system, you cannot be certain that this will actually regain control every 10ms. It is also possible for the other stuff executing in this loop to take longer than ten ms.
Quote
That calls kbd_process() and if a script is running, process_script() is called to process any stack operations.
Note that this stack should not be confused with the task stack mentioned earlier.
Don't forget what the H stands for.

Re: Strange get_usb_power inconsistency
« Reply #13 on: 22 / June / 2010, 04:55:01 »
Thanks, useful information.

Do we know when physw_run is false ?

Are you saying that occasionally the usb_power counter will not be incremented ?

Do all CHDK tasks have to yield to certain Canon tasks ?

When not capturing an image or movie or writing to a file, are the CHDK tasks allocated equal time ?

Presumably, we have absolutely no control how tasks are allocated ?



Re: Strange get_usb_power inconsistency
« Reply #14 on: 22 / June / 2010, 14:59:25 »
Quote
It is also possible for the other stuff executing in this loop to take longer than ten ms.

I wonder if this is the cause of the consistently low measurements.  It seems like the error is cumulative, ie the longer the pulse to measure, the more below the mark the measurement is.  Take a look at the two attachments I've added.  Both are measurements of the same pulse width (400ms).  The yellow trace is the pulse generated by the microcontroller.  The green trace is generated by scoping a ubasic_set_led executed from within my_kbd_read_keys, in the section:

Code: [Select]
      remote_key = (physw_status[2] & USB_MASK)==USB_MASK;   // USB V+ present ?
      if (remote_key)                 // Yes
      {
        remote_count += 1;      // so increment 1/100 sec counter

// TEST
// toggle led
toggle = !toggle;
ubasic_set_led(9,toggle,100);

       }

So, every time remote_count is incremented, the green trace toggles. 

One of the measurements is from the simplified and accurate script for measurement, the other is from my full complex script.  It looks like there are long durations between toggles in the complex script waveform, causing missing toggles and therefore missing increments of remote_count.

I hope this is useful, I'm willing to scope out more things if needed.

*

Offline reyalp

  • ******
  • 14080
Re: Strange get_usb_power inconsistency
« Reply #15 on: 22 / June / 2010, 22:53:18 »
Thanks, useful information.

Do we know when physw_run is false ?
I don't know, that loop is functionally equivalent to the original unmodified physw task.
Quote
Are you saying that occasionally the usb_power counter will not be incremented ?
I'm saying that the sleep(10) may take longer than 10ms, and that iterations of the loop may also take longer than 10ms even if the sleep doesn't. You should be able to figure out how long it took quite easily with get_tick_count.
Quote
Do all CHDK tasks have to yield to certain Canon tasks ?
Canon tasks need some CPU time for the camera to function normally. physw task is really a canon task anyway, we just modify it a bit. The only true CHDK task (doesn't exist in stock firmware) is spytask.
Quote
When not capturing an image or movie or writing to a file, are the CHDK tasks allocated equal time ?
I'm not completely clear how scheduling works on these systems. Something I've wanted to investigate, but round toits have been extremely scarce recently.

I bet ewavr knows something about this topic :)
Quote
Presumably, we have absolutely no control how tasks are allocated ?
Priority is one of the parameters to CreateTask. Presumably we could hack in more control.
Don't forget what the H stands for.

Re: Strange get_usb_power inconsistency
« Reply #16 on: 23 / June / 2010, 18:10:53 »
Priority is one of the parameters to CreateTask.

I have seen this declaration for ARM :-

void CreateTask(TCB *t, void (*task)(void *),long *stack, int stacksize,int priority,char *name,void *arg);

What does 'void (*task)(void *)'   define ?



It would seem the Canon firmware uses  :-

int _CreateTask (const char *name, int prio, int stack_size, void *entry, long parm);

Quote
.The only true CHDK task (doesn't exist in stock firmware) is spytask.

and init_chdk_ptp in experimental builds.

So, why is task priority 0x19 ?

In createHook() we have :-

    char *name = (char*)(*(long*)((char*)pNewTcb+0x34));

A lot of type-casting going on there, what does it all mean ?

« Last Edit: 23 / June / 2010, 18:27:32 by Microfunguy »

*

Offline ewavr

  • ****
  • 1057
  • A710IS
Re: Strange get_usb_power inconsistency
« Reply #17 on: 23 / June / 2010, 19:14:05 »
In createHook() we have :-
    char *name = (char*)(*(long*)((char*)pNewTcb+0x34));

A lot of type-casting going on there, what does it all mean ?

Access to internal task structures: name and entry point address. Now this code is obsolete (http://chdk.setepontos.com/index.php/topic,4801.0.html - now in CHDK).


Re: Strange get_usb_power inconsistency
« Reply #18 on: 24 / June / 2010, 12:12:11 »
What does 'void (*task)(void *)'   define ?

A function pointer. You can define a function as:

void foo (void *arg) { }

and then pass foo to CreateTask. foo would be the task entry point.

char *name = (char*)(*(long*)((char*)pNewTcb+0x34));
A lot of type-casting going on there, what does it all mean ?

The type casting wouldn't concern me. Use of magic numbers like 0x34 would.

Andy
« Last Edit: 24 / June / 2010, 12:14:54 by ajayre »

Re: Strange get_usb_power inconsistency
« Reply #19 on: 24 / June / 2010, 18:23:19 »
Thanks Andy and EWAVR.

You can learn a lot studying CHDK.

VitalyB and GrAnd did amazing original work.


David

 

Related Topics