Author Topic: Why dont my pointer works ?  (Read 5465 times)

0 Members and 1 Guest are viewing this topic.

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Why dont my pointer works ?
« on: November 18, 2018, 02:01:37 pm »
Hi, i am trying this with XC32 for PIC32MX170F256B :

Code: [Select]
unsigned char screen[ 64 ][ 16 ];

unsigned long long * lcdptr;
unsigned long long * lcdptrPlus127;

// init
lcdptr = ( unsigned long long * )screen;
lcdptrPlus127 = lcdptr + 127;

// ckear function

// clear screen
*(lcdptr++) = 0;

// this part dont works :
if( lcdptr == lcdptrPlus127 )stop clear function.


Problem : the clear function wont stop.
Ofcourse i can add a counter, i would like to use the pointer as counter.

thanks
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Why dont my pointer works ?
« Reply #1 on: November 18, 2018, 02:38:38 pm »
Could you post your actual code? Also, alignment is important on MIPS CPUs. There is no guarantee that your char array will be to allow it to be accessed as anything but chars. As a sidenote, it's be really difficult to out-perform memset, which has the added bonus of being correct.

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Why dont my pointer works ?
« Reply #2 on: November 18, 2018, 02:47:01 pm »
I'd use a counter to make sure. Also a pointer to a long (typically 32 bit) will be incremented by 4 bytes. Besides that try to use types (line uint32_t, in8_t, etc) from std_int.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #3 on: November 18, 2018, 03:01:14 pm »
Could you post your actual code? Also, alignment is important on MIPS CPUs. There is no guarantee that your char array will be to allow it to be accessed as anything but chars. As a sidenote, it's be really difficult to out-perform memset, which has the added bonus of being correct.

So the whole screen is not a solid piece of memory ?
I thought from the first byte to last is all aligned behind eachother,
i am keeping to in the memory range, to 127, instead of going over the memory range ( 128 ), something with pages or something could happen i imagined.

For the memset :
I am trying to spread out the function for in background rendering in main loop, dont stop the main loop for rendering functions since it is writing the backbuffer to screen.
Anyways : this will be faster then memset i think, i can run some tests again for this PIC32, i,m almost sure already.

btw : for clearing the screen is no problem, only the pointer.
Clearing the screen with a counter still works the same, here it only wont stop the function.

I'd use a counter to make sure. Also a pointer to a long (typically 32 bit) will be incremented by 4 bytes. Besides that try to use types (line uint32_t, in8_t, etc) from std_int.

Here its unsigned long long, increments of 8 bytes.
« Last Edit: November 18, 2018, 03:04:09 pm by Jan Audio »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Why dont my pointer works ?
« Reply #4 on: November 18, 2018, 03:23:24 pm »
So the whole screen is not a solid piece of memory ?
That's not what I said at all. If the first byte of the array is not allocated on an address evenly divisible by 4, your program will crash.

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #5 on: November 18, 2018, 03:31:34 pm »
Ooh, thanks.
Now its getting more complicated with things i dont see in C language.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Why dont my pointer works ?
« Reply #6 on: November 18, 2018, 03:44:07 pm »
Agree with the above request to post the whole code (or at least the relevant parts, more than you've posted above).

You also have an off-by-one (or off by 8 bytes). The code above, once made to be correct, will never clear the last 8 bytes of the screen array.

You might also consider switching to just a 32 bit type. I doubt the PIC is more efficient at clearing 64 bits at a time, and it might even be slower/higher overhead to do so.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11882
  • Country: us
Re: Why dont my pointer works ?
« Reply #7 on: November 18, 2018, 03:49:33 pm »
So the whole screen is not a solid piece of memory ?
I thought from the first byte to last is all aligned behind eachother,
i am keeping to in the memory range, to 127, instead of going over the memory range ( 128 ), something with pages or something could happen i imagined.

If you add 127 to a long long pointer, it will increment it by 127 long longs, i.e. 127*8 = 1016 bytes. If you were hoping to advance the pointer by 127 bytes it will not do that.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Why dont my pointer works ?
« Reply #8 on: November 18, 2018, 03:59:28 pm »
So the whole screen is not a solid piece of memory ?
I thought from the first byte to last is all aligned behind eachother,
i am keeping to in the memory range, to 127, instead of going over the memory range ( 128 ), something with pages or something could happen i imagined.

If you add 127 to a long long pointer, it will increment it by 127 long longs, i.e. 127*8 = 1016 bytes. If you were hoping to advance the pointer by 127 bytes it will not do that.
That part is right (though off-by-one in the last test). Screen is a 64x16 char array, which is 1024 bytes in memory.
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: Why dont my pointer works ?
« Reply #9 on: November 18, 2018, 04:04:36 pm »
Try:
Code: [Select]
union {
   unsigned long long lcd[ 128 ]; // will be 8-byte aligned by default now
   unsigned char screen[ 64 ][ 16 ]; // by itself, might not have been aligned nicely
}

unsigned long long * lcdptr;
unsigned long long * lcdptrPlus127;

// init
lcdptr = lcd;
lcdptrPlus127 = &lcd[127]; 

...
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #10 on: November 18, 2018, 04:04:52 pm »
Here is the code :
Code: [Select]
//------------------------------------------------------------------------------
// y , x * 8 ( 128 x 64 display swapping backbuffer )
//------------------------------------------------------------------------------
struct ScreenBuffer
{
unsigned char data[ 64 ][ 16 ];
};

//------------------------------------------------------------------------------
struct ScreenBuffer*pScreen;
struct ScreenBuffer*pInternalScreen;
struct ScreenBuffer screen1,screen2;

//------------------------------------------------------------------------------
// clear graphical display backbuffer
//------------------------------------------------------------------------------
#define ClearScreen( screen ) lcdtemp = 0; \
lcdptr = ( unsigned long long * )screen; \
do{ *(lcdptr++) = 0; }while( lcdtemp++ != 127 );


void ( *HandleRender )();


// init
pScreen = &screen1;
pInternalScreen = &screen2;

// set pointer for clear
lcdptr = ( unsigned long long * )pScreen->data;
lcdptrPlus127 = lcdptr + 127;

HandleRender = Clear;

//------------------------------------------------------------------------------
// Clear
//------------------------------------------------------------------------------
void Clear()
{
*(lcdptr++) = 0;
*(lcdptr++) = 0;
*(lcdptr++) = 0;
*(lcdptr) = 0;

if( lcdptr++ == lcdptrPlus127 )
  HandleRender = PaintLine;
}


Now let me read the comments, thnx.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #11 on: November 18, 2018, 04:05:30 pm »
Thanks Nusa i tryd that, wont work.
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Why dont my pointer works ?
« Reply #12 on: November 18, 2018, 04:19:27 pm »
Slight rewrite:
Code: [Select]
void Clear()
{
  *lcdptr = 0;
  lcdptr += 1;
  *lcdptr = 0;
  lcdptr += 1;
  *lcdptr = 0;
  lcdptr += 1;
  *lcdptr = 0;

  if (lcdptr == lcdptrPlus127)
    HandleRender = PaintLine;
  lcdptr += 1;
}
Do you see the problem there? Or, altenatively
Code: [Select]
void Clear()
{
  lcdptr[0] = 0;
  lcdptr[1] = 0;
  lcdptr[2] = 0;
  lcdptr[3] = 0;
  lcdptr += 3;

  if (lcdptr == lcdptrPlus127)
    HandleRender = PaintLine;
  lcdptr += 1;
These two forms are functionally equivalent to the code you posted, and they all have the same problem.

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #13 on: November 18, 2018, 04:21:20 pm »
Yes all the same.
Should work right ?,
Maybe i can use a union with unsigned long longs at same memory ?
« Last Edit: November 18, 2018, 04:27:48 pm by Jan Audio »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Why dont my pointer works ?
« Reply #14 on: November 18, 2018, 05:03:46 pm »
Should work right ?,
No. Simulate the code on paper if you can't figure it out.

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #15 on: November 18, 2018, 05:23:58 pm »
Why dont you tell me the problem please ?
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Why dont my pointer works ?
« Reply #16 on: November 18, 2018, 05:37:41 pm »
I'm trying to be educational.

Just to prove an earlier point, here's what you get with memset, compiled with -O1. Still sure you can do better?
Code: [Select]
#include <string.h>
#include <stdint.h>

typedef void(*renderfunc)(void);
extern renderfunc pFun;
void otherfunc(void);

extern union {
    uint8_t b[1024];
    uint32_t i[256];
} a;
extern int loop_index;

void clear(void)
{
    memset(&a.i[loop_index], 0, 32);
    loop_index += 8;

    if (loop_index == 256)
        pFun = otherfunc;
}
Code: [Select]
00000000 <clear>:
   0: 8f830000 lw v1,0(gp)
   4: 00032080 sll a0,v1,0x2
   8: 3c020000 lui v0,0x0
   c: 24420000 addiu v0,v0,0
  10: 00441021 addu v0,v0,a0
  14: ac400000 sw zero,0(v0)
  18: ac400004 sw zero,4(v0)
  1c: ac400008 sw zero,8(v0)
  20: ac40000c sw zero,12(v0)
  24: ac400010 sw zero,16(v0)
  28: ac400014 sw zero,20(v0)
  2c: ac400018 sw zero,24(v0)
  30: ac40001c sw zero,28(v0)
  34: 24620008 addiu v0,v1,8
  38: 24030100 li v1,256
  3c: 14430004 bne v0,v1,50 <clear+0x50>
  40: af820000 sw v0,0(gp)
  44: 3c020000 lui v0,0x0
  48: 24420000 addiu v0,v0,0
  4c: af820000 sw v0,0(gp)
  50: 03e00008 jr ra
  54: 00000000 nop

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #17 on: November 18, 2018, 05:43:54 pm »
Did you compare it with the unsigned long long filling ?
What would be the solution to my problem without memset ?, dont you have that ?

Set timer output on display, then also for the memset,
i dont know about instructions.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: Why dont my pointer works ?
« Reply #18 on: November 18, 2018, 07:03:50 pm »
Code: [Select]
#include "Osc.hpp"
#include "Uart.hpp"
#include "Cp0.hpp"
#include <cstdio>
#include <cstdint>
#include <cstring> //memset

uint8_t screen[ 64 ][ 16 ];

// clear screen
//screen must be multiple of 128bytes
void cls(){
    uint64_t* p = (uint64_t*)screen;
    for(uint32_t i = sizeof(screen); i; i-=128){
        *p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes
        *p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes
        *p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes
        *p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes
    }
}

//tx only
Uart info { Uart::UART2TX, Pins::C6, 230400 };
//so I can use printf with 'info' as the output
extern "C" void _mon_putc(char c){ info.putchar(c); }

int main()
{
    Osc osc;
    osc.pll_set ( osc.MUL12, osc.DIV4 );
    info.on ( true );

    printf( "\n\n&screen: 0x%04X\n", (uint32_t)screen );
    uint32_t t1 = Cp0::count();
    cls();
    uint32_t t2 = Cp0::count();;
    memset(screen, 0, sizeof(screen));
    uint32_t t3 = Cp0::count();
    printf( "cls: %d  memset: %d\n", t2-t1, t3-t2 );

    for(;;);
}
/*

&screen: 0x8000004C
cls: 154  memset: 212

*/

It also looks to me that xc32 will always align an array on 4bytes. If you create some vars as bytes, the addresses will of course only be byte aligned, but the minute you create a byte array of 1 or more,
it seems to always be 4byte aligned. I don't know the rules, but that is what seems to happen. I tried to get 'screen' unaligned, but could not.

Quote
I am trying to spread out the function for in background rendering in main loop, dont stop the main loop for rendering functions since it is writing the backbuffer to screen.
If you want screen buffer cleared while doing something else, use DMA.
« Last Edit: November 18, 2018, 07:11:26 pm by cv007 »
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: Why dont my pointer works ?
« Reply #19 on: November 18, 2018, 08:56:22 pm »
You ClearScreen() looks reasonably correct, but I think you must have other code here. If I have to guess, you are being clever using RenderHandler to first to set to Clear, and you would call it a number of times, and then when it clears the whole buffer, you set RenderHandler to some other "real" drawing routine.

Without seeing your other code, we have no other what else you are doing. My advice is that it could be something simple, but generally, it looks a bit too "clever for clever" sake. Just have a ClearScreen() macro/function that you call to clear the whole screen, then another function to draw.

Basically, pointers work, and if you code doesn't, there is something you do not understand, and it's hard to guess what it is.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Why dont my pointer works ?
« Reply #20 on: November 18, 2018, 11:12:18 pm »
It looks like you are trying to incrementally clean the buffer, four words at a time.

Are you sure that your pointer is aligned as you expect at the start?

Otherwise you need to test to see if you are at the end of the buffer more often.

Code: [Select]
void Clear()
{
  int i;
  for(i = 0; i < 4; i++) {
    *lcdptr = 0;
    if (lcdptr == lcdptrPlus127) {
      HandleRender = PaintLine;
      return;
    }
    lcdptr++;
  }
}

It seems to be doing a very small amount of work to do each time though....
« Last Edit: November 18, 2018, 11:14:00 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #21 on: November 19, 2018, 02:01:07 pm »
If you want screen buffer cleared while doing something else, use DMA.

Thanks, here i am intrested.
So i can use DMA for anything not only peripherals ?, nice.
I need to generate some DMA code in MCC then,
could i do my update routine also in another DMA ?, that would be even better.

Just have a ClearScreen() macro/function that you call to clear the whole screen, then another function to draw.

It will take to long, and it will make my MIDI in signal be handled to late, also the screen updating routine will be delayed.
Ofcourse like you say would be simpler, then i would need other things interrupt based, while MIDI data can not be handles in the interrupt, then it might be to slow to receive the next byte.

It looks like you are trying to incrementally clean the buffer, four words at a time.

Are you sure that your pointer is aligned as you expect at the start?

Otherwise you need to test to see if you are at the end of the buffer more often.

It seems to be doing a very small amount of work to do each time though....

Yes,yes, also yes small ammount to keep the main loop running,
no problems, the screen updates a bit more then 20 frames per second with total redraw,
enough time to clean and draw some lines and circles piece by piece.

The only problem is with these sucky LCDs that the update is to fast for the pixels to show : a moving line is very vague.

Anyways if it should work i will try some more, thanks.
It is not compicated to make it complicated, it is very simple only not so common.

I,m going to add some variables to the union for comparing.
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #22 on: November 19, 2018, 06:13:36 pm »
I've read through this thread twice now and, since no one explicitly told you what your problem was, I will.  Mr. andersm hinted around it, but you are hitting a problem that many novice (no offense) C programmers encounter.  In the code in message 10, in the Clear function, the post-increment instruction in the if statement:

if( lcdptr++ == lcdptrPlus127 )

does not behave as you seem to expect.  The behavior is a bit "fuzzy".  In several of the C language definitions, in the descriptions of post-increment, you will find statements like:

The increment will take place at the end of the execution unit.

That leaves you wondering, "what is an execution unit"?  I won't go any further other than to tell you the the increment takes place after the compare.  You can go read the language definitions yourself if you are having trouble sleeping or enjoy headaches.  I hope you can logically see that, due to this behavior, the if condition will never be true.
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: Why dont my pointer works ?
« Reply #23 on: November 19, 2018, 10:00:47 pm »
...In the code in message 10, in the Clear function, the post-increment instruction in the if statement:

if( lcdptr++ == lcdptrPlus127 )

does not behave as you seem to expect.  The behavior is a bit "fuzzy". ...

Not sure exactly what the OP's problem is, but this statement is "misleading"  ;) The C language is quite clear on what this statement means:

The initial (pre-incremented) value of lcdptr is compared to lcdptrPlus127 and the result of the comparison is the (boolean) value of the test expression. lcdptr is incremented.

The only thing "fuzzy" is when does the increment happens, which has no bearing whatsoever.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #24 on: November 19, 2018, 10:07:53 pm »
...In the code in message 10, in the Clear function, the post-increment instruction in the if statement:

if( lcdptr++ == lcdptrPlus127 )

does not behave as you seem to expect.  The behavior is a bit "fuzzy". ...

Not sure exactly what the OP's problem is, but this statement is "misleading"  ;) The C language is quite clear on what this statement means:

The initial (pre-incremented) value of lcdptr is compared to lcdptrPlus127 and the result of the comparison is the (boolean) value of the test expression. lcdptr is incremented.

The only thing "fuzzy" is when does the increment happens, which has no bearing whatsoever.

What about this:

if ((lcdptr++) == lcdptrPlus127)

???
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11882
  • Country: us
Re: Why dont my pointer works ?
« Reply #25 on: November 19, 2018, 10:23:50 pm »
What about this:

if ((lcdptr++) == lcdptrPlus127)

???

Why would the parentheses make a difference?
 
The following users thanked this post: newbrain

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Why dont my pointer works ?
« Reply #26 on: November 19, 2018, 10:30:32 pm »
What about this:

if ((lcdptr++) == lcdptrPlus127)

???

Why would the parentheses make a difference?
Probably increment before comparing. However I'd strongly advice to split operations in single lines because code like this is wildly obfustigated and impossible to maintain long term. Screens are big nowadays so there is no need to cram as much C code as possible in a 80x40 terminal screen.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11882
  • Country: us
Re: Why dont my pointer works ?
« Reply #27 on: November 19, 2018, 10:34:09 pm »
What about this:

if ((lcdptr++) == lcdptrPlus127)

???

Why would the parentheses make a difference?
Probably increment before comparing. However I'd strongly advice to split operations in single lines because code like this is wildly obfustigated and impossible to maintain long term. Screens are big nowadays so there is no need to cram as much C code as possible in a 80x40 terminal screen.

It's still a post-increment operation. The value of (lcdptr++) should be evaluated before the comparison. The value of (lcdptr++) would be the value of lcdptr prior to the increment operation. If instead we wrote (++lcdptr) we would get the value of lcdptr after the increment.
 
The following users thanked this post: newbrain

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: Why dont my pointer works ?
« Reply #28 on: November 19, 2018, 10:34:53 pm »
Its not how I would do it, but the Clear() function in post 10 works fine-

this is simply printing out some info about the pointers, then running Clear() 1024/32 times where the last time shows that the pointers are a match (before the increment, as the 'end' pointer is one 'position' short of the end, which is a little different than most would do)

pScreen: 0x80000058
lcdptr: 0x80000058
lcdptrPlus127: 0x80000450

[Clear start][lcdptr: 0x80000058]
    lcdptr: 0x80000060
    lcdptr: 0x80000068
    lcdptr: 0x80000070
    lcdptr: 0x80000070
[Clear end][lcdptr: 0x80000078]

[Clear start][lcdptr: 0x80000078]
    lcdptr: 0x80000080
    lcdptr: 0x80000088
    lcdptr: 0x80000090
    lcdptr: 0x80000090
[Clear end][lcdptr: 0x80000098]

...
...

[Clear start][lcdptr: 0x80000438]
    lcdptr: 0x80000440
    lcdptr: 0x80000448
    lcdptr: 0x80000450
    lcdptr: 0x80000450
lcdptr==lcdptrPlus127
[Clear end][lcdptr: 0x80000458]

FYI, this Clear() function run 32 times takes 340 cp0 cycles (680 cpu cycles), the cls function I showed earlier takes 308 cpu cycles and memset takes 424 cpu cycles. So by calling the Clear() function multiple times, it takes an extra 372 cycles.

I don't know all the details of the C rules and which compiler follows them or not, but these 2 produce the same result in xc32-
if ((lcdptr++) == lcdptrPlus127)
if (lcdptr++ == lcdptrPlus127)
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #29 on: November 19, 2018, 10:39:33 pm »
To make it really nasty (not that I would advocate using code like this in any serious fashion) how about:

/* using simple variable names for clarity */

if ((z == (y = x++)) && (x == 5))
{
   printf ("%d\n", x);
}

Assuming that execution reaches the printf, what does it print?
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #30 on: November 19, 2018, 10:44:00 pm »
What about this:

if ((lcdptr++) == lcdptrPlus127)

???

Why would the parentheses make a difference?

Exactly.  Maybe I'm not remembering the correct terms any more, (I sure thought the concept was called an "execution unit") but that is the concept.  Ponder my other example.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11882
  • Country: us
Re: Why dont my pointer works ?
« Reply #31 on: November 19, 2018, 10:44:25 pm »
To make it really nasty (not that I would advocate using code like this in any serious fashion) how about:

/* using simple variable names for clarity */

if ((z == (y = x++)) && (x == 5))
{
   printf ("%d\n", x);
}

Assuming that execution reaches the printf, what does it print?

Don't we need to know the initial value of x before entering the if statement?
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #32 on: November 19, 2018, 10:54:42 pm »
Don't we need to know the initial value of x before entering the if statement?

Just think about what it takes to make it to the printf.  x must be 5, right?  But when is the increment?

Anyway, I can tell you that back in the late 1980s, this was fuzzy.  I had a coworker code what was essentially this example "by accident".  Depending on whether you used Lattice or Borland, you got 5 or 6 as the output.

 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11882
  • Country: us
Re: Why dont my pointer works ?
« Reply #33 on: November 19, 2018, 11:02:53 pm »
Don't we need to know the initial value of x before entering the if statement?

Just think about what it takes to make it to the printf.  x must be 5, right?  But when is the increment?

Anyway, I can tell you that back in the late 1980s, this was fuzzy.  I had a coworker code what was essentially this example "by accident".  Depending on whether you used Lattice or Borland, you got 5 or 6 as the output.

OK, I see.

It seems that in modern C++ the logical && operator introduces a sequence point, so the results of x++ should be complete before doing the (x == 5) comparison. Therefore modern C++ should print 5 and not 6.

(This is logical because && short circuits. It is required that everything before the && is evaluated before looking at anything after the &&.)
 

Offline bsudbrink

  • Frequent Contributor
  • **
  • Posts: 406
  • Country: us
Re: Why dont my pointer works ?
« Reply #34 on: November 19, 2018, 11:36:29 pm »
(This is logical because && short circuits. It is required that everything before the && is evaluated before looking at anything after the &&.)

Hmmm... I'm not sure I follow the logic here.  Shouldn't the various sub-clauses, connected with &&, be evaluatable in any order without changing the outcome?  That would argue for carrying out the increment after the entire expression was evaluated.  Of course, those kind of side effects are exactly why all of this should be avoided like the plague.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Why dont my pointer works ?
« Reply #35 on: November 19, 2018, 11:58:39 pm »
(This is logical because && short circuits. It is required that everything before the && is evaluated before looking at anything after the &&.)

Hmmm... I'm not sure I follow the logic here.  Shouldn't the various sub-clauses, connected with &&, be evaluatable in any order without changing the outcome?  That would argue for carrying out the increment after the entire expression was evaluated.  Of course, those kind of side effects are exactly why all of this should be avoided like the plague.
They are logically, but the language specifies that && short-circuits. As soon as a false is encountered as the rvalue of the first operand, the language spec guarantees that the second operand is not evaluated.

This permits you to do things like without a segfault if the pointer is 0:

if (pointer && pointer->value > 0) ...

If pointer is 0, pointer is never dereferenced.
 
The following users thanked this post: newbrain

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: Why dont my pointer works ?
« Reply #36 on: November 20, 2018, 02:45:44 am »
People need to read a C book (or two  ;D) - yes, I wrote one.

Anyway, || and && have ALWAYS been sequence points and shortcircuited, since K&R. Heck, since Ritchie's original compiler.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #37 on: November 20, 2018, 01:33:36 pm »
Are you sure that your pointer is aligned as you expect at the start?

It was my own stupid fault, you are right, the pointer was not init, only when redraw not on start, how stupid.
Thanks for your mental support all.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #38 on: November 20, 2018, 01:41:44 pm »
it's be really difficult to out-perform memset,

I like to have my code the fastest i can get and am willing to test the timing for various methods.
Only i still have this problem : i can not set my PIC32MX in fast performance mode yet, take a look at this topic :
https://www.microchip.com/forums/m404723.aspx

The codes they suggest are not working, seems to be outdated info.
So i read :
NO Caching turned on
NO Prefetch buffer enabled
7 FLASH wait states
1 SRAM wait states.

I only find one thing in the datasheet : BMXWSDRM: CPU Instruction or Data Access from Data RAM Wait State bit
nothing about caching and other wait states.

I will look a bit into more and maybe make another topic about this.
Then i can proof if maybe my code is faster then memset.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #39 on: November 20, 2018, 01:59:45 pm »
I read i make more problems then i asked for.
Dont worry its all good, thanks.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: Why dont my pointer works ?
« Reply #40 on: November 20, 2018, 06:59:52 pm »
But yes, memcpy/memset lead to very efficient *inline* code (no call to a library's function) when using optimizations, at least with GCC, so doing the same "by hand" is rarely a good idea. GCC knows how to schedule the instructions in the most efficient way and will do so much more easily if you use memset() than if you devise your own assignments which may be harder for GCC to optimize. Hardly worth it.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: Why dont my pointer works ?
« Reply #41 on: November 20, 2018, 07:13:07 pm »
NB: you can still memset a portion (4, 8, 16, 32 bytes) at a time if you don't want to pause the program for the whole time.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #42 on: November 21, 2018, 02:04:44 pm »
Indeed like Anders sayd,
only without chip running optimal no point to do testing.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: Why dont my pointer works ?
« Reply #43 on: November 21, 2018, 06:34:15 pm »
Quote
only without chip running optimal no point to do testing
You don't have much to do on that chip except set the freq you want.

You can simulate the various options, and just use cp0 count to time them. It really doesn't matter what the cpu speed is when simulating this, as you are counting cpu cycles not absolute time.
Code: [Select]
#include <xc.h>
#include <stdint.h>
#include <string.h>

uint8_t screen [64][16];

uint32_t cls32(uint32_t addr){
   uint64_t* p = (uint64_t*) addr;
   *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes
   return (uint32_t)p;
}
void cls(){
   uint64_t* p = (uint64_t*) screen;
   uint32_t i = sizeof(screen)/128;
   for(; i; i--){
   *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes
   *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes
   *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes
   *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes
   }
}

//volatile so not optimized away and can see in simulator
volatile uint32_t t_mem, t_mem32, t_cls32, t_cls, t_dma;
uint32_t zero = 0;

void main(void) {
    uint32_t i = (uint32_t)screen;
    uint32_t j = i + sizeof(screen);

    //memset
    uint32_t t = __builtin_mfc0(9, 0);
    memset(screen, 0, 64*16);
    t_mem = __builtin_mfc0(9, 0) - t;

    //memset - 32bytes at a time
    t = __builtin_mfc0(9, 0);
    for( ; i<j; memset((void*)i, 0, 32), i+=32);
    t_mem32 = __builtin_mfc0(9, 0) - t;

    //cls32 - 32bytes at a time
    t = __builtin_mfc0(9, 0);
    i = (uint32_t)screen;
    j = i + sizeof(screen);
    for(; i<j; i = cls32(i));
    t_cls32 = __builtin_mfc0(9, 0) - t;

    //cls
    t = __builtin_mfc0(9, 0);
    cls();
    t_cls = __builtin_mfc0(9, 0) - t;

    //dma
    DCH0SSA = 0x1FFFFFFF & (uint32_t)&zero;
    DCH0DSA = 0x1FFFFFFF & (uint32_t)screen;
    DCH0SSIZ = 4;
    DCH0DSIZ = sizeof(screen);
    DCH0CSIZ = sizeof(screen);
    DCH0CONbits.CHPRI = 3;
    DCH0CONbits.CHEN = 1;
    DMACONbits.ON = 1;
    DCH0ECONbits.CFORCE = 1;
    t = __builtin_mfc0(9, 0);
    while(DCH0CONbits.CHBUSY);
    t_dma = __builtin_mfc0(9, 0) - t;

    for(;;);
}

//-Os
//          CP0 count
//t_mem   = 0xCF (207)  =  414 cpu cycles
//t_mem32 = 0x2D2 (722) = 1444 cpu cycles
//t_cls32 = 0x122 (290) =  580 cpu cycles
//t_cls   = 0x91 (145)  =  290 cpu cycles
//t_dma   = 0x403 (1027)
The dma code may not be correct, but it simulates ok. The memset is probably a bad thing to use in pieces as it takes a bit of code to get going (check alignment, etc). The all-in-one cls is fastest as you can eliminate much looping where cpu cycles are wasted in branching.

You don't say what the lcd is driven by, so its not clear whether dma could also be used to send data to the lcd.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #44 on: November 22, 2018, 03:55:03 pm »
Thank you CV.

The diplay is driven by 4 bit mode.

I have problems : sometimes i see chinese characters.
The whole day its good, then all the sudden it give garbage on screen.
So i think its a timing issue, and made the timing very slow, it wont help.
Then i doubled my breadboard cables, added extra to be sure.

It is so weird if something running all day without problems, then the next day its no good.
Its very weird i have a few days wasted on this 12864B displsy.

So my question now is : does anyone use this 12864B display in 4-bit parallel mode successfully ?
I also readed that that display library, u8g lib also dont support 4 bit mode for this display, it got me thinking, maybe it wont work at all ?
I hope anyone can confirm.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: Why dont my pointer works ?
« Reply #45 on: November 22, 2018, 05:45:14 pm »
Quote
does anyone use this 12864B display
You will have to be more specific, 12864b probably describes every other lcd panel with those pixel dimensions.
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #46 on: November 26, 2018, 03:09:05 pm »
Its with ST7920 chipset display from ebay china, i can make a picture tomorow.
Only i dont know if the real ST7920 is in there, since the times can be set much faster then this manual : http://www.hpinfotech.ro/ST7920.pdf
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: Why dont my pointer works ?
« Reply #47 on: November 27, 2018, 08:09:35 am »
Some of those LCDs are badly implemented. You sneeze a little and they don't work well. Some times you have a add timing delay between commands...
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline Jan AudioTopic starter

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: Why dont my pointer works ?
« Reply #48 on: November 27, 2018, 10:23:31 am »
Did i wreck it ?, i did connected it wrong one time.
The thing is it works for a day, then problems arise, then next day all good, and repeat.
I give up on this display, going for the full color TFT next time.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf