Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Keil can't recognize next struct

Hi,

I am currently developing a project using ultrasonic sensor for measuring level. So I was migrating library from development kit to nrf sdk code. I am using Keil uVision to develop the code.

So in my case, there are 2 structs that connected together in the library and 1 is list-of typedef that using those structs. 

This is the first typedef.

//! API function pointer typedefs.
typedef uint8_t	 (*ch_fw_load_func_t)(ch201_device *dev_ptr);
typedef uint8_t	 (*ch_get_config_func_t)(ch201_device *dev_ptr, ch_config_t *config_ptr);
typedef uint8_t	 (*ch_set_config_func_t)(ch201_device  *dev_ptr, ch_config_t *config_ptr);
typedef uint8_t  (*ch_set_mode_func_t)(ch201_device  *dev_ptr, ch_mode_t mode);
typedef uint8_t  (*ch_set_sample_interval_func_t)(ch201_device *dev_ptr, uint16_t sample_interval);
typedef uint8_t	 (*ch_set_num_samples_func_t)(ch201_device  *dev_ptr, uint16_t num_samples);
typedef uint8_t	 (*ch_set_max_range_func_t)(ch201_device  *dev_ptr, uint16_t max_range);
typedef uint8_t	 (*ch_set_static_range_func_t)(ch201_device  *dev_ptr, uint16_t static_range);
typedef uint32_t (*ch_get_range_func_t)(ch201_device  *dev_ptr, ch_range_t range_type);
typedef uint16_t (*ch_get_amplitude_func_t)(ch201_device  *dev_ptr);
typedef uint32_t (*ch_get_frequency_func_t)(ch201_device  *dev_ptr);
typedef uint8_t	 (*ch_get_iq_data_func_t)(ch201_device  *dev_ptr, ch_iq_sample_t *buf_ptr, 
										  uint16_t start_sample, uint16_t num_samples, 
										  ch_io_mode_t io_mode);
typedef uint16_t (*ch_samples_to_mm_func_t)(ch201_device  *dev_ptr, uint16_t num_samples);
typedef uint16_t (*ch_mm_to_samples_func_t)(ch201_device  *dev_ptr, uint16_t num_mm);
typedef uint8_t  (*ch_set_thresholds_func_t)(ch201_device  *dev_ptr, ch_thresholds_t *thresh_ptr);
typedef uint8_t  (*ch_get_thresholds_func_t)(ch201_device  *dev_ptr, ch_thresholds_t *thresh_ptr);

This is the first struct

//! Chirp sensor device structure.
typedef struct ch201_device {	
	ch_mode_t	mode;			
	uint16_t	max_range;		
	uint16_t	static_range;	
	uint16_t 	sample_interval;
	uint16_t 	rtc_cal_result; 
	uint32_t 	op_frequency; 	
	uint16_t 	bandwidth; 		
	uint16_t 	scale_factor; 	
	uint8_t  	i2c_address; 	
	uint8_t  	app_i2c_address;
	uint16_t	i2c_drv_flags;	
	uint16_t 	part_number; 	
	int8_t		oversample;		
	uint8_t  	sensor_connected;
	uint8_t  	io_index; 		
	uint8_t  	i2c_bus_index; 	
	uint16_t 	max_samples; 	
	uint16_t 	num_rx_samples; 
	uint32_t 	rtc_cal_pulse_ms;

	const char	  *fw_version_string;		
	const uint8_t *firmware;				
	const uint8_t *ram_init;				
	void     (*prepare_pulse_timer)(struct ch201_device *dev_ptr);
	void     (*store_pt_result)(struct ch201_device *dev_ptr);
	void     (*store_op_freq)(struct ch201_device *dev_ptr);	
	void     (*store_bandwidth)(struct ch201_device *dev_ptr);	
	void     (*store_scalefactor)(struct ch201_device *dev_ptr);
	uint8_t  (*get_locked_state)(struct ch201_device *dev_ptr);
	uint16_t (*get_fw_ram_init_size)(void);
	uint16_t (*get_fw_ram_init_addr)(void);	
	ch_api_funcs_t api_funcs;
} ch201_device;

This is the second struct

typedef struct {
	ch_fw_load_func_t			fw_load;
	ch_set_mode_func_t			set_mode;
	ch_set_sample_interval_func_t	set_sample_interval;
	ch_set_num_samples_func_t	set_num_samples;
	ch_set_max_range_func_t		set_max_range;
	ch_set_static_range_func_t	set_static_range;
	ch_get_range_func_t			get_range;
	ch_get_amplitude_func_t		get_amplitude;
	ch_get_frequency_func_t		get_frequency;
	ch_get_iq_data_func_t		get_iq_data;
	ch_samples_to_mm_func_t		samples_to_mm;
	ch_mm_to_samples_func_t		mm_to_samples;
	ch_set_thresholds_func_t	set_thresholds;
	ch_get_thresholds_func_t	get_thresholds;
} ch_api_funcs_t;

In keil, I have to put the position for definitions first. But as you can see each part is connected at all. I mean in the list-of-typedef, it is calling each item on the first struct. In the first struct, it is calling several item in second struct.

Do you have any idea to arrange this position or is there any configuration so I don't have to do this allignment? because I thought in OOP, arrangement doesn't matter for definition.

Thanks.

Parents
  • Hi 

    In the case where you have circular dependencies between structs you can use a forward declaration, where you declare the name of the struct first, then you define the second struct which references the first, and then you declare the first struct, which references the second. 

    If you write the following above your typedefs I believe it should work:

    typedef struct ch201_device;
    
    // Typedefs
    
    // First struct
    
    // Second struct

    If it still doesn't work please let me know, and I will fire up Keil and try it out myself Slight smile

    Best regards
    Torbjørn

  • great, it works properly. Anyway, if I have another header file in same folder.

    And I have method that use ch201_device struct, how do I call the struct? sorry for a basic question. Thank you.

    I already put it in header file #include "ch201.h" (file that contains typedef struct ch201_device), but still undefined. Thank you.

  • Hi 

    Since you've used a typedef you can now use your struct as a type (similar to int, char etc). 

    In order to use your struct you typically need to instantiate and initialize it somewhere, like this:

    // Create an instance of the ch201_device struct called my_device
    ch201_device my_device;
    
    // You can also populate the fields of the struct during initialization
    ch201_device my_device = {
        .oversample = 10,
        .fw_version_string = "Version 1"};

    To access the fields just use the . operator:

    my_device.oversample = 12;

    To provide a pointer to the struct you use the & operator. 

    Whenever you want to access the fields of a struct through a pointer rather than directly through the instance you have to use the -> operator instead of the . operator.

    ch201_device *my_device_pointer = &my_device;
    my_device_pointer->oversample = 0;

    For a good understanding of the C programming language I would recommend getting The C Programming Language, by Kernighan and Ritchie, widely considered the gold standard of C books. 

    Best regards
    Torbjørn

  • Hi, thank you for response. Thanks for confirming that, but I mean call it on another header at function declaration.

    I think it is really weird. Hopefully you can double check my ticket here  Can't call struct on another file or call the function in main code 

    Thank you.

  • Hi 

    To access the same variable from multiple files you need to use the extern keyword. 

    To do this you need to declare the variable in a header file, using extern:

    extern ch201_device my_device;

    Then in one of your C files you need to initialize it:

    ch201_device my_device = {..};

    And from now on you can access the variable in any file that includes the header file, and access it directly.

    Best regards
    Torbjørn

Reply
  • Hi 

    To access the same variable from multiple files you need to use the extern keyword. 

    To do this you need to declare the variable in a header file, using extern:

    extern ch201_device my_device;

    Then in one of your C files you need to initialize it:

    ch201_device my_device = {..};

    And from now on you can access the variable in any file that includes the header file, and access it directly.

    Best regards
    Torbjørn

Children
No Data
Related