src/occ_405/cmdh/cmdh_snapshot.c
// Function Specification
//
// Name: cmdh_snapshot_callback
//
// Description: Called from timer every 30seconds to store cimp data into
//              an array of 20 cimp snapshots. Then it triggers the generation
//              of a new snapshot in the g_cmdh_sna
//
// End Function Specification
Function Specification
Name: cmdh_snapshot_callback

Called from timer every 30seconds to store cimp data into
an array of 20 cimp snapshots. Then it triggers the generation
of a new snapshot in the g_cmdh_sna

End Function Specification
Function Specification Name : cmdh_snapshot_callback Called from timer every 30seconds to store cimp data into an array of 20 cimp snapshots . Then it triggers the generation of a new snapshot in the g_cmdh_sna End Function Specification
void cmdh_snapshot_callback(void * arg)
{
    static cmdh_snapshot_cimp_entry_t L_cim_buf[CMDH_CIMP_MAX]; 
    static uint8_t  L_cim_seq_number = 0;       
    static uint32_t L_prev_pwr_accum = 0;       
    static uint32_t L_prev_pwr_update_tag = 0;  
    uint32_t        l_pwr_accum         =
        (uint32_t)AMECSENSOR_PTR(PWRSYS)->accumulator;
    uint32_t        l_pwr_update_tag    = AMECSENSOR_PTR(PWRSYS)->update_tag;
    uint32_t        l_avg_pwr           = 0;
    uint32_t        l_min_pwr           = g_pwr250us_over30sec.min;
    uint32_t        l_max_pwr           = g_pwr250us_over30sec.max;
    uint32_t        l_freq_accum        = g_pwr250us_over30sec.freqaAccum;
    uint32_t        l_freq_cnt          = g_pwr250us_over30sec.count;
    uint16_t        l_avg_freq          = 0;
    cmdh_snapshot_cimp_entry_t  l_cim_buf_temp[CMDH_CIMP_MAX - 1];
    cmdh_snapshot_buffer_t      l_30s_snapshot; 
    memset(&g_pwr250us_over30sec,0,sizeof(g_pwr250us_over30sec));
    if (g_cmdh_snapshot_reset)
    {
        memset(g_cmdh_snapshot_array, 0, sizeof(g_cmdh_snapshot_array));
        g_cmdh_snapshot_cur_id  = 0;
        memset(L_cim_buf,0,sizeof(cmdh_snapshot_buffer_t));
        L_cim_seq_number        = 0;
        L_prev_pwr_accum        = l_pwr_accum;
        L_prev_pwr_update_tag   = l_pwr_update_tag;
        g_cmdh_snapshot_reset   = FALSE;
        g_cmdh_snapshot_cur_index = CMDH_SNAPSHOT_DEFAULT_CUR_INDEX;
    }
    else if (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE() || IS_OCC_STATE_CHARACTERIZATION())
    {
        uint32_t l_pwr_accum_diff =  0;
        uint32_t l_pwr_uptag_diff =  0;
        if(l_pwr_accum >= L_prev_pwr_accum)
        {
            l_pwr_accum_diff =  l_pwr_accum - L_prev_pwr_accum;
        }
        else
        {
            l_pwr_accum_diff = l_pwr_accum + (~L_prev_pwr_accum);
        }
        if(l_pwr_update_tag >= L_prev_pwr_update_tag)
        {
            l_pwr_uptag_diff =  l_pwr_update_tag - L_prev_pwr_update_tag;
        }
        else if(l_pwr_update_tag < L_prev_pwr_update_tag)   
        {
            l_pwr_uptag_diff = l_pwr_update_tag + (~L_prev_pwr_update_tag);
        }
        if(l_pwr_uptag_diff == 0)
        {
            TRAC_INFO("cmdh_snapshot_callback: update tag difference should not be 0. current:%i, previous:%i.",
                     l_pwr_update_tag, L_prev_pwr_update_tag);
            l_avg_pwr = 0;
        }
        else
        {
            l_avg_pwr = l_pwr_accum_diff / l_pwr_uptag_diff;
        }
        if(l_freq_cnt == 0)
        {
            TRAC_INFO("cmdh_snapshot_callback: No frequency data has been accumulated.  Returning 0 for frequency. count:%i.",
                      l_freq_cnt);
            l_avg_freq = 0;
        }
        else
        {
            l_avg_freq = (uint16_t)(l_freq_accum / l_freq_cnt);
        }
        L_prev_pwr_accum = l_pwr_accum;
        L_prev_pwr_update_tag = l_pwr_update_tag;
        memcpy(l_cim_buf_temp, L_cim_buf, sizeof(cmdh_snapshot_cimp_entry_t) * (CMDH_CIMP_MAX - 1));
        L_cim_buf[0].seq_number = L_cim_seq_number;
        memcpy(L_cim_buf[0].avg_dc, &l_avg_pwr,sizeof(L_cim_buf[0].avg_dc));
        memcpy(L_cim_buf[0].min_dc, &l_min_pwr,sizeof(L_cim_buf[0].min_dc));
        memcpy(L_cim_buf[0].max_dc, &l_max_pwr,sizeof(L_cim_buf[0].max_dc));
        memcpy(L_cim_buf[0].avg_cpu_freq, &l_avg_freq,sizeof(L_cim_buf[0].avg_cpu_freq));
        memcpy(&(L_cim_buf[1]), l_cim_buf_temp, sizeof(cmdh_snapshot_cimp_entry_t) * (CMDH_CIMP_MAX - 1));
        memcpy(l_30s_snapshot.cim, L_cim_buf, sizeof(cmdh_snapshot_cimp_entry_t) * CMDH_CIMP_MAX);
        l_30s_snapshot.current_id = g_cmdh_snapshot_cur_id;
        g_cmdh_snapshot_cur_index++;
        if (g_cmdh_snapshot_cur_index > CMDH_SNAPSHOT_MAX_INDEX)
        {
            g_cmdh_snapshot_cur_index = 0;
        }
        memcpy(&(g_cmdh_snapshot_array[g_cmdh_snapshot_cur_index]),&l_30s_snapshot, sizeof(cmdh_snapshot_buffer_t));
        g_cmdh_snapshot_cur_id++;
        L_cim_seq_number ++;
    }
}
void cmdh_snapshot_callback ( void * arg ) { static cmdh_snapshot_cimp_entry_t L_cim_buf [ CMDH_CIMP_MAX ] ; static uint8_t L_cim_seq_number = 0 ; static uint32_t L_prev_pwr_accum = 0 ; static uint32_t L_prev_pwr_update_tag = 0 ; uint32_t l_pwr_accum = ( uint32_t ) AMECSENSOR_PTR ( PWRSYS ) -> accumulator ; uint32_t l_pwr_update_tag = AMECSENSOR_PTR ( PWRSYS ) -> update_tag ; uint32_t l_avg_pwr = 0 ; uint32_t l_min_pwr = g_pwr250us_over30sec . min ; uint32_t l_max_pwr = g_pwr250us_over30sec . max ; uint32_t l_freq_accum = g_pwr250us_over30sec . freqaAccum ; uint32_t l_freq_cnt = g_pwr250us_over30sec . count ; uint16_t l_avg_freq = 0 ; cmdh_snapshot_cimp_entry_t l_cim_buf_temp [ CMDH_CIMP_MAX - 1 ] ; cmdh_snapshot_buffer_t l_30s_snapshot ; memset ( & g_pwr250us_over30sec , 0 , sizeof ( g_pwr250us_over30sec ) ) ; if ( g_cmdh_snapshot_reset ) { memset ( g_cmdh_snapshot_array , 0 , sizeof ( g_cmdh_snapshot_array ) ) ; g_cmdh_snapshot_cur_id = 0 ; memset ( L_cim_buf , 0 , sizeof ( cmdh_snapshot_buffer_t ) ) ; L_cim_seq_number = 0 ; L_prev_pwr_accum = l_pwr_accum ; L_prev_pwr_update_tag = l_pwr_update_tag ; g_cmdh_snapshot_reset = FALSE ; g_cmdh_snapshot_cur_index = CMDH_SNAPSHOT_DEFAULT_CUR_INDEX ; } else if ( IS_OCC_STATE_OBSERVATION ( ) || IS_OCC_STATE_ACTIVE ( ) || IS_OCC_STATE_CHARACTERIZATION ( ) ) { uint32_t l_pwr_accum_diff = 0 ; uint32_t l_pwr_uptag_diff = 0 ; if ( l_pwr_accum >= L_prev_pwr_accum ) { l_pwr_accum_diff = l_pwr_accum - L_prev_pwr_accum ; } else { l_pwr_accum_diff = l_pwr_accum + ( ~ L_prev_pwr_accum ) ; } if ( l_pwr_update_tag >= L_prev_pwr_update_tag ) { l_pwr_uptag_diff = l_pwr_update_tag - L_prev_pwr_update_tag ; } else if ( l_pwr_update_tag < L_prev_pwr_update_tag ) { l_pwr_uptag_diff = l_pwr_update_tag + ( ~ L_prev_pwr_update_tag ) ; } if ( l_pwr_uptag_diff == 0 ) { TRAC_INFO ( " " , l_pwr_update_tag , L_prev_pwr_update_tag ) ; l_avg_pwr = 0 ; } else { l_avg_pwr = l_pwr_accum_diff / l_pwr_uptag_diff ; } if ( l_freq_cnt == 0 ) { TRAC_INFO ( " " , l_freq_cnt ) ; l_avg_freq = 0 ; } else { l_avg_freq = ( uint16_t ) ( l_freq_accum / l_freq_cnt ) ; } L_prev_pwr_accum = l_pwr_accum ; L_prev_pwr_update_tag = l_pwr_update_tag ; memcpy ( l_cim_buf_temp , L_cim_buf , sizeof ( cmdh_snapshot_cimp_entry_t ) * ( CMDH_CIMP_MAX - 1 ) ) ; L_cim_buf [ 0 ] . seq_number = L_cim_seq_number ; memcpy ( L_cim_buf [ 0 ] . avg_dc , & l_avg_pwr , sizeof ( L_cim_buf [ 0 ] . avg_dc ) ) ; memcpy ( L_cim_buf [ 0 ] . min_dc , & l_min_pwr , sizeof ( L_cim_buf [ 0 ] . min_dc ) ) ; memcpy ( L_cim_buf [ 0 ] . max_dc , & l_max_pwr , sizeof ( L_cim_buf [ 0 ] . max_dc ) ) ; memcpy ( L_cim_buf [ 0 ] . avg_cpu_freq , & l_avg_freq , sizeof ( L_cim_buf [ 0 ] . avg_cpu_freq ) ) ; memcpy ( & ( L_cim_buf [ 1 ] ) , l_cim_buf_temp , sizeof ( cmdh_snapshot_cimp_entry_t ) * ( CMDH_CIMP_MAX - 1 ) ) ; memcpy ( l_30s_snapshot . cim , L_cim_buf , sizeof ( cmdh_snapshot_cimp_entry_t ) * CMDH_CIMP_MAX ) ; l_30s_snapshot . current_id = g_cmdh_snapshot_cur_id ; g_cmdh_snapshot_cur_index ++ ; if ( g_cmdh_snapshot_cur_index > CMDH_SNAPSHOT_MAX_INDEX ) { g_cmdh_snapshot_cur_index = 0 ; } memcpy ( & ( g_cmdh_snapshot_array [ g_cmdh_snapshot_cur_index ] ) , & l_30s_snapshot , sizeof ( cmdh_snapshot_buffer_t ) ) ; g_cmdh_snapshot_cur_id ++ ; L_cim_seq_number ++ ; } }
Function Specification
Name: cmdh_snapshot_callback
Function Specification Name : cmdh_snapshot_callback
// Holds the earlier cim data snapshots. // Holds the next cim seq number to be used. // Holds the previous power sensor accumulator // Holds the previous power sensor update tag. // Used to temporarily hold new snapshot data. // Clear data that is calculated every 250us to prep for next callback in 30seconds. // Reset max and min over 30 seconds. // Clear reset flag.  - This should be the only place that clears it. // Calculate the accumulator difference. // Calculate the update tag difference. // accum must have wrapped. // Make sure we don't divide by 0 // This should never happen. // Calculate average power since previous callback. // This should never happen. // Calculate average frequency of all Cores for the whole Node (all OCCs) // Save power sensor accumulator and update tag values for next callback. // Append the new cim buffer entry to the front of the local static array of cim buffers. // Populate the local 30s snapshot buffer before writing it out to the global array.  Reason is // we don't want the buffer data to be read by tmgt cmd while we are filling it. // Copy cim data to snapshot buffer. // Increment current index to signify that we are going to add a new snapshot. // Wrap back to start // Write buffer to the current index in the global array g_cmdh_snapshot_array. // Increment snapshot id. // Increment sequence count.