1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Problem with function pointers AVR simulation

Discussion in 'Embedded' started by aravind, Apr 8, 2008.

  1. aravind

    aravind Guest

    Hi, i'm developing some Menu structures for my LCD. Each menu display
    is associated with a state and each state is associated with a
    handling function. I have created an array functions to handle each
    state and need to call the function depending on the state. When i
    simulate in Avr studio, the control does not jump to the called
    function instead carries on as if FPtr is just another variable. On
    examining the listing file, i find the function pointers do not point
    to the actual location of the function and also on adding watch to the
    function pointer array, avr studio shows that the pointers point to a
    location on SRAM rather than FLASH. I'm new to using pointers, the
    problem could be a silly mistake, please help. Thanks.


    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdbool.h>
    #include <avr/pgmspace.h>
    #include "global.h"
    #include "twi.h"
    #include "timertick.h"
    #include "ks0066u.h"
    #include "uart_com.h"
    #include "spi_comm.h"


    typedef void (*FuncPtr)(void);
    //function pointer
    FuncPtr FPtr;


    #define front 1
    #define rear 2
    #define csub 3
    #define headphone 4

    #define all_reg 7

    #define mux_select 0
    #define gain 1
    #define volume 2
    #define bass 3
    #define mid 4
    #define treble 5
    #define atten_l 6
    #define atten_r 7

    #define gain_max 0x0F
    #define gain_min 0x00

    #define volume_max 0x00
    #define volume_min 0x2F

    #define mute 0x38

    #define atten_max 0x4F
    #define atten_min 0x00
    #define atten_mute 0x78

    #define equ_max 0x0F
    #define equ_min 0x00
    //
    *****************************************************************************
    //***************************Display State
    Definitions*************************
    #define power_dwn_s 0

    #define main_disp_s 1

    #define main_menu_s 2

    #define speak_set_s 3

    #define sourc_set_s 4

    #define front_sel_s 5
    #define rear__sel_s 6
    #define csub__sel_s 7
    #define headp_sel_s 8

    #define volum_set_s 9

    #define mastr_set_s 10
    #define chanl_vol_s 11
    #define front_vol_s 12
    #define rear__vol_s 13
    #define csub__vol_s 14
    #define headp_vol_s 15

    #define gain__set_s 16

    #define gainf_set_s 17
    #define gainr_set_s 18
    #define gainc_set_s 19
    #define gainh_set_s 20

    #define equlz_set_s 21

    #define equf__set_s 22
    #define equfb_set_s 23
    #define equfm_set_s 24
    #define equft_set_s 25

    #define equrb_set_s 26
    #define equrm_set_s 27
    #define equrt_set_s 28

    #define equcb_set_s 29
    #define equcm_set_s 30
    #define equct_set_s 31

    #define equhb_set_s 32
    #define equhm_set_s 33
    #define equht_set_s 34

    #define disp__set_s 35
    #define LCDBL_set_s 36
    #define VUdis_set_s 37

    #define systm_set_s 38
    #define temp__dis_s 39
    #define fansp_set_s 40
    #define fanma_set_s 41
    //
    *****************************************************************************
    //***************************Function
    Definitions******************************

    void cmd_proc(void);
    bool call_bindfunc(void);
    void call_def_func(void);
    //
    *****************************************************************************
    //*******************State Handling Function
    Definitions***********************
    void power_dwn_f(void);
    void main_disp_f(void);
    void main_menu_f(void);
    //
    *****************************************************************************
    //***************************Global Variable
    Declarations**********************
    //***************************Function Pointer
    Declarations*********************
    const FuncPtr dis_handle[] PROGMEM =
    {power_dwn_f,main_disp_f,main_menu_f};
    //********************* Function - Key Binding Table Declarations
    *************
    //const uint8_t power_dwn_bk[] = {0x02,0x03,0xFE};
    //const uint8_t main_disp_bk[] = {0x02,0x03,0x07,0x0B,0x1A,0x1B,0xFE};

    const uint8_t fkeybind[60][60] PROGMEM= {{0x02,0x03,0xFE}, //
    power_dwn_s
    {0x02,0x03,0x07,0x0B,0x1A,0x1B,0xFE}}; //main_disp_s
    //***************************Other Variable
    Declarations***********************
    const uint8_t equ_range[15] =
    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
    0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08};

    const uint8_t def_7439[8] = {0x03,0x00,0x38,0x07,0x07,0x07,0x00,0x00};
    const uint8_t defcsub_7439[8] =
    {0x03,0x00,0x38,0x07,0x07,0x07,0x00,0x00};



    uint8_t front_7439[8],rear_7439[7],csub_7439[7],headp_7439[7];
    uint8_t
    prev_front_7439[8],prev_rear_7439[7],prev_csub_7439[7],prev_headp_7439[7];

    bool noslave;

    unsigned int d_state,pstate,opt_set;

    unsigned int cmd,prev1_cmd,prev2_cmd;
    volatile bool new_cmd;

    //
    *****************************************************************************
    //***************************LCD Display
    Strings*******************************
    const char main_disp1[20] PROGMEM = " APAG2 ";
    const char volume1[20] PROGMEM = " Master Volume: ";

    //
    *****************************************************************************
    //***************************Main
    Entry****************************************

    int main(void)
    {

    char init1[20] = " Initialized..... ";
    // char init2[20] = " Volume up ";
    // char init3[20] = " Volume down ";
    sei();

    systemtick_init();
    lcd_pwminit();
    spisetup();
    spitx(0xAA);

    i2c_init();
    set_7439all(front,(uint8_t*) &def_7439);
    set_7439all(rear,(uint8_t*) &def_7439);
    set_7439all(csub,(uint8_t*) &defcsub_7439);
    set_7439all(headphone,(uint8_t*) &def_7439);

    init_uart0();
    init_uart1();

    // txuchar1('R');
    // txuchar1('e');
    // txuchar1('a');
    // txuchar1('d');
    // txuchar1('y');


    // while(!uart0_ch_rx)
    // {
    // txuchar0(0xAE);
    // txuchar1(0xAE);
    // }
    uart0_ch_rx = false;
    if(!(uart0_ch == 0xDD))
    noslave = false;
    else
    noslave = true;
    txuchar1(noslave);
    lcd_init();
    lcd_write(1,init1);


    d_state = power_dwn_s;

    while(1)
    {
    if(uart0_ch_rx)
    cmd_proc();

    if(new_cmd)
    if(!call_bindfunc())
    call_def_func();
    }

    /* while(1){
    while(!uart0_ch_rx);
    uart0_ch_rx = false;
    if(uart0_ch == 0xCC)
    {
    while(!uart0_ch_rx);
    uart0_ch_rx = false;
    if(uart0_ch == 0x70)
    {
    while(!uart0_ch_rx);
    uart0_ch_rx = false;
    if(uart0_ch == 0x07)
    lcd_write(2,init3);
    else if (uart0_ch == 0x0B)
    lcd_write(2,init2);
    }
    }
    }
    txuchar0(0xEA);*/
    while(1);
    }

    void cmd_proc(void)
    {
    uart0_ch_rx = false;

    if((uart0_ch > 0) && (uart0_ch <=0x2E))
    {
    new_cmd = true;
    cmd = uart0_ch;
    }
    }

    bool call_bindfunc(void)
    {
    unsigned int i,n;
    n = 0;
    for(;;)
    {
    i = pgm_read_byte(&fkeybind[d_state][n]);
    n++;
    if(i == cmd)
    {
    FPtr = (FuncPtr)pgm_read_word(*dis_handle[d_state]);
    return true;
    }else if(i == 0xFE)
    break;
    }
    return false;
    }

    void call_def_func(void)
    {
    int i;
    i =12;
    }

    void main_disp_f(void)
    {
    }
    void main_menu_f(void)
    {
    }
    void power_dwn_f(void)
    {
    }
     
    aravind, Apr 8, 2008
    #1
    1. Advertisements

  2. aravind

    David Brown Guest

    First off, if you want to find out what is going wrong here, write a
    small test program that does nothing except call an example function
    through a function pointer, using the same sort of PROGMEM arrays as
    your real program. That way you can see what is going on, it's easier
    to test on the simulator, and it is much easier for others to figure out
    what your code is supposed to be doing.

    Another tip is to use enumerated types instead of lists of #defines like
    you have done. Stand-alone #defines are fair enough, but if you have a
    collection of related values, an enum is normally a much better choice.
    It makes your program clearer, lets the compiler to a slightly better
    job of checking for silly mistakes (and lets a linter do a much better
    job), and gives more useful values when you are debugging.

    On to your real problem - you declare FPtr to be a pointer to a
    function, then you set its value via a lookup table:

    FPtr = (FuncPtr)pgm_read_word(&dis_handle[d_state]);

    (Note - the "*dis_handle" should be "&dis_handle".)

    All you have done here is found the address of your function from the
    table, and stored it in the global FPtr variable. You haven't called
    the function at all. You do this by simply treating FPtr as a function:

    FPtr();

    FPtr should probably be local to call_bindfunc - there is no need to
    store it globally, and it will let the compiler optimise a little better.

    mvh.,

    David



    <snip>
     
    David Brown, Apr 8, 2008
    #2
    1. Advertisements

  3. aravind

    aravind Guest

    Thanks for the advice, i'll remember that next time when i post.
    I called the function with "FPtr();", and it works now.Thanks
     
    aravind, Apr 8, 2008
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.