source: svn/trunk/newcon3bcm2_21bu/dta/src/app/bapp_util.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 18.9 KB
Line 
1/******************************************************************************
2 *    (c)2008-2009 Broadcom Corporation
3 *
4 * This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 * and may only be used, duplicated, modified or distributed pursuant to the terms and
6 * conditions of a separate, written license agreement executed between you and Broadcom
7 * (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 * no license (express or implied), right to use, or waiver of any kind with respect to the
9 * Software, and Broadcom expressly reserves all rights in and to the Software and all
10 * intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 * Except as expressly set forth in the Authorized License,
15 *
16 * 1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 * and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 * THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 * USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 * ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile:  $
39 * $brcm_Revision:  $
40 * $brcm_Date:  $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * Created: 09/28/2009 by Jeff Fisher
47 *
48 * $brcm_Log:  $
49 *
50 *
51 *****************************************************************************/
52#include "bapp_util.h"
53#include "bapp.h"
54#include "chan_mgr.h"
55
56BDBG_MODULE(bapp_util);         /* Register software module with debug interface */
57
58#define MSO_PHONE_LEN   (MAX_PHONE_LEN - 1)
59#define CMD_LEN 3
60
61const char *s_def_phone_str = "1-800-COMCAST (1-800-266-2278)";
62const char *s_def_service_str = "Please check the connections and if the problem is not resolved please contact Comcast at %s to restore service.  We're sorry for the inconvenience.";
63
64#ifdef PROFILE
65#include "bprofile.h"
66static bprofile_sys_iface s_sys_iface;
67static bprofile_entry *s_table = NULL;
68static int s_num_entrires = 10000;
69
70static const char *bapp_util_thread_name(bprofile_thread_id thread)
71{
72        return (const char*)thread;
73}
74
75/*
76Summary:
77        Profiling utility start profiling.
78*/
79void bapp_util_start_profiling(void)
80{
81        if (s_table == NULL)
82        {
83                BKNI_Memset(&s_sys_iface,0,sizeof(s_sys_iface));
84                s_table = BKNI_Malloc(s_num_entrires *sizeof(bprofile_entry));
85        }
86        BDBG_ASSERT(s_table);
87        bprofile_sys_iface_init(&s_sys_iface);
88        bprofile_start(s_table, s_num_entrires);
89}
90/*
91Summary:
92        Profiling utility stop profiling.
93*/
94
95void bapp_util_stop_profiling(void)
96{
97        int nentries = bprofile_stop();
98        BDBG_WRN(("profile nentries %d\n", nentries));
99        s_sys_iface.thread_from_stack = bos_task_from_stack;
100        s_sys_iface.thread_name = bapp_util_thread_name;
101        s_sys_iface.maxentries = s_num_entrires;
102        s_sys_iface.show_entries = 15;
103        s_sys_iface.split_threads = true;
104        s_sys_iface.substract_overhead = true;
105        s_sys_iface.call_count = true;
106        s_sys_iface.preempt_time = true;
107        s_sys_iface.comma_delimited = true;
108        bprofile_report_flat(s_table, nentries, &s_sys_iface);
109}
110#endif /* PROFILE */
111/*
112Summary:
113        Utility IO function.
114Description:
115        Utility IO function to be used for pseudo IO.
116*/
117
118int bin_read( void *buffer, int size, int count, void *fp )
119{
120        bin_read_t *p_br = (bin_read_t*)fp;
121        size = size * count;
122        if (p_br->cnt + size > p_br->size)
123        {
124                BDBG_MSG(("Requesting more bytes than available (cnt = %d, size = %d,total = %d)\n",
125                                  p_br->cnt,size,p_br->size));
126                size = p_br->size - p_br->cnt;
127        }
128
129        memcpy(buffer,&p_br->data[p_br->cnt],size);
130        p_br->cnt += size;
131        return size;
132}
133/*
134Summary:
135        Utility IO function.
136Description:
137        Utility IO function to be used for pseudo IO.
138*/
139
140unsigned int bin_tell(void *fp )
141{
142        bin_read_t *p_br = (bin_read_t*)fp;
143
144        return p_br->cnt;
145}
146/*
147Summary:
148        Utility IO function.
149Description:
150        Utility IO function to be used for pseudo IO.
151*/
152
153int bin_set(void *fp, int offset, int whence )
154{
155        bin_read_t *p_br = (bin_read_t*)fp;
156
157        if ((whence != 0) || ((unsigned int)offset > p_br->size))
158                return -1;
159
160        p_br->cnt = offset;
161        return 0;
162}
163#if 0
164/**
165Summary:
166        Get ticks used to establish time deltas in the applicaiton.
167**/
168
169unsigned int bapp_util_get_ticks(void)
170{
171        b_timeval tv;
172
173        GETTIMEOFDAY(&tv);
174
175        return((tv.tv_sec * BAPP_TICKS_PER_SECOND) + (tv.tv_usec * BAPP_TICKS_PER_SECOND) / 1000000);
176}
177#endif
178
179#define isaf(c)         ((c) >= 'a' && (c) <= 'f')
180#define isAF(c)         ((c) >= 'A' && (c) <= 'Z')
181#define isdigit(c)      ((c) >= '0' && (c) <= '9')
182
183/**
184Summary:
185        Convert string to int value
186**/
187int bapp_util_atoi(unsigned char *str_p, int bytes)
188{
189        int i, value = 0;
190        unsigned char c, *p;
191
192        p = str_p;
193
194        for (i = 0; i < bytes; i++)
195        {
196                value <<= 4;
197                c = *p++;
198                if (isdigit(c))
199                        value |= (c - '0');
200                else if (isaf(c))
201                        value |= (c - 'a') + 10;
202                else if (isAF(c))
203                        value |= (c - 'A') + 10;
204                else
205                        return 0;
206        }
207        return value;
208}
209
210/****************************************************************
211 * timeval_subtract
212 *
213 * INPUTS:      x,y - subtract the timevals
214 * OUTPUTS:     result - result of x,y timeval subtract
215 * RETURNS:     none
216 * DESCRITPION: Subtract the `b_timeval' values X and Y,
217 *              storing the result in RESULT.
218 *              Return 1 if the difference is negative, otherwise 0
219 ****************************************************************/
220
221int timeval_subtract (b_timeval *result, b_timeval *x, b_timeval *y)
222{
223        /* Perform the carry for the later subtraction by updating y. */
224        if (x->tv_usec < y->tv_usec)
225        {
226                int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
227                y->tv_usec -= 1000000 * nsec;
228                y->tv_sec += nsec;
229        }
230        if (x->tv_usec - y->tv_usec > 1000000)
231        {
232                int nsec = (x->tv_usec - y->tv_usec) / 1000000;
233                y->tv_usec += 1000000 * nsec;
234                y->tv_sec -= nsec;
235        }
236
237        /* Compute the time remaining to wait.
238           tv_usec is certainly positive. */
239        result->tv_sec = x->tv_sec - y->tv_sec;
240        result->tv_usec = x->tv_usec - y->tv_usec;
241
242        /* Return 1 if result is negative. */
243        return x->tv_sec < y->tv_sec;
244}
245#define UNIT_ADDR_LEN 20
246#define HW_ADDR_BYTES 5
247static unsigned char s_unit_addr_str[UNIT_ADDR_LEN];
248static unsigned char s_hw_addr_str[HW_ADDR_BYTES];
249
250static const unsigned char crc8_table[] = 
251{
252          0, 155, 173,  54, 193,  90, 108, 247,  25, 130, 180,  47, 216,  67, 117, 238,
253         50, 169, 159,   4, 243, 104,  94, 197,  43, 176, 134,  29, 234, 113,  71, 220,
254        100, 255, 201,  82, 165,  62,   8, 147, 125, 230, 208,  75, 188,  39,  17, 138,
255         86, 205, 251,  96, 151,  12,  58, 161,  79, 212, 226, 121, 142,  21,  35, 184,
256        200,  83, 101, 254,   9, 146, 164,  63, 209,  74, 124, 231,  16, 139, 189,  38,
257        250,  97,  87, 204,  59, 160, 150,  13, 227, 120,  78, 213,  34, 185, 143,  20,
258        172,  55,   1, 154, 109, 246, 192,  91, 181,  46,  24, 131, 116, 239, 217,  66,
259        158,   5,  51, 168,  95, 196, 242, 105, 135,  28,  42, 177,  70, 221, 235, 112,
260         11, 144, 166,  61, 202,  81, 103, 252,  18, 137, 191,  36, 211,  72, 126, 229,
261         57, 162, 148,  15, 248,  99,  85, 206,  32, 187, 141,  22, 225, 122,  76, 215,
262        111, 244, 194,  89, 174,  53,   3, 152, 118, 237, 219,  64, 183,  44,  26, 129,
263         93, 198, 240, 107, 156,   7,  49, 170,  68, 223, 233, 114, 133,  30,  40, 179,
264        195,  88, 110, 245,   2, 153, 175,  52, 218,  65, 119, 236,  27, 128, 182,  45,
265        241, 106,  92, 199,  48, 171, 157,   6, 232, 115,  69, 222,  41, 178, 132,  31,
266        167,  60,  10, 145, 102, 253, 203,  80, 190,  37,  19, 136, 127, 228, 210,  73,
267        149,  14,  56, 163,  84, 207, 249,  98, 140,  23,  33, 186,  77, 214, 224, 123,
268};
269
270/*
271Summary:
272        Return the mac address. Can return false if chip does not support HW address.
273        An address to an array of at least 6 bytes must be provided.
274*/
275bool get_mac_address(unsigned char *hw_address)
276{
277#if 1 /* Test value from UDTA CCAD spec with Radner stream captures */
278        hw_address[0] = 0x12;
279        hw_address[1] = 0xBE;
280        hw_address[2] = 0x20;
281        hw_address[3] = 0x00;
282        hw_address[4] = 0x1C;
283        hw_address[5] = 0xC3;
284    return true;
285#endif
286}
287
288/*
289Summary:
290        Return the 40 bit hardware address. Can return false if chip does not support HW address.
291        An address to an array of at least 5 bytes must be provided.
292*/
293#define SWAP_INT(x)   ((((unsigned int)x & 0xFF) << 24) |(((unsigned int)x & 0xFF00) << 8) |(((unsigned int)x & 0xFF0000) >> 8) | (((unsigned int)x & 0xFF000000) >> 24))
294bool get_hw_address(unsigned char *hw_address)
295{
296#if 1 /* Test value from UDTA CCAD spec */
297        hw_address[0] = 0xc3;
298        hw_address[1] = 0x1c;
299        hw_address[2] = 0x00;
300        hw_address[3] = 0x20;
301        hw_address[4] = 0xBE;
302
303/* c3:1c:00:20:be */
304#endif
305        return true;
306}
307
308/*
309Summary:
310        Get the current utc time in seconds.
311        Return non-zero on failure.
312*/
313bool s_have_time = false;
314unsigned int s_system_time = 0;
315unsigned int s_system_offset = 0;
316unsigned int s_dst_entry = 0;
317unsigned int s_dst_exit = 0;
318unsigned int s_dst_delta = 0;
319bool get_utc_time(unsigned int *time )
320{
321        b_timeval tv;
322
323        if (!s_have_time)
324                return false;
325
326        GETTIMEOFDAY(&tv);
327
328        *time = s_system_time + (tv.tv_sec - s_system_offset);
329
330        return true;
331}
332
333/*
334Summary:
335        Get the current UTC time, local offset and dst flag.
336        Returns non-zero when it is not possible to determine local time.
337        Currently this function uses XDS local offset over one obtained from the TSIDs
338       
339*/
340bool get_local_time(unsigned int *utc_secs )    /* Current UTC time in seconds adjusted to local time */
341{
342        if (!get_utc_time(utc_secs))
343                return false;
344
345        if ((*utc_secs >= s_dst_entry) && (*utc_secs <= s_dst_exit))
346        {
347                if (s_dst_delta == 0)
348                        *utc_secs += 3600;
349                else
350                        *utc_secs += s_dst_delta * 60;
351        }
352        return true;
353}
354
355/*
356Summary:
357        8-bit CRC value based on  x^^8 + x^^7 + x^^4 + x^^3 + x + 1 polynomial used
358        to calculate CRC on 40-bit hardware address.  Defined in Appendix F of CCAD UDTA
359        specification.
360*/
361
362static unsigned char calc_crc8_ua40(unsigned char *hw_address)
363{
364    unsigned char crc8;
365        int i;
366
367    crc8 = 0xFF;        /* Start with all 1s */
368    for (i = 0; i < HW_ADDR_BYTES; i++) 
369        {
370        crc8 = crc8_table[crc8 ^ *hw_address];
371        hw_address++;
372    }
373    return crc8;
374}
375
376/*
377Summary:
378        Return a null terminated string form of the hw_address (40 bit chip ID)
379       
380*/
381
382char *get_unit_address_str()
383{
384        unsigned int lw,i;
385        unsigned char crc8;
386        unsigned char tmp_hw_addr_str[HW_ADDR_BYTES];
387       
388        get_hw_address(s_hw_addr_str);
389       
390        lw = ((uint32_t)s_hw_addr_str[3] << 24) | ((uint32_t)s_hw_addr_str[2] << 16) | ((uint32_t)s_hw_addr_str[1] << 8) | ((uint32_t)s_hw_addr_str[0]);
391        /* memcpy(&lw,s_hw_addr_str,sizeof(lw)); */
392   
393        bapp_util_memset(s_unit_addr_str,0,UNIT_ADDR_LEN);
394
395    snprintf(s_unit_addr_str,UNIT_ADDR_LEN,"%03d-%010u",s_hw_addr_str[4],lw);
396   
397        /* Add - at dash in the middle of the 10 digit number */
398        s_unit_addr_str[15] = s_unit_addr_str[14];
399        s_unit_addr_str[14] = s_unit_addr_str[13];
400        s_unit_addr_str[13] = s_unit_addr_str[12];
401        s_unit_addr_str[12] = s_unit_addr_str[11];
402        s_unit_addr_str[11] = s_unit_addr_str[10];
403        s_unit_addr_str[10] = s_unit_addr_str[9];
404    s_unit_addr_str[9] = '-';
405
406    /* figure check digits and append */
407    crc8 = 0;
408    if ((s_hw_addr_str[0] == 0) && (s_hw_addr_str[1] == 0) && (s_hw_addr_str[2] == 0) && (s_hw_addr_str[3] == 0) && (s_hw_addr_str[4] == 0)) 
409                crc8 = 0;
410        else
411        {
412                /* Swap order */
413                for (i = 0; i < HW_ADDR_BYTES; i++) 
414                        tmp_hw_addr_str[i] = s_hw_addr_str[4-i];
415        crc8 = calc_crc8_ua40(tmp_hw_addr_str);
416        }
417    snprintf(&s_unit_addr_str[15],5,"-%03d",crc8);
418
419    return s_unit_addr_str;
420}
421
422
423/*
424Summary:
425    Same as text box but with shadow.
426Description:
427    Same as text box but with shadow.
428*/
429#define TEXT_SHADDOW
430int text_box_shadow(bgfx_surf_t *p_surf,       /* bgfx surface */
431             bgfx_font_t *font,                 /* bgfx font */
432            uint16_t x,                         /* x location in pixels */
433            uint16_t y,                         /* y location in pixels */
434            uint16_t width,                     /* width in pixels */
435            uint16_t height,                    /* height in pixels */ 
436            unsigned int *msg,                  /* UNI string */
437            unsigned int msg_len,               /* Number of characters in the msg */
438            bgfx_pixel c_f,                     /* palette index for forground text*/
439            bgfx_pixel c_b,                     /* palette index for background text */
440            int shadow_offset,                 /* offset from xy to place shadow (can be negative) */
441            int line_spacing                    /* number of vertical pixels between lines */
442            )
443{
444#ifdef TEXT_SHADDOW
445    text_box(p_surf,font,x + shadow_offset,y + shadow_offset,width,height,msg,msg_len,c_b,line_spacing);
446#endif
447    text_box(p_surf,font,x,y,width,height,msg,msg_len,c_f,line_spacing);
448    return 0;
449}
450
451
452/**
453Summary:
454        scan the mso string looking for a delimiter
455*/
456
457static int scan_mso_str(char *pMSO, char *pStr, int max_str_len, char *pCmd, int max_cmd_len)
458{
459        int cnt = 0;
460        int acm = 0;
461        char delim;
462        delim = '\0';
463
464        /* Search for | delmited message string */
465        while (pMSO[cnt])
466        {
467                switch (pMSO[cnt])
468                {
469                case '|': delim = pMSO[cnt]; break;
470                default: pStr[acm++] = pMSO[cnt]; break;
471                }
472
473                cnt++;
474
475                if (delim != '\0')
476                        break;
477
478                if (acm >= max_str_len)
479                        return -1;
480        }
481
482        pStr[acm] = 0;
483
484        /* Search for command */
485        acm = 0;
486        delim = '\0';
487        while (pMSO[cnt] != 0)
488        {
489                switch (pMSO[cnt])
490                {
491                case '|'/* Empty command */
492                        delim = pMSO[cnt];
493                        if (acm < 2)
494                        {
495                                pCmd[acm++] = '*';
496                                cnt++;
497                                if (pMSO[cnt] != 0)
498                                {
499                                        pCmd[acm++] = '*';
500                                }
501                        }
502                        else
503                        {
504                                if (pMSO[cnt] == '|')
505                                        cnt++; /* This is a field separator so get rid of it also */
506                        }
507                        break;
508                case '#':
509                case '&':
510                case '*':
511                        pCmd[acm++] = pMSO[cnt]; 
512                        break;
513                default: return -1;
514                }
515                cnt++;
516
517                if (delim != '\0')
518                        break;
519
520                if (acm >= max_cmd_len)
521                        return -1;
522        }
523        pCmd[acm] = 0;
524
525        return cnt;
526}
527
528/**
529Summary:
530        Process the MSO command string and construct the MSO message
531*/
532
533static void process_mso_cmd(char *pMsg, 
534                                                        int max_len,
535                                                        char *pDefMsg,
536                                                        char *pCmd)
537{
538        static char s_tmp_phone_str[MSO_PHONE_LEN+1];
539        switch (pCmd[0])
540        {
541        case '#':
542                snprintf(pMsg,max_len,pDefMsg,s_def_phone_str);
543                break;
544        case '&':
545                break;
546        case '\0':
547        case '*':
548                if (strlen(pMsg) > 0)
549                        strcpy(s_tmp_phone_str,pMsg);
550                else
551                        strcpy(s_tmp_phone_str,s_def_phone_str);
552
553                snprintf(pMsg,max_len,pDefMsg,s_tmp_phone_str);
554                break;
555        }
556}
557
558
559/**
560Summary:
561        parse the mso string looking for a delimiter and return true if successful
562*/
563
564void parse_mso_str(char *pMSO, 
565                                   char *pServiceInterrupted, 
566                                   char *pActivationSupport,
567                                   int max_len)
568{
569        int offset,len,ret;
570        char s_service_interrupted_cmd_str[CMD_LEN+1];
571        char s_activation_support_cmd_str[CMD_LEN+1];
572
573        len = strlen(pMSO);
574        offset = 0;
575        ret = scan_mso_str(&(pMSO[offset]),pServiceInterrupted,max_len,s_service_interrupted_cmd_str,CMD_LEN);
576        if (ret < 0)
577                goto ErrExit;
578        else
579                offset += ret;
580
581        BDBG_MSG(("MSO SI INFO:  %s - %s\n",pServiceInterrupted,s_service_interrupted_cmd_str));
582
583        process_mso_cmd(pServiceInterrupted, max_len, (char*)s_def_service_str, s_service_interrupted_cmd_str);
584
585        ret = scan_mso_str(&(pMSO[offset]),pActivationSupport,max_len,s_activation_support_cmd_str, CMD_LEN);
586        if (ret < 0)
587                goto ErrExit;
588        else
589                offset += ret;
590
591        BDBG_MSG(("MSO SI INFO:  %s - %s\n",pActivationSupport,s_activation_support_cmd_str));
592
593        process_mso_cmd(pActivationSupport, max_len, (char*)s_def_service_str, s_activation_support_cmd_str);
594
595        return;
596
597ErrExit:
598        BDBG_WRN(("Invalid MSO String:  %s\n",pMSO));
599
600        pServiceInterrupted[0] = pActivationSupport[0] = 0;
601        process_mso_cmd(pServiceInterrupted, max_len, (char*)s_def_service_str, s_service_interrupted_cmd_str);
602        process_mso_cmd(pActivationSupport, max_len, (char*)s_def_service_str, s_activation_support_cmd_str);
603
604        return;
605}
606
607#define MAX_TP_ALLOWED  4
608
609static timing_profile_t g_tp[MAX_TP_ALLOWED];
610/**
611Summary:
612    initialize timing structure to use
613
614    true if OK
615    false otherwise
616*/
617bool timing_profile_init(void)
618{
619        memset(g_tp, 0, sizeof(g_tp));
620        return true;
621}
622
623/**
624Summary:
625    uninitialize timing structure used
626
627    true if OK
628    false otherwise
629*/
630bool timing_profile_uninit(void)
631{
632        memset(g_tp, 0, sizeof(g_tp));
633        return true;
634}
635
636/**
637Summary:
638    get timing profile object
639
640    return NULL if all timing profile resources are used
641    pointer to a timing profile resource to use
642*/
643p_timing_profile_t timing_profile_get(char *name)
644{
645    int i, j;
646
647    for (i = 0; i < MAX_TP_ALLOWED; i++) {
648        if (!g_tp[i].in_use) {
649                        j = strlen(name);
650                        if (j > sizeof(g_tp[i].name))
651                                j = sizeof(g_tp[i].name) - 1;
652                        strncpy(g_tp[i].name, name, j);
653                        g_tp[i].min = 0xffffffff;
654                        g_tp[i].in_use = true;
655                        return &g_tp[i];
656                }
657    }
658        return NULL;
659}
660
661/**
662Summary:
663    reset timing profile object
664
665    true if OK
666    false otherwise
667*/
668bool timing_profile_reset(p_timing_profile_t ptp)
669{
670        if (!ptp || !ptp->in_use)
671                return false;
672       
673        memset(ptp, 0, sizeof(*ptp));   
674        ptp->in_use = true;
675        return true;   
676}
677
678/**
679Summary:
680    start timing profile
681
682    true if OK
683    false otherwise
684*/
685bool timing_profile_start(p_timing_profile_t ptp)
686{
687        if (!ptp || !ptp->in_use)
688                return false;
689
690    ptp->cur_ticks = bos_getticks();
691       
692        return true;
693}
694
695/**
696Summary:
697    stop timing profiling
698
699    true if OK
700    false otherwise
701*/
702bool timing_profile_stop(p_timing_profile_t ptp)
703{
704        if (!ptp || !ptp->in_use)
705                return false;
706
707        ptp->cnt++;
708    ptp->diff = bos_getticks() - ptp->cur_ticks;
709        /* TODO wrap */         
710        if (ptp->diff > ptp->max)
711                ptp->max = ptp->diff;
712        if (ptp->diff < ptp->min)
713                ptp->min = ptp->diff;
714        ptp->total += ptp->diff;
715
716        timing_profile_print(ptp);
717        return true;
718}
719
720/**
721Summary:
722    print timing profile information
723
724    true if OK
725    false otherwise
726*/
727bool timing_profile_print(p_timing_profile_t ptp)
728{
729        int cnt;
730
731        if (!ptp || !ptp->in_use)
732                return false;
733
734        cnt = ptp->cnt;
735        if (cnt < 1)
736                cnt = 1;
737        printf("Profiling %s: min=%u, ave=%u, max=%u, last time=%d\n", ptp->name, TICKS_TO_MS(ptp->min), 
738                TICKS_TO_MS(ptp->total/cnt), TICKS_TO_MS(ptp->max), TICKS_TO_MS(ptp->diff));
739        return true;
740}
Note: See TracBrowser for help on using the repository browser.