|
|
View previous topic :: View next topic |
Author |
Message |
ralph79
Joined: 29 Aug 2007 Posts: 87
|
variable corruption... |
Posted: Sun Feb 02, 2020 9:19 am |
|
|
hi to all,
I know that is very strange thing to say but, it must be an variable value corruption...
Lets start: I'm programming in a PIC16F1936 with the CCS v. 5.089.
The program is quite extensive, but I have a problem that I have figured out a couple of weeks debugging and digging, the global variable acquires a value that it is not supposed to.
code: I defined a global variable as:
Code: | unsigned int8 sist_prog_val = 0; |
This variable as only two values: 13 and 0
When i change the value of this variable, I write it to eeprom (write_eeprom(.., ..)) and when the system resets, I go to eeprom and read it again (read_eeprom(...);).
In the code for detecting this issue (I had to find the reason), i put a printf function, so that I can see the value of the variable.
Always, during 12 days, the printf had given the correct value of my variable (13), but somehow, in the middle of 12th day the value of this variable was 168 and after a couple of seconds, the variable has taken the value of 143. Why???? By the way, in the eeprom adress position I have the value of 13 as it is supposed to be.
Should it be better to declare the variable as static to prevent this error ? Or is there any other kind of workaround?
Has any other programmer faced a similar problem? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Feb 02, 2020 9:26 am |
|
|
What variables are in front of it?.
Look in the symbol file.
Is this a global variable?.
You do understand that a 'local' variable will potentially lose it's value
when you are outside the routine that generates it.
The 'odds' are that you are overrunning a buffer. So either accessing
an array just in front of it, and going beyond the declared size for this, or
the same with a text buffer. Remember that a 10 character 'string' needs
11 characters of storage. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Sun Feb 02, 2020 1:12 pm |
|
|
Hi Ttelmah,
Thanks for your feedback, but I think that I couldn't explain myself clearly, I will try to explain a little more (according also to your doubts).
My variable is a global variable, which is declared in the main.h header file. I have other files (.h) that could use this variable. In this case I use this variable only for double checking that my system is correctly configured, it's like a test flag only.
As it is only given the values of 0 (0x00) and the value of 13 (0x0D) an 8bit size variable is enough (normally I use only unsigned). I don't have any other variable with the same name (neither similar). I have some arrays of chars but they are declared much lower in my header file...so I really don't understand.
For ensuring that I didn't have a problem with the printf, I had also in my code insert a condition, that if the value of variable was different than the values it should have (0 / 13), a test led would flash. And all occur at the same time, so it was not a problem of size/text or other ODD... any suggestion? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 02, 2020 2:04 pm |
|
|
Post the section of your .SYM file that contains this special variable.
Post several lines of the file before, and after the variable.
Example:
Quote: | 004 rs232_errors
005 temp
006-019 data
01A my_special_variable
01B-01C value
01D result |
Except, post more lines than that. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Sun Feb 02, 2020 3:39 pm |
|
|
This variable corruption is random. It could occur after a couple of days, or weeks/months. By the way, now I'm trying to double check the integrity of the other variables. But that is not very easy because this one I only use (change only two times) and use in a particular part of the code. The remaining variables are not so easy to check.
Below I send a part of the .sym file. I hope it could help.
Quote: | 004-005 @WRITE_PACKED_MEMORY.P1
004-005 @WRITE_PROGRAM_MEMORY8.P2
004-005 @READ_PACKED_MEMORY.P3
004-005 @READ_PROGRAM_MEMORY8.P4
006-007 @READ_PACKED_MEMORY.P1
006-007 @WRITE_PACKED_MEMORY.P2
020 @INTERRUPT_AREA
021 @INTERRUPT_AREA
022 @INTERRUPT_AREA
023 @INTERRUPT_AREA
024 @INTERRUPT_AREA
025 @INTERRUPT_AREA
026 @INTERRUPT_AREA
027 @INTERRUPT_AREA
028 rs232_errors
029-02C n_total_movements
02D-02E encoder_counter_val
02F-030 encoder_counter_total_val
031-032 Actual_ADC_Value
033-034 Crush_Value_ADC
035-036 pwm_actual_value
037-038 pwm_max_value
039-03A encoder_counter_aux
03B-03C encoder_counter_to_stop
03D-03E time_cl_auto
03F-040 count_time_cl_auto
041-042 count_set_lamp_on_one_minute
043-044 n_total_temp_oper
045-046 val_aux_encoder
047-048 max_adc_value_prog_up
049-04A max_adc_value_prog_var
04B-04C crc_accum
04D-06A rf_rcv_data
06B n_total_codes
06C rf_rcv_pointer
06D valid_rf
06E rf_state
06F count_timer_bt
070 state_bt_push
071 count_bt_push
072 count_timer_led
073 n_chanel
074 count_disable_out1
075 n_times_code_already_eeprom
076 count_lamp_high
077 @SCRATCH
078 @SCRATCH
078 _RETURN_
079 @SCRATCH
07A @SCRATCH
07B count_lamp_piri
07C count_teste_crush
07D count_timer1
07E State_prog
07F @INTERRUPT_AREA
0A0 pos_eeprom
0A1 Motor_State
0A2 Lecture_Interval_ADC_counter
0A3 System_State
0A4 test_encoder_runing
0A5 var_time_flash_lamp
0A6 sist_prog_val //// this is the variable with problem
0A7 pointer_eeprom_adc_vals
0A8 count_n_encoder_back
0A9 count_pointer_encoder_back
0AA count_wait_for_normal_func
0AB count_n_x_flash_wait_for_normal_func
0AC time_between_flash_lamp
0AD state_of_art_mode
0AE count_time_leave_entry2
0AF n_v_after_crush
0B0 time_flash_led_push_button
0B1 n_times_crush_auto_close_value
0B2 motor_running
0B3 ADC_Window_Interval
0B4 crushing_monitoring_strength
0B5 time_test_motor_runing_var
0B6 count_n_time_back_without_close
0B7 strength_increment
0B8 countter_to__stop
0B9 n_bytes_recv
0BA count_programing_new_entry
0BB count_programing_new_entry_aux
0BC pushbutton_entry_saved
0BD lamp_power
0BE var_time_pisca_flashings_system
0BF count_timer4
0C0 count_disable_serial_entry
0C1.0 flag_counterback_val
0C1.1 count_delay_new_order_flag
0C1.2 disable_serial
0C1.3 flag_unpress_bt
0C1.4 disable_output_1
0C1.5 disable_timer
0C1.6 data_rcv_ok
0C1.7 can_stop_motor
0C2 n_codes_in_entry_aux1
0C3 count_delay_for_new_order
0C4 counter_for_data_rf_ok
........................................
........................................
........................................
Project Files:
..\main_file.c [01-fev-20 14:12 CRC=57CA008C]
..\main_file.h [02-fev-20 20:59 CRC=B5569524]
C:\Program Files (x86)\PICC\devices\16F1936.h [19-set-19 14:01 CRC=38E67206]
..\eeprom_funcs_file.h [30-jan-20 16:06 CRC=52A7327F]
..\eeprom_vars_file.h [30-jan-20 16:07 CRC=037AB8EA]
..\radio_frequency_file.h [30-jan-20 13:23 CRC=78B19AC7]
..\adc_file_functions.h [31-jan-20 11:54 CRC=1F82646B]
..\initfunctions_file.h [31-jan-20 14:46 CRC=1E111F79]
..\motor_full_control.h [31-jan-20 11:21 CRC=C55C6EDF]
..\common_mode_functions.h [31-jan-20 14:40 CRC=386DAD7F]
..\interrupt_functions_file.h [29-jan-20 10:40 CRC=A886E852]
..\programming_functions_file.h [30-jan-20 17:50 CRC=24806A33]
..\normal_functions_file.h [31-jan-20 14:42 CRC=699A9D97]
Source signature=F074BBDB
Program memory checksum=0000
Hex file CRC=DC23
Units:
..\main_file (main)
Compiler Settings:
Processor: PIC16F1936
Pointer Size: 16
ADC Range: 0-1023
Opt Level: 9
Short,Int,Long: UNSIGNED: 1,8,16
Float,Double: 32,32
Enhanced 16: Yes
Compile Mode: CCS5
Predefined symbols:
#define __16F1936 1
Output Files:
XREF file: build\default\production\_ext\1472\main_file.xsym
Errors: build\default\production\_ext\1472\main_file.err
Ext Symbols: build\default\production\_ext\1472\main_file.esym
INHX8: build\default\production\_ext\1472\main_file.hex
Symbols: build\default\production\_ext\1472\main_file.sym
List: build\default\production\_ext\1472\main_file.lst
Debug/COFF: build\default\production\_ext\1472\main_file.cof
Project: main_file.ccspjt
Call Tree: build\default\production\_ext\1472\main_file.tre
Statistics: build\default\production\_ext\1472\main_file.STA
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Feb 02, 2020 4:32 pm |
|
|
Some random comments..
Any chance you power up the RF device or motor or other 'high current' device?
Is the power supply BIGGER than required (say X2 , X5 max draw )?
Any chance oddball EMI producing machine nearby? welders, cellphones, lasers,????
Any enabled interrupts occourring at the time of 'oopsy' ??
Just trying to think of oddball, weird stuff that might affect you.
Finding it will probably be a process of elimination, confirming it's NOT 'a,b or c'.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 02, 2020 4:33 pm |
|
|
I notice you're using a large number of global variables. This is not the
preferred method to write a program. I advise you to go to Google and
enter this search string:
Quote: | why not to use global variables in C |
There are many articles explaining the risks involved.
Also, search for this with Google:
Quote: | disadvantages of global variables in c |
1. You should use the "search in files" feature of your IDE (either CCS or
MPLAB) to search for sist_prog_val. Check the places that write
to that variable. Is there any way that it could be written to incorrectly ?
2. Look at the top of your .LST file. How many stack levels is your
program using ? Post it.
3. I have a question. Is the failure in the RAM variable ? Or is it the
eeprom copy of it that is being corrupted ? Because if it's the eeprom
it's possible that after 12 days of running the program, you may have
written to it too many times. The endurance count for the 16F1936 eeprom
is only 100,000 writes. Lets say you wrote to the eeprom once every ten
seconds. That's 360 writes per hour.
360 x 24 hours x 12 days =103,680 and that would use up the life of the
eeprom. Are you doing this ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Feb 03, 2020 1:00 am |
|
|
I notice:
can_stop_motor &
Motor_State
Which suggests that some form of motor control is involved. If so, Jay's
comment on EMI definitely applies.
The commonest _hardware_ cause for variable corruption, is that the
supply is not properly smoothed, or RFI is being picked up on chip pins.
Do you have any pins that are floating?. Any pin that is not driven high/low
and has nothing actually connected to it, is potentially a radio receiver.
I'd suspect that when the motor is being stopped (this is when the worst
EMI problems are generated), some of the power is being dumped back
through the PIC. Post a drawing of the motor control circuit. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Mon Feb 03, 2020 2:55 am |
|
|
Thanks for your feedback...
I have in fact a system with an DC brushed motor and a open frame RF receiver. This code works well in almost all the control boards (couple of hundreds/thousands..) but in some of them the code seems to have hang, and it is necessary to restart the main power supply.
My figure, as writes, could be an EMI problem or something like nested interrupts.
I know that I have several global variables, but almost all my programs are interrupt driven.. the main file works only as an test flag (to do the slowest functions). To give you an idea, in this particular code I have:
-> 3 adc entrys
-> 2 pwm channels @ 40Khz
-> 1 rs232 (sending (printf) and receive (RF) @19200bps
-> 2 external interrupt (int_ext and int_timer0) for double encoder
-> timer1 @ 65.5ms interrupt
-> timer4 @ 8.1ms interrupt
-> timer6 @ 1ms interrupt (only some testing flags and changing the values for the main file)
About the ram/rom usage: (the code without printfs has only 76% of ROM occupied)
CCS PCM C Compiler, Version 5.089
ROM used: 7937 words (97%)
Largest free fragment is 190
RAM used: 147 (29%) at main() level
172 (34%) worst case
Stack used: 7 locations (6 in main + 1 for interrupts)
Stack size: 16
About the name of variable, I always, for not having the name problems, I use the copy and paste method when writing the code. In the past I have a problem with some compiler (IAR, XC8, and others) that misunderstood some name variables (specially with Caps...).
The problem is in fact with the RAM variable. I write to the EEPROM only when is really need (in this case, at most, in all control board lifetime about 20 times, at most). Reading the EEPROM, I read it only when I reboot the system. So I'm very, very far away of the eeprom cycling endurance. But the problem is really in the RAM variable that somehow changes the value without having code to do that (I'm monitoring every time "I" change the code).
The motor control is made by a full bridge mosfet control driven by an HIP4082. So it's an basic control. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Feb 03, 2020 3:05 am |
|
|
The key with any chip like this, is what actually takes the 'spare' energy, when the motor stops?.
The chip itself dumps this into it's supply.
It is absolutely vital, that this supply has sufficient reservoir capacitance
and clamping to prevent over-voltage when this happens.
Presume the PIC is running off it's own regulated supply separate from the
motor supply?. Are there any routes by which noise on the motor supply
can get into the PIC supply?. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Mon Feb 03, 2020 3:20 am |
|
|
The micro has an dedicated power supply (based in a 78M05 with capacitors in entry and in the output of it), has also 3 capacitors (10pF, 10nF and 1uF) near the VCC/Ground pins for correct decoupling of the micro.
Regarding the routes, the most problematic ones are some of the adc_inputs (current measure) and the encoder entries. In this case I have a Schmitt Trigger for better accuracy of the encoder.
How I can tell to the compiler to not fall in these errors? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Feb 03, 2020 3:50 am |
|
|
You mention ADC.
What speed are you clocking your CPU at?.
The chip has an erratum that can result in ADC conversions hanging.
This is a real 'nasty', and may be causing problems.
Static has no effect on a global variable, except to ensure it is initialised.
Try moving the variable to a different memory location. Simply add an extra unused variable in front of it's declaration. Will prove it is not a specific
memory cell causing the issue.
Do you use arrays or pointers anywhere?. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Mon Feb 03, 2020 4:14 am |
|
|
The CPU is @ 32MHz (maximum internal speed).
The ADC is configured something like this:
Code: | setup_adc_ports(adc_current_m1|adc_current_m2 |time_func_t1|VSS_VDD); // set adc input, voltage reference
setup_adc(ADC_CLOCK_DIV_32); |
So i think it should be OK. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Feb 03, 2020 4:22 am |
|
|
No it won't.
As I said, this is a major problem with the chip. You need:
Code: |
setup_oscillator(OSC_8MHZ);
val = read_adc();
setup_oscillator(OSC_32MHz);
|
wherever you read the ADC. You might as well set the ADC to run faster
as well.
The problem is if the CPU is running about 8MHz, it can fail to set the
flag that the ADC conversion has completed. Pretty much at random....
It's a real nasty on this chip and gives random hangs. |
|
|
ralph79
Joined: 29 Aug 2007 Posts: 87
|
|
Posted: Mon Feb 03, 2020 6:15 am |
|
|
Ttelmah,
Your suggestion (I think) could produce more hangs.
I say this, because as my code is continuously reading the ADC inputs, changing the speed of the internal oscillator (and eventually waiting for the correct settling of the oscillator) could cause several hangs (don't forget that I have several interrupts source.
By the way for your information (i didn't said in the last post) I don't use pointers in this particular code, and I have only two global arrays of chars declared as follows:
Code: |
unsigned int8 rf_rcv_data[11] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned int8 rf_rcv_data[5] = {0x00,0x00,0x00,0x00,0x00};
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|