- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
While debugging my program, I found that the pointers gets lost and could not trace the current statement when halted. Disassembly opens and points to one of the sub routine. Note that I have I2C sensors connected. They gave output as follows at the USBUART:
"Temp = 26580 Humidity = 35596 UV = 1 LW = 65533 IR = 65535
HDR Address 64 Temperature = 00046,0223124215, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, MPPT A = 40 B = 35 C = 38 D = 36 Pmax A = 88 B = 86 C = 85 D = 29 Temp = 26584 Humidity = 35468 UV = 0 LW = 65534 IR = 0
HDR Address 64 Temperature = 00046,0223124225, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, MPPT A = 49 B = 35 C ="
But all of the sudden, it program window opens to Disassembly and I could not see the program pointer. Though I can run and halt but nothing happens.
"
673:
674: if((atoi(hour)> 7) && (atoi(hour)<19) && (RTC_1_ReadMinute() != (u_short)atoi(min)))
0x0000172E add r0, sp, #54 ; 0x54
0x00001730 bl d6a0 <atoi>
0x00001734 cmp r0, #7
0x00001736 ble.n 1790 <CYDEV_DMA_SRAM16K_MSIZE+0x790>
0x00001738 add r0, sp, #54 ; 0x54
0x0000173A bl d6a0 <atoi>
0x0000173E cmp r0, #12
0x00001740 bgt.n 1790 <CYDEV_DMA_SRAM16K_MSIZE+0x790>
0x00001742 bl 464c <RTC_1_ReadMinute>
0x00001746 mov r5, r0
0x00001748 add r0, sp, #58 ; 0x58
0x0000174A bl d6a0 <atoi>
0x0000174E uxth r0, r0
0x00001750 cmp r5, r0
0x00001752 beq.n 1790 <CYDEV_DMA_SRAM16K_MSIZE+0x790>
675: {
676: RTC_1_WriteMinute((u_short)atoi(min));
0x00001754 add r0, sp, #58 ; 0x58
0x00001756 bl d6a0 <atoi>
0x0000175A uxtb r0, r0
0x0000175C bl 4604 <RTC_1_WriteMinute>
677: UART_1_PutString("Minutes updated\n");
0x00001760 ldr r0, [pc, #1cc] ; (1930 <CYDEV_DMA_SRAM16K_MSIZE+0x930>)
0x00001762 bl 4d54 <UART_1_PutString>
678: EEPROM_1_UpdateTemperature();
0x00001766 bl 5090 <EEPROM_1_UpdateTemperature>
679: EEPROM_1_Write2Byte((u_short)atoi(date)*100+(u_short)atoi(hour),SYNC_ADDRESS);
0x0000176A add r0, sp, #5c ; 0x5c
0x0000176C bl d6a0 <atoi>
0x00001770 mov r5, r0
"
Output window log:
"
Device 'PSoC 5LP CY8C5868AXI-LP035' was successfully programmed at 02/24/2020 18:01:18.
Continuing target program
The target program has stopped at: file: main.c line: 904 function: main address: 0x00001BF8
Continuing target program
The target program has stopped at: file: main.c line: 1056 function: main address: 0x00002018
Continuing target program
The target program has stopped at: file: main.c line: 674 function: MyRxInt address: 0x0000172E
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
Continuing target program
The target program has stopped at: file: line: -1 function: USBUART_TABLE address: 0x0003EF74
"
Please find the attachment containing my project.
Appreciate any assistance.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo, Len,
The problem was with the strcat. After using the first sprintf(disp,"S%.5u,", index) ; resolved the global variable issue. We can safely say that the root cause of the problem was the sprintf in ISR. After moving them to main.c and changing %f to %d resolved the stack overflow issue.
But I wonder why %f fails when the length of the sprintf is more i.e. 100+ bytes even after increasing the heap size to even 0x2000. Main issue is certainly now with the stack or heap size but the %f function itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi SAJO_1338106,
When I build the project I am getting an error stating that some files are missing as shown -
I was unable to find FS.h in the archive shared.
Can you please re-attach the project?
Thanks and Regards,
Rakshith M B
Rakshith M B
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rakshith,
Just follow the instruction given in the datasheet of the emfile component
to generate FS.h.
When using the GCC toolchain, you must specify the directory where the
library file is located.
The steps to create the emFile project for PSoC 5LP application using GCC
toolchain are as
follows:
1. Decide which library you need. This decision is based on whether you
need FAT12/16 or
FAT32, whether your application uses an OS, and whether you need long file
name
support. This example uses emf32nosnlfn.lib (FAT32, no OS, and no long file
name
support).
2. Select the necessary include file directory. Go to Project > Build
Settings > ARM GCC
4.8.4 > Compiler > General. Click the “…” button in the Additional Include
Directories
property field. The Additional Include Directories dialog will display.
Click the New
button and select an include directory for PSoC 5 and an include directory
for the specific
options you want.
Note If want to run the project in both “Debug” and “Release”
configurations you need to
add the Include Directories for both configurations.
3. Go to Project > Build Settings > ARM GCC 4.8.4 > Linker > General >
Additional
Library Directories. Click the “…” button in the Additional Library
Directories property
field.
The Additional Library Directories dialog will display.
4. Click the New button and select the library directory for the GCC
library.
Adding Library Directory
5. Specify the library in the library directory.
a. Go to Project > Build Settings > ARM GCC 4.8.4 > Linker > General >
Additional
Libraries.
b. Type in the library name without prefix "lib" and suffix ".a" (for
example,
"libemf32nosnlfn.a" would be "emf32nosnlfn"). This is because GCC
compiler will automatically add the “lib” prefix to the library name.
Note If want to run the project in both “Debug” and “Release”
configurations you need to
add the Link library for both configurations.
6. If usage of OS or logging feature is desired then FS_ConfigIO.c or FS_X_OS.c
files
should be added to the project. Details on OS integration and logging
feature usage can
be found in the emFile User Guide in Chapters 8 and 9 respectively.
The mentioned files can be added directly into your project from the
Code/Source/PSoC5
directory or copied first to your project directory and added from there.
The files will
usually be edited, so you need to decide whether to change the original
files or a copy
that is specific to the project.
The files are added to the project using Project > Existing Item.
Add <FS.h> header file in your main.c function.
ᐧ
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SAJO,
I was finally able to get your project to compile. I'm having difficulties getting your program to run since I don't have the right CPU or the same peripherals.
However, I noticed the following:
- Flash used: 259928 of 262144 bytes (99.2 %). SRAM used: 54441 of 65536 bytes (83.1 %). Stack: 4096 bytes. Heap: 512 bytes.
Wow! This is a VERY FULL program. You're using 99.2% of FLASH and 83.1% of SRAM. Suggestion: Can you reduce your SRAM requirements and increase your Stack and your heap? You might be running out of stack or heap. - I noticed you have 6 ISRs. I also noticed you are performing a lot of processing in some of them including CyDelay()s. I hope you don't mind a recommendation from someone with years of experience in embedded design. I learned LONG AGO (30+ years) from a mentor, always write your interrupt code small and tight. If you spend too much time in the interrupt, you might lose the next interrupt. Always get the data or signal that caused the interrupt and signal back to the task level (main.c in your case) that the signal occurred or the data is now stored in a buffer.
Having said that: Here's a tool to use in the debugger. Sometimes it can be a big help when the code "goes off in the weeds".
When you stop the debugger (manually or using a breakpoint) notice the "Call Stack" tab. It should indicate the levels of stack at the stop point up to main().
Once I re-targetted your project to the Device being used for the CY8CKIT-059 board, I got your project running-ish. Since I don't have your peripherals it is limited.
What are you using to communicate (HMI) with the application? UART_1 or USBUART? I'd say it was UART_1 since you have a UART_1_GetChar(). It does look like you are using USBUART as a output.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Len,
Advice well taken.
Stack overflow could be the reason. I am storing the results in flash so it is almost full.
I2C devices are required to run the code. I am using ESP for wireless communication and downloading the results through UART and USB for debugging purpose. Program would run without USB.
I will decrease the ISR task and re code it in main.c and let you know the results.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Reading your main.c, I felt a little bit uneasy about sprintfs.
By any chance, can you replace all
sprintf(disp,
with
snprintf(disp, 150,
and try if it still caused problem?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
Any specific reason to use snprintf instead of sprintf? I have ensured that the total bytes never exceeds 132 bytes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, SaJo-san,
At first I was afraid that there could be a case the total exceeds 150.
So it may not help at all.
Following are idea(s) off my head... (so may not be quite convincing)
Before I had an experience with smaller device (PSoC 4)
when the number of arguments exceeded 5 or 6 sprintf caused malfunction of the application.
(The length of buffer was enough.)
So, I also may try to reduce the length of disp[] and make more sprintf and UART_1_PutString couples.
(This also release some sram but may consume more flash)
and/or I would create and try an onion skin function something like
============
#define TIMEOUT_LIMIT 5000
my_print(char *str)
{
uint16_t timeout_count = 0 ;
UART_1_PutString(str) ;
while(UART_1_GetTxBufferSize()) {
timeout_count++ ;
if (timeout_count > TIMEMOUT_LIMIT) {
break ;
}
CyDelayUs(1) ;
}
}
============
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HI Moto,
Yes, this will reduce the SRAM(16% RAM is still available to handle these)
but I think that the issue could be something else because the debugger is
clueless about the current operating statement. Debugger suppose to have
the track recorder of what are the previous states. Strange that the
debugger is of no help in this scenario. Anyway, I am rewriting code as Len
suggested and share my results.
ᐧ
On Tue, Feb 25, 2020 at 10:38 AM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Sajo-san,
I'm sorry for missing the point.
I hope you will be successful with the rewrite.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SAJO,
As moto pointed out snprintf() is preferred over sprintf() because it is considered safer by ANSI C. The 'n' in snprintf() prevents accidentally overwriting beyond the allocated string size thus preventing corrupting RAM.
It's great that you're counting the size of the string. I have on too many occasions just slapped together a sprintf() without counting and found I didn't allocate a large enough string. Then I wondered why my code went off into the weeds or some variable was nowhere close to what it is suppose to be.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Len,
Keeping that issue in mind, I had kept extra 20 bytes. Till now, the maximum length was 118 bytes.
Hi Moto,
Glad that you brought this new function snprintf.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Len, Moto,
It is been one and half days on the debugger and still running with the following changes.
- I cut short the ISR of RX and moved the task to main.c
- Set the master clock to 24 MHz
- Stack: 8192 bytes. Heap: 4096 bytes
No issues till now except some UART send receive functionality delay which needs to be worked out with ESP. However, I am still surprised to encounter same issue when the master clock is set to 48 MHz. Am I still missing something here? Is it because of GPIO limitation? Is there any other alternatives to CyDelay which Len mentioned that I am using so many times which could cause an issue? Kindly advise.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
I just reopened your original project and played with the DWR > Clocks
To support USB, the device has very accurate 24MHz IMO +/- 0.25%
But if I changed it to 48MHz the accuracy is now +/- 5% which is about the limit of UART to work correctly
and also if you are using USB, the accuracy is not acceptable.
I wonder if you use IMO 24MHz and use PLL to make it 48MHz, will it make it work better?
Best Regards,
27-Feb-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
Setting was exactly similar. I increased the PLL to 48 MHz and USB to IMOx2. Program pointer gets last after a couple of main program execution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
> Setting was exactly similar. I increased the PLL to 48 MHz and USB to IMOx2.
> Program pointer gets last after a couple of main program execution.
Oh, you've done it.
Another thing I would try is to divide the Bus Clock by 2 = 24Mhz, but still keep Master Clock 48MHz
In advance, if this does not help, I'm sorry.
Best Regards,
27-Feb-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
Is the XTAL 32kHz clock generated from the IMO? I also have a crystal oscillator of 32kHz in my PCB. Let me know. I will try your suggestion now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
IMO can be generated from XTAL but I'm afraid that it can not be generated from XTAL 32kHz.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
Your suggestion is working fine now. I reduced the bus frequency to 24 MHz and rest to 48 MHz. I will keep it running for some more time and let you know if I encounter any issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Len, Moto,
I encountered the same issue now.
Program counter
0x00000000 <RomVectors>:
40: Disassembly of section .text:
0x00000000 ... ....9B..9B..
0x00000010 <Reset>:
55: * This function handles the reset interrupt for the GCC toolchain. This is the
56: * first bit of code that is executed at startup.
57: *
58: *******************************************************************************/
59: void Reset(void)
60: {
0x00000010 push {r3, lr}
69: #endif /* (CYDEV_DEBUGGING_ENABLE) */
70: /* Reset Status Register has Read-to-clear SW access mode.
71: * Preserve current RESET_SR0 state to make it available for next reading.
72: */
73: *(reg32 *)(CYREG_PHUB_CFGMEM23_CFG1) = *(reg32 *)(CYREG_RESET_SR0);
0x00000012 ldr r3, [pc, #10] ; (24 <CYDEV_CHIP_REVISION_4G_ES2+0x3>)
0x00000014 ldr r2, [r3, #0]
0x00000016 add.w r3, r3, #2fc0 ; 0x2fc0
0x0000001A adds r3, #2
0x0000001C str r2, [r3, #0]
82: #if ((CYDEV_BOOTLOADER_ENABLE) && (CYDEV_PROJ_TYPE != CYDEV_PROJ_TYPE_LOADABLEANDBOOTLOADER))
83: CyBtldr_CheckLaunch();
84: #endif /* ((CYDEV_BOOTLOADER_ENABLE) && (CYDEV_PROJ_TYPE != CYDEV_PROJ_TYPE_LOADABLEANDBOOTLOADER)) */
85: Start_c();
0x0000001E bl 4278 <Start_c>
0x00000022 nop
0x00000024 .word 0x400046fa
0x00000028 <__do_global_dtors_aux>:
0x00000028 push {r4, lr}
0x0000002A ldr r4, [pc, #14] ; (40 <CY_METADATA_SIZE>)
0x0000002C ldrb r3, [r4, #0]
0x0000002E cbnz r3, 3e <CYDEV_MFGCFG_ANAIF_SIZE+0x6>
0x00000030 ldr r3, [pc, #10] ; (44 <CY_METADATA_SIZE+0x4>)
0x00000032 cbz r3, 3a <CYDEV_MFGCFG_ANAIF_SIZE+0x2>
0x00000034 ldr r0, [pc, #10] ; (48 <CY_METADATA_SIZE+0x8>)
0x00000036 nop.w
0x0000003A movs r3, #1
0x0000003C strb r3, [r4, #0]
0x0000003E pop {r4, pc}
0x00000040 .word 0x1fff8370
0x00000044 .word 0x00000000
0x00000048 .word 0x0000fd2c
Call stack log
0 appl1_start() ?????? ?????? 0x00000000 (All)
1 <signal handler called>() ?????? ?????? 0xFFFFFFF1 (All)
2 appl1_start() ?????? ?????? 0x00000000 (All)
3 <signal handler called>() ?????? ?????? 0xFFFFFFF9 (All)
4 __lshift() ?????? ?????? 0x0000F672 (All)
5 ??() ?????? ?????? 0x00000000 (All)
Register status
r0=,0xF8000000,r1=,0x201EDC34,r2=,0xFFFFFFFF,r3=,0x201EDC54,r4=,0x00000000,
r5=,0x4B04B509,r6=,0x4B04B508,r7=,0x1FFF82D0,r8=,0x00000020,r9=,0x0000001B,
r10=,0x201EDC50,r11=,0xFFFFFFFE,r12=,0x00000005,sp=,0x20007B30,lr=,0xFFFFFFF1,
pc=,0x00000000,xpsr=,0xA0000003,msp=,0x20007B30,psp=,0x00000000,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SAJO,
From your last email it is evident that your code 'train' "went off the tracks". Sadly, the Call stack log does not indicate where the last call to valid code was made.
Debugging is going to be a bit more complicated.
Just before the code crashes, is there anything specific that is happening? For example: user input, user output?
There are MANY reasons why code can crash. Stack over runs. Out of bounds array processing. Nested interrupts, overly-recursive functions. Just to name a few.
Does your program always crash to the same place (ie: void Reset(void))?
Although it would be great to use the debugger, it appears not to be of help YET. It would be great if the call stack had a valid location. This would be effectively the last place the code was 'sane'. If this valid location was consistently the last sanity point, you could inspect/review the code executed before it. Additionally, you could put a breakpoint in the code immediate following the last sanity point. With that you might be able to inspect the variables passed to see what might have happened.
Another debugging tip is to leave 'breadcrumbs'. You can place external signals in your code to read these signals using a scope. For example, you are using a I2C device. With this, you can see every time I2C is occurring. If you put thoughtfully placed calls to GPIO pin(s) to toggle at certain points this might be helpful. If there is a consistent pattern, you might find where in the sequence of signals the breakdown occurs.
The goal of the 'signal' strategy above is to try to reduce the places in your code where the problem may be. If this is effective, then you can more quickly found the root cause.
Question: Are you enabling the Watchdog?
I hope this helps. I've found that these moments where the issue is complex to solve helped to build my trouble-shooting skills which in itself is a valuable skill. The lessons learned from a successful root cause analysis in turn became improvements to my design skills.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
I'm a little bit slow and was not reading everything carefully,
and I just noticed the following line.
> and USB for debugging purpose. Program would run without USB.
If this is the case, can you replace USBUART with another UART, such as UART_2 ?
As you know, USB takes up a lot of memory and CPU power, just replacing USBUART
with a simple UART and connect a USB-Serial converter something like below
may make the situation better.
UMFT234XF FTDI, Future Technology Devices International Ltd | 集積回路(IC) | DigiKey
Best Regards,
27-Feb-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo, Len,
I increased the stack size and heap size (Stack -16384 bytes. Heap: 4096 bytes.) and did not connect USB(hence USBUART component was not running). Though I faced the same situation of hanging in the disassembly, I was able to record the stack call as follows:
0 __lshift() ?????? ?????? 0x0000F628 (All)
1 _dtoa_r() ?????? ?????? 0x0000EF58 (All)
2 __cvt() ?????? ?????? 0x0000DBD6 (All)
3 _printf_float() ?????? ?????? 0x0000DD9E (All)
4 _svfprintf_r() ?????? ?????? 0x0000FC00 (All)
5 sprintf() ?????? ?????? 0x0000E49C (All)
6 display_content(uint8 index = <optimized out>, uint8 mode = 0 '\000', uint8 mode@entry = 0 '\000') main.c 356 0x00000BC0 (All)
7 TimerInt4() main.c 570 0x000014BA (All)
8 <signal handler called>() ?????? ?????? 0xFFFFFFF9 (All)
9 CyDelayCycles_loop() Generated_Source\PSoC5/CyBootAsmGnu.s 48 0x000099F8 (All)
10 CyDelay(uint32 milliseconds = 10, uint32 milliseconds@entry = 10) Generated_Source\PSoC5\CyLib.c 1471 0x00004550 (All)
11 main() main.c 1169 0x0000268C (All)
Assembly code and the current point location is in bold.
0x0000F60C <__lshift>:
0x0000F60C stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
0x0000F610 mov r4, r1
0x0000F612 mov r7, r0
0x0000F614 mov r9, r2
0x0000F616 ldr r6, [r4, #10]
0x0000F618 mov.w sl, r2, asr #5
0x0000F61C add r6, sl
0x0000F61E ldr r1, [r1, #4]
0x0000F620 ldr r3, [r4, #8]
0x0000F622 adds r5, r6, #1
0x0000F624 cmp r3, r5
0x0000F626 bge.n f62e <__lshift+0x22>
0x0000F628 adds r1, #1
0x0000F62A lsls r3, r3, #1
0x0000F62C b.n f624 <__lshift+0x18>
0x0000F62E mov r0, r7
0x0000F630 bl f294 <_Balloc>
0x0000F634 movs r3, #0
0x0000F636 mov r8, r0
0x0000F638 mov r2, r3
0x0000F63A add.w r1, r0, #14
0x0000F63E cmp r3, sl
0x0000F640 bge.n f64a <__lshift+0x3e>
0x0000F642 str.w r2, [r1, r3, lsl #2]
0x0000F646 adds r3, #1
0x0000F648 b.n f63e <__lshift+0x32>
0x0000F64A bic.w r3, sl, sl, asr #1f
0x0000F64E ldr r0, [r4, #10]
0x0000F650 add.w r3, r1, r3, lsl #2
0x0000F654 ands.w r9, r9, #1f
0x0000F658 add.w r1, r4, #14
0x0000F65C add.w lr, r1, r0, lsl #2
0x0000F660 beq.n f68c <__lshift+0x80>
0x0000F662 rsb ip, r9, #20
0x0000F666 movs r2, #0
0x0000F668 ldr r0, [r1, #0]
0x0000F66A mov sl, r3
0x0000F66C lsl.w r0, r0, r9
0x0000F670 orrs r2, r0
0x0000F672 str.w r2, [r3], #4
0x0000F676 ldr.w r2, [r1], #4
0x0000F67A cmp lr, r1
0x0000F67C lsr.w r2, r2, ip
0x0000F680 bhi.n f668 <__lshift+0x5c>
0x0000F682 str.w r2, [sl, #4]
0x0000F686 cbz r2, f69a <__lshift+0x8e>
0x0000F688 adds r5, r6, #2
0x0000F68A b.n f69a <__lshift+0x8e>
0x0000F68C subs r3, #4
0x0000F68E ldr.w r2, [r1], #4
0x0000F692 cmp lr, r1
0x0000F694 str.w r2, [r3, #4]!
0x0000F698 bhi.n f68e <__lshift+0x82>
0x0000F69A subs r5, #1
0x0000F69C mov r0, r7
0x0000F69E str.w r5, [r8, #10]
0x0000F6A2 mov r1, r4
0x0000F6A4 bl f2fe <_Bfree>
0x0000F6A8 mov r0, r8
0x0000F6AA ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
Problem seems to be with float printing I guess.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
That printf is called from an ISR, TimerInt4.
IMHO, using printf/sprintf inside an ISR is not a safe operation.
By any chance can you only set a flag in the TimerInt4 and
print (call the display_content()) outside of the ISR?
Best Regards,
10-Mar-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
I have removed timer 4. The subroutine under timer 4 is moved to main.c. I will post the results soon. Hope that this might resolve the issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
Still the problem remains but current program pointer going at the beginning of the main function. Still do not understand what is going wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After moving the timer subroutine to main.c, I got the same call stack trace.
0 appl1_start() ?????? ?????? 0x00000000 (All)
1 <signal handler called>() ?????? ?????? 0xFFFFFFF1 (All)
2 appl1_start() ?????? ?????? 0x00000000 (All)
3 <signal handler called>() ?????? ?????? 0xFFFFFFF9 (All)
4 __lshift() ?????? ?????? 0x0000F48C (All)
5 _dtoa_r() ?????? ?????? 0x0000ED68 (All)
6 __cvt() ?????? ?????? 0x0000D9E6 (All)
7 _printf_float() ?????? ?????? 0x0000DBAE (All)
8 _svfprintf_r() ?????? ?????? 0x0000FA10 (All)
9 sprintf() ?????? ?????? 0x0000E2AC (All)
10 display_content(uint8 index = <optimized out>, uint8 mode = 0 '\000', uint8 mode@entry = 0 '\000') main.c 355 0x00000BC8 (All)
11 main() main.c 1380 0x00002C18 (All)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
From the stack trace, what I can say are
(1) display_content(index=?, mode=0) was called at main.c line 1380
(2) sprintf() was called from display_content
(3) _svprintf() was called from sprintf()
(4) _print_float() was called from _svprintf()
...
So the first exception happened in the _print_float(),
which means one of the "%f" triggered the exception.
Since the "mode" was 0 following line was called
============
len = sprintf(disp,"\r%u %.5u,%ld,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%2.2f,%2.2f,%d,%d,%d\n",sizeof(flash_dump), index,flash_dump.day_seq,(float32)flash_dump.I1,(float32)flash_dump.V1/1000,(float32)flash_dump.I1*flash_dump.V1/1000,(float32)flash_dump.I1,(float32)flash_dump.V1/1000,(float32)flash_dump.I2*flash_dump.V2/1000,(float32)flash_dump.I3,(float32)flash_dump.V3/1000,(float32)flash_dump.I3*flash_dump.V3/1000,(float32)flash_dump.I4,(float32)flash_dump.V4/1000,(float32)flash_dump.I4*flash_dump.V4/1000,(float32)flash_dump.Vbat/1000,temperature,humidity,flash_dump.U_V,flash_dump.LW,flash_dump.MIR);
============
To test the behaviour of this line, I created a test project and copied variable definitions and display_content()
(I used CY8CKIT-059).
The output was
And something was wrong here, as you have 21 arguments in the sprintf's format
1: sizeof(flash_dump),
2: index,
3: flash_dump.day_seq,
4: (float32)flash_dump.I1,
5: (float32)flash_dump.V1/1000,
6: (float32)flash_dump.I1*flash_dump.V1/1000,
7: (float32)flash_dump.I1,
8: (float32)flash_dump.V1/1000,
9: (float32)flash_dump.I2*flash_dump.V2/1000,
10: (float32)flash_dump.I3,
11: (float32)flash_dump.V3/1000,
12: (float32)flash_dump.I3*flash_dump.V3/1000,
13: (float32)flash_dump.I4,
14: (float32)flash_dump.V4/1000,
15: (float32)flash_dump.I4*flash_dump.V4/1000,
16: (float32)flash_dump.Vbat/1000,
17: temperature,
18: humidity,
19: flash_dump.U_V,
20: flash_dump.LW,
21: flash_dump.MIR
But the last argument correctly written was
No.16 : (float32)flash_dump.Vbat/1000,
and
No.17: temperature,
was only written as "-"
Then I noticed that I have not enlarged the heap size so it was 0x80
and I enlarged it to 0x200, then data was printed correctly.
So in your application's case, you have already set the heap size as 0x200,
but may be you need to enlarge it more.
Meantime, if you have time and patience, please refer to my old memo
printf and float rhapsody (aka, yet another printf and floating topic)
In general, I'd rather avoid using "%f" and use "%d.%02d" trick in the above memo.
And if you will still have the same problem, how about temporary rewriting the display_content() just like
==================
uint8 display_content(uint8 index, uint8 mode)
{
uint8 len;
char buf[32] ;
if(mode)
{
temperature = (temp[index]*0.0025177001953125 - 40); humidity = humid[index]*0.00152587890625;
len = sprintf(disp,"%.5u,%.2u%.2u%.2u%.2u%.2u,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%5.2f,%2.2f,%2.2f,%d,%d,%d\n",index,timestamp.Month,timestamp.DayOfMonth,timestamp.Hour,timestamp.Min,timestamp.Sec,(float32)I1[ index],(float32)V1[ index]/1000,(float32)I1[ index]*V1[ index]/1000,(float32)I2[ index],(float32)V2[ index]/1000,(float32)I2[ index]*V2[ index]/1000,(float32)I3[ index],(float32)V3[ index]/1000,(float32)I3[ index]*V3[ index]/1000,(float32)I4[ index],(float32)V4[ index]/1000,(float32)I4[index]*V4[ index]/1000,(float32)Vbat[index]/1000,temperature,humidity,U_V[index],LW[index],MIR[index]);
}
else
{
// temperature = flash_dump.temp*0.0025177001953125 - 40;
temperature = ((float32)flash_dump.temp)*0.0025177001953125 - 40.0;
humidity = flash_dump.humid*0.00152587890625;
sprintf(disp, "\r%u ", sizeof(flash_dump)) ; /* No. 1 */
snprintf(buf, 32, "%.5u, ", index) ; /* No.2 */
strcat(disp, buf) ;
snprintf(buf, 32, "%ld, ",flash_dump.day_seq) ; /* No.3 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I1) ; /* No.4 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.V1/1000) ; /* No. 5 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I1*flash_dump.V1/1000) ; /* No.6 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I1) ; /* No.7 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.V1/1000) ; /* No.8 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I2*flash_dump.V2/1000) ; /* No.9 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I3) ; /* No.10 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.V3/1000) ; /* No.11 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I3*flash_dump.V3/1000) ; /* No.12 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I4) ; /* No.13 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.V4/1000) ; /* No.14 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f,",(float32)flash_dump.I4*flash_dump.V4/1000) ; /* No.15 */
strcat(disp, buf) ;
snprintf(buf, 32, "%5.2f, ",(float32)flash_dump.Vbat/1000) ; /* No.16 */
strcat(disp, buf) ;
snprintf(buf, 32, "%2.2f,",temperature) ; /* No.17 */
strcat(disp, buf) ;
snprintf(buf, 32, "%2.2f,",humidity) ; /* No.18 */
strcat(disp, buf) ;
snprintf(buf, 32, "%d,",flash_dump.U_V) ; /* No.19 */
strcat(disp, buf) ;
snprintf(buf, 32, "%d,",flash_dump.LW) ; /* No.20 */
strcat(disp, buf) ;
snprintf(buf, 32, "%d\n",flash_dump.MIR) ; /* No.21 */
strcat(disp, buf) ;
len = strlen(disp) ;
/*
len = sprintf(disp,
"\r%u // 1
%.5u, // 2
%ld, // 3
%5.2f, // 4
%5.2f, // 5
%5.2f, // 6
%5.2f, // 7
%5.2f, // 8
%5.2f, // 9
%5.2f, // 10
%5.2f, // 11
%5.2f, // 12
%5.2f, // 13
%5.2f, // 14
%5.2f, // 15
%5.2f, // 16
%2.2f, // 17
%2.2f, // 18
%d, // 19
%d, // 20
%d\n", // 21
sizeof(flash_dump), // 1
index, // 2
flash_dump.day_seq, // 3
(float32)flash_dump.I1, // 4
(float32)flash_dump.V1/1000, // 5
(float32)flash_dump.I1*flash_dump.V1/1000, // 6
(float32)flash_dump.I1, // 7 (I2?)
(float32)flash_dump.V1/1000, // 8 (V2?)
(float32)flash_dump.I2*flash_dump.V2/1000, // 9
(float32)flash_dump.I3, // 10
(float32)flash_dump.V3/1000, // 11
(float32)flash_dump.I3*flash_dump.V3/1000, // 12
(float32)flash_dump.I4, // 13
(float32)flash_dump.V4/1000, // 14
(float32)flash_dump.I4*flash_dump.V4/1000, // 15
(float32)flash_dump.Vbat/1000, // 16
temperature, // 17
humidity, // 18
flash_dump.U_V, // 19
flash_dump.LW, // 20
flash_dump.MIR); // 21
*/
}
return len;
}
==================
With this you can tell exactly which line is causing the problem.
Best Regards,
11-Mar-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
Wow. That's a lot of work I gave you. Appreciate your help. Sorry for making it complicated. I am trying the strcat now and I have increased the heap size to 0x1000. Just to understand the issue better, I will run my code with the new heap size, with %d and then with series of strcat. Sharing the results soon.
I am with strcat and the call trace is similar to previous.
0 appl1_start() ?????? ?????? 0x00000000 (All)
1 <signal handler called>() ?????? ?????? 0xFFFFFFF1 (All)
2 appl1_start() ?????? ?????? 0x00000000 (All)
3 <signal handler called>() ?????? ?????? 0xFFFFFFF9 (All)
4 __lshift() ?????? ?????? 0x0000FF90 (All)
5 _dtoa_r() ?????? ?????? 0x0000F880 (All)
6 __cvt() ?????? ?????? 0x0000E47E (All)
7 _printf_float() ?????? ?????? 0x0000E646 (All)
8 _svfprintf_r() ?????? ?????? 0x00010528 (All)
9 snprintf() ?????? ?????? 0x0000ED56 (All)
10 main() main.c 1650 0x0000344C (All)
1650 snprintf(buf, 32, "%5.2f,",(float32)V3[index]/1000) ; /* No.11 */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
After replacing the %f with %d, I was getting garbage values for the global variable. After moving them to the main.c, issue is not seen. But still unable to resolve the original problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
> After replacing the %f with %d, I was getting garbage values for the global variable.
If this is happening in the "ISR", the global values must be defined as "volatile" to be accessed correctly. But I don't suggest you to use any print or memory handling function in it.
> After moving them to the main.c, issue is not seen.
This means the print statements are working OK, right?
> But still unable to resolve the original problem.
Does this mean you still get error in the debugger?
Is the error "exact" the same with the first question you post?
Or similar but showing something else?
Best Regards,
13-Mar-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
BTW,
> I am trying the strcat now and I have increased the heap size to 0x1000.
0x1000 for the heap may be too much, how about tryint to reduce it to 0x800 ~ 0x500?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
I am now testing with the %d and no issues till now. I will post the
results by the end of the day.
ᐧ
On Fri, Mar 13, 2020 at 12:23 PM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo, Len,
The problem was with the strcat. After using the first sprintf(disp,"S%.5u,", index) ; resolved the global variable issue. We can safely say that the root cause of the problem was the sprintf in ISR. After moving them to main.c and changing %f to %d resolved the stack overflow issue.
But I wonder why %f fails when the length of the sprintf is more i.e. 100+ bytes even after increasing the heap size to even 0x2000. Main issue is certainly now with the stack or heap size but the %f function itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Sajo-san,
Thank you for the good news!
To be honest I'm not believing in "%f", so that I usually I use "%d" instead.
Best Regards,
16-Mar-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SAJO,
I'm glad you've identified the issue.
%f processing in sprintf() does take more stack because it is making calls to the SW floating point library.
Len
"Engineering is an Art. The Art of Compromise."