📄 sink.c
字号:
/*************************************************************************** sink.c - RTLinux kernel module for an empty module ------------------- begin : 2002 authors : Linus Gasser emails : linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** Changes ------- date - name - description 02-09-19 - ineiti- begin 02-10-22 - daniela - enhace to count u8 03/05/26 - ineiti - added complex-input 04/03/06 - ineiti - adjusted description **************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//** * Works as a display of what has been received. There are different inputs * to deserve different sources: * input 0: U8 * input 1: SYMBOL_COMPLEX * input 2: DOUBLE * input 3: DOUBLE_COMPLEX * Just by connecting to the appropriate port, you will activate the display * of this given port. * Additionaly one can set the 'size' in small chains where no module has * given any size yet. */#include "spc.h"#define DBG_LVL 0#define BUF_SIZE 2048typedef struct { // Gives the input-port size int size; // 0 // 0 - no output, 1 - wrstr, 2 - count occurences, 3 - output hex int flag; // 0 // 0 - no output, 1 - write complex symbols int flag_complex; // 0 // 0 - no output, 1 - write doubles, 8 in a line int flag_double; // 0 // 0 - no output, 1 - write double_complexess, 8 in a line int flag_double_complex; // 0}config_t;typedef struct { // The total bytes/symbols/double/complex doubles received int tot_in;}stats_t;typedef struct { char buf[BUF_SIZE];}private_t;/** * The initialisation part that is only called the first time this module * is instantiated. */int spc_init( swr_sdb_t *context ) { stats_t *stats; config_t *config; MOD_INC_USE_COUNT; if ( sizeof( private_t ) > 0 ) context->private_data = swr_malloc( sizeof( private_t ) ); swr_sdb_get_config_struct( context->id, (void**)&config ); swr_sdb_get_stats_struct( context->id, (void**)&stats ); config->size = 0; config->flag = 0; config->flag_complex = 0; config->flag_double = 0; config->flag_double_complex = 0; stats->tot_in = 0; swr_sdb_free_stats_struct( context->id, (void**)&stats ); swr_sdb_free_config_struct( context->id, (void**)&config ); return 0;}/** * Every time somebody from the outside changes a configuration value, * this function is called just before the working-function */int spc_reconfig( swr_sdb_t *context ) { config_t *config; swr_sdb_get_config_struct( context->id, (void**)&config ); if ( config->size > 0 ) { size_in(3) = size_in(2) = size_in(1) = size_in(0) = config->size; } swr_sdb_free_config_struct( context->id, (void**)&config ); return 0;}/** * The actual working function */int spc_pdata( swr_sdb_t *context ) { stats_t *stats; config_t *config; int flag, flag_complex, flag_double, flag_double_complex, len; U8 *data; SYMBOL_COMPLEX *data_complex; double *data_double; double_complex *data_double_complex; char *str; int vect[256], n; swr_sdb_get_config_struct( context->id, (void**)&config ); flag = config->flag; flag_complex = config->flag_complex; flag_double = config->flag_double; flag_double_complex = config->flag_double_complex; swr_sdb_free_config_struct( context->id, (void**)&config ); if ( data_available(0) ) { // Process the u8-input data = buffer_in( 0 ); switch ( flag ) { case 0: //PR_DBG( 4, "Received some data...\n" ); break; case 1: // Print the received string. str = swr_malloc( size_in(0) + 1 ); memcpy( str, data, size_in(0) ); str[ size_in(0) ] = 0; PR_DBG( 0, "Got %i bytes: %s\n", size_in(0), str ); swr_free( str ); break; case 2: // Counts the occurence of a given integer between 0...2^8-1. memset(vect, 0, 256*sizeof(int)); for ( n=0; n<size_in(0); n++) { vect[data[n]]++; } for (n=0; n< 256; n++) { PR_DBG( 0, "P(%3i..%3i) * 256 = { ", n, n+15 ); for ( ;(n+1)%16; n++ ) { PR_DBG_CL( 0, "%1.2f ", vect[n]/(double)size_in(0) * 256 ); } PR_DBG_CL( 0, "}\n" ); } break; case 3: // Writes the hexadecimal values for ( n=1; n<=size_in(0); n++ ) { if ( !( (n-1) % 16 ) ) { PR_DBG( 0, "%04x: ", n - 1 ); } PR_DBG_CL( 0, "%02x ", data[n-1] ); if ( !(n % 8) && (n % 16) ) { PR_DBG_CL( 0, "- " ); } else if ( !(n % 16) ) { PR_DBG_CL( 0, "\n" ); } } if ( size_in(0) % 16 ) { PR_DBG_CL( 0, "\n" ); } break; } len = min( size_in(0), BUF_SIZE ); memcpy( private->buf, port_in(0).data, len ); } if ( data_available(1) ) { // Process the complex input PR_DBG( 1, "Data on complex: %i symbols. Flag is %i\n", size_in(1), flag_complex ); data_complex = buffer_in(1); switch( flag_complex ) { case 1: for ( n=0; n<size_in(1); n++ ) { PR_DBG( 0, "(%5i, %5i)\n", data_complex[n].real, data_complex[n].imag ); } break; } } if ( data_available(2) ) { // Process the complex input PR_DBG( 1, "Data on double: %i. Flag is %i\n", size_in(2), flag_double ); data_double = buffer_in(2); switch( flag_double ) { case 1: for ( n=0; n<size_in(2); n++ ) { if ( !( n % 8 ) ) { if ( n ) { PR_DBG_CL( 0, "\n" ); } PR_DBG( 0, "Double [%i..%i]: ", n, min( n+8, size_in(2) ) - 1 ); } PR_DBG_CL( 0, "%g ", data_double[n] ); } if ( n % 8 ) { PR_DBG_CL( 0, "\n" ); } break; } } if ( data_available(3) ) { // Process the complex input PR_DBG( 1, "Data on double_complex: %i. Flag is %i\n", size_in(3), flag_double_complex ); data_double_complex = buffer_in(3); switch( flag_double_complex ) { case 1: for ( n=0; n<size_in(3); n++ ) { if ( !( n % 4 ) ) { if ( n ) { PR_DBG_CL( 0, "\n" ); } PR_DBG( 0, "Double_Complex [%i..%i]: ", n, min( n+4, size_in(2) ) - 1 ); } PR_DBG_CL( 0, "(%g,%g) ", data_double_complex[n].real, data_double_complex[n].imag ); } if ( (n+1) % 4 ) { PR_DBG_CL( 0, "\n" ); } break; } } swr_sdb_get_stats_struct( context->id, (void**)&stats ); stats->tot_in += size_in(0); swr_sdb_free_stats_struct( context->id, (void**)&stats ); return 0;}int spc_finalize( swr_sdb_t *context ) { if ( sizeof( private_t ) > 0 ) swr_free( private ); MOD_DEC_USE_COUNT; return 0;}swr_spc_id_t spc_id;/** * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */int spc_module_init(void) { swr_spc_desc_t *desc; // Get a description-part from SPM // Nbr_input_ports, Nbr_output_ports, Nbr_config_values, Nbr_stats_values desc = swr_spc_get_new_desc( 4, 0, 5, 1 ); if ( !desc ) { PR_DBG( 0, "Can't initialise the module. This is bad!\n" ); return -1; } // Define the different parts of config, stats and io-ports UM_STATS_INT( "tot_in" ); UM_CONFIG_INT( "size", PARAMETER_DEBUG ); UM_CONFIG_INT( "flag", PARAMETER_DEBUG ); UM_CONFIG_INT( "flag_complex", PARAMETER_DEBUG ); UM_CONFIG_INT( "flag_double", PARAMETER_DEBUG ); UM_CONFIG_INT( "flag_double_complex", PARAMETER_DEBUG ); UM_INPUT( SIG_U8, 0 ); UM_INPUT( SIG_SYMBOL_COMPLEX, 0 ); UM_INPUT( SIG_DOUBLE, 0 ); UM_INPUT( SIG_DOUBLE_COMPLEX, 0 ); // Initialise the callback-functions. NULL for not-used functions desc->fn_init = spc_init; desc->fn_reconfigure = spc_reconfig; desc->fn_process_data = spc_pdata; desc->fn_custom_msg = NULL; desc->fn_finalize = spc_finalize; // And register the module in the SPM spc_id = swr_cdb_register_spc( &desc, "sink" ); if ( spc_id == SWR_SPM_INVALID_ID ) { swr_spc_free_desc( desc ); PR_DBG( 0, "Couldn't register the module!\n" ); return 1; } PR_DBG( 2, "\"sink\" is ready to destroy your data\n" ); return 0;}void spc_module_exit( void ) { PR_DBG( 2, "Sink is saying goodbye\n" ); if ( swr_cdb_unregister_spc( spc_id ) < 0 ) { PR_DBG( 0, "Still in use somewhere\n" ); }}module_init( spc_module_init );module_exit( spc_module_exit );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -