CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

malloc on 16F76

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Roebi



Joined: 12 Jan 2006
Posts: 6

View user's profile Send private message

malloc on 16F76
PostPosted: Thu Jan 19, 2006 11:27 am     Reply with quote

I have a problem with malloc. My program is for the 16F76 and compiled with PCW 3.242 and then downloaded to the target with ICD-U40 (under control of the ICD Control Program V2.48) I also run and stop the program using the ICD-Control Program.

[Note: The debugger of the PCW does not work with the ICD-U40 - although the ICD is connected to my board strictly according to the rules - but this is a different story.]

Back to malloc. My program initializes everthing, calls malloc twice and then enters an eternal loop. Sometimes the program works, but mostly not.

I then added RS232-output to see the pointers I get from malloc and surprise: The pointers are not the same for each run - although the program just comes out of reset. More: In many cases malloc returns zero. That's wrong with malloc?????
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 9:01 pm     Reply with quote

You need to post a sample program that demonstrates the problem.
Small, but complete.
Roebi



Joined: 12 Jan 2006
Posts: 6

View user's profile Send private message

The code to the malloc problem
PostPosted: Fri Jan 20, 2006 8:30 am     Reply with quote

The program T1_Mal.c is as follows:
Code:
/*==============================================================================
System  :       PREMOS S/W                                  Copyright 2006..
================================================================================
Compiler:       PCW V 3.242 by Custom Computer Services Inc.
Target:         PIC16F76 (prototype-HW) PIC16C76 (flightHW)
Abstract:       Testprogram to isolate problem with malloc.
                Printf go to RS232 with 19200,n,8,1 using UART of 16F76.
--------------------------------------------------------------------------------
Edit history:
20-Jan-06 RWB   Created - based on T1_TMTC.c


================================================================================
*/
#include "PREMOS.h"
#include <string.h>
#include <STDLIBM.h>

// types =======================================================================

struct TBufList{          // Struct for linked-list for binary transmission
  struct TBufList *next;  // link to next buffer or null if last
  unsigned char bc;       // byte-count: number of user bytes to follow
  unsigned char pid;      // there will be more, pid is first user byte
                          //....... more user data
  unsigned char checksum; // twos-complement of sum of bc and user bytes
};                        // hence sum(bc..checksum) must be zero


// globals =====================================================================

struct TBufList *first;       // were our linked list starts
int8 cnt;                     // counter - not initialized

// routines ====================================================================

void SendIt( struct TBufList *packet)
// packet points to heap area with a valid packet
{
  struct TBufList *lp;

  printf(" packet:%4x ", (long)packet);
  if (packet != NULL) { // just in case
    disable_interrupts(GLOBAL);
    if (first == NULL) first = packet; // is first
    else { // append at end of list
      lp = first;
      while ( lp->next != NULL) lp = lp->next;
      lp->next = packet;
    } // end else
    // normally we would check if the UART needs a kick to start transmission
    // of this packet, but now we keep it simple - just a linked list
    enable_interrupts(GLOBAL);
  } // if packet
} // SendIt

void SendDBG(char *dbgtext)
// creates a debug packet and sends it.
{
   struct TBufList *lp;
   long lpe;
   int8 sle, sz, *cp, j;

   sle = strlen(dbgtext);
   sz = sle + 8;
   lp = malloc(sz);    // text with null-byte and 7 bytes overhead for packet
   lpe = (long)lp+sz;
   printf("\r\nlp:%4x/%4x sz: %2x sle:%2x", (long)lp, lpe, sz, sle); // show what malloc produced
   if (lp != NULL) { // just in case
     lp->next = NULL;
     lp->bc = strlen(dbgtext) + 5;  // pid, time and terminating zero goes with it
     lp->pid = 0x87;  // debug packet
     cp = (char*)&(lp->checksum);  // not really, but here data start
     cp[0] = 0; cp[1] = 0; cp[2] = 0; // time all zero for now
     for (j = 0; j <= sle; j++) cp[j+3] = dbgtext[j]; // append text
     printf(" last:%4x", (long)&cp[sle+3]);
     SendIt(lp); // and out it goes
   } // if lp not NULL
} // SendDBG


void PowerupInit(void)
{
  output_A(portA_val);          // initial settings for A and C-ports
  set_tris_A(trisa_val);
  output_C(portC_val);
  set_tris_C(trisc_val);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED,0,1);

} // PowerupInit

void main()
{
  char gomsg[] = {"\r\nT1_Mal V5"};
  char msg1[] = {"achwas"};

  first = NULL;       // list of packet is empty
  PowerupInit();

  enable_interrupts(GLOBAL);

  printf("%s cnt:%2u", gomsg, cnt);
  cnt++;
  SendDBG(gomsg);
  SendDBG(msg1);

  while (true) { // eternal loop
    // commented out: ChkTMTC();                    // TMTC.ChkTMTC
  } // end while
  printf("exit-while"); // never
}

The include file PREMOS.H is
Code:
/*==============================================================================
System  :       PREMOS Flight S/W                           Copyright 2005..
================================================================================
Compiler:       PCW V 3.242 by Custom Computer Services Inc.
Target:         PIC16F76 (prototype-HW) PIC16C76 (flightHW)
Abstract:       "system-file 16F76.h with PREMOS application- and board-
                specific extensions.
--------------------------------------------------------------------------------
Edit history:
21-Nov-05 RWB   Created.

================================================================================
*/
//////// Standard Header file for the PIC16F76 device ////////////////
#device PIC16F76 ICD=TRUE
#nolist
//////// Program memory: 8192x14  Data RAM: 367  Stack: 8
//////// I/O: 22   Analog Pins: 5
//////// C Scratch area: 77   ID Location: 2000
//////// Fuses: LP,XT,HS,RC,NOWDT,WDT,NOPUT,PUT,PROTECT,NOPROTECT,BROWNOUT
//////// Fuses: NOBROWNOUT
////////
////////////////////////////////////////////////////////////////// I/O
// Discrete I/O Functions: SET_TRIS_x(), OUTPUT_x(), INPUT_x(),
//                         PORT_B_PULLUPS(), INPUT(),
//                         OUTPUT_LOW(), OUTPUT_HIGH(),
//                         OUTPUT_FLOAT(), OUTPUT_BIT()
// Constants used to identify pins in the above are:

#define PIN_A0  40
#define PIN_A1  41
#define PIN_A2  42
#define PIN_A3  43
#define PIN_A4  44
#define PIN_A5  45

#define PIN_B0  48
#define PIN_B1  49
#define PIN_B2  50
#define PIN_B3  51
#define PIN_B4  52
#define PIN_B5  53
#define PIN_B6  54
#define PIN_B7  55

#define PIN_C0  56
#define PIN_C1  57
#define PIN_C2  58
#define PIN_C3  59
#define PIN_C4  60
#define PIN_C5  61
#define PIN_C6  62
#define PIN_C7  63

////////////////////////////////////////////////////////////////// Useful defines
#define false 0
#define true 1

#define byte int
#define boolean short int

#define getc getch
#define fgetc getch
#define getchar getch
#define putc putchar
#define fputc putchar
#define fgets gets
#define fputs puts

////////////////////////////////////////////////////////////////// Control
// Control Functions:  RESET_CPU(), SLEEP(), RESTART_CAUSE()
// Constants returned from RESTART_CAUSE() are:
#define WDT_FROM_SLEEP  3
#define WDT_TIMEOUT     11
#define MCLR_FROM_SLEEP 19
#define MCLR_FROM_RUN   27
#define NORMAL_POWER_UP 24
#define BROWNOUT_RESTART 26


////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER_0(),
//                              SET_TIMER0() or SET_RTCC(),
//                              GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER_0() are:
#define RTCC_INTERNAL   0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48

#define RTCC_DIV_1      8
#define RTCC_DIV_2      0
#define RTCC_DIV_4      1
#define RTCC_DIV_8      2
#define RTCC_DIV_16     3
#define RTCC_DIV_32     4
#define RTCC_DIV_64     5
#define RTCC_DIV_128    6
#define RTCC_DIV_256    7


#define RTCC_8_BIT      0

// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:

////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
//                            RESTART_WDT()
//
#define WDT_18MS        8
#define WDT_36MS        9
#define WDT_72MS       10
#define WDT_144MS      11
#define WDT_288MS      12
#define WDT_576MS      13
#define WDT_1152MS     14
#define WDT_2304MS     15

////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
//      (or (via |) together constants from each group)
#define T1_DISABLED         0
#define T1_INTERNAL         0x85
#define T1_EXTERNAL         0x87
#define T1_EXTERNAL_SYNC    0x83

#define T1_CLK_OUT          8

#define T1_DIV_BY_1         0
#define T1_DIV_BY_2         0x10
#define T1_DIV_BY_4         0x20
#define T1_DIV_BY_8         0x30

////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED         0
#define T2_DIV_BY_1         4
#define T2_DIV_BY_4         5
#define T2_DIV_BY_16        6

////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF                         0
#define CCP_CAPTURE_FE                  4
#define CCP_CAPTURE_RE                  5
#define CCP_CAPTURE_DIV_4               6
#define CCP_CAPTURE_DIV_16              7
#define CCP_COMPARE_SET_ON_MATCH        8
#define CCP_COMPARE_CLR_ON_MATCH        9
#define CCP_COMPARE_INT                 0xA
#define CCP_COMPARE_RESET_TIMER         0xB
#define CCP_PWM                         0xC
#define CCP_PWM_PLUS_1                  0x1c
#define CCP_PWM_PLUS_2                  0x2c
#define CCP_PWM_PLUS_3                  0x3c
long CCP_1;
#byte   CCP_1    =                      0x15
#byte   CCP_1_LOW=                      0x15
#byte   CCP_1_HIGH=                     0x16
long CCP_2;
#byte   CCP_2    =                      0x1B
#byte   CCP_2_LOW=                      0x1B
#byte   CCP_2_HIGH=                     0x1C
////////////////////////////////////////////////////////////////// SPI
// SPI Functions: SETUP_SPI, SPI_WRITE, SPI_READ, SPI_DATA_IN
// Constants used in SETUP_SSP() are:
#define SPI_MASTER       0x20
#define SPI_SLAVE        0x24
#define SPI_L_TO_H       0
#define SPI_H_TO_L       0x10
#define SPI_CLK_DIV_4    0
#define SPI_CLK_DIV_16   1
#define SPI_CLK_DIV_64   2
#define SPI_CLK_T2       3
#define SPI_SS_DISABLED  1

#define SPI_SAMPLE_AT_END 0x8000
#define SPI_XMIT_L_TO_H  0x4000

////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE  - Turn UART on
#define UART_ADDRESS           2
#define UART_DATA              4


////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
//                SET_ADC_CHANNEL(), READ_ADC()
// Constants used for SETUP_ADC() are:
#define ADC_OFF                0          // ADC Off
#define ADC_CLOCK_DIV_2    0x100
#define ADC_CLOCK_DIV_8     0x40
#define ADC_CLOCK_DIV_32    0x80
#define ADC_CLOCK_INTERNAL  0xc0          // Internal 2-6us


// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS                            7   // None
#define ALL_ANALOG                            0   // A0 A1 A2 A3 A5
#define AN0_AN1_AN2_AN4_VSS_VREF              1   // A0 A1 A2 A5 VRefh=A3
#define AN0_AN1_AN3                           4   // A0 A1 A3
#define AN0_AN1_VSS_VREF                      5   // A0 A1 VRefh=A3
#define ANALOG_RA3_REF         1         //!old only provided for compatibility
#define RA0_RA1_RA3_ANALOG     4         //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_REF 5         //!old only provided for compatibility


// Constants used in READ_ADC() are:
#define ADC_START_AND_READ     7   // This is the default if nothing is specified
#define ADC_START_ONLY         1
#define ADC_READ_ONLY          6



////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
//                      EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H              0x40
#define H_TO_L                 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL                    0x0BC0
#define INT_RTCC                  0x0B20
#define INT_RB                    0x0B08
#define INT_EXT                   0x0B10
#define INT_AD                    0x8C40
#define INT_TBE                   0x8C10
#define INT_RDA                   0x8C20
#define INT_TIMER1                0x8C01
#define INT_TIMER2                0x8C02
#define INT_CCP1                  0x8C04
#define INT_CCP2                  0x8D01
#define INT_SSP                   0x8C08
#define INT_TIMER0                0x0B20

#list

// application- & board- specific definitions =========================
#device *=16                  // 16-bit pointers
#device adc=8                 // well - not needed, but leave it

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected

#define adc_cs   PIN_A0       // chip select active low for TLS2543
#define adc_eoc   PIN_A1      // end of conversion
#define asic_cs   PIN_A2      // chip select active low for asic
#define asic_reload   PIN_A3  // reload-pulse active low!!
#define min_pulse   PIN_B0    // external interrupt min_pulse
#define int_l   PIN_B4        // portb-change interrupt low gate rdy
#define int_h   PIN_B5        // portb-change interrupt fast gate rdy
#define sec_pulse   PIN_B6    // portb-change interrupt sec-pulse
#define tx_disable   PIN_C2   // high disables tx-driver
#define sck   PIN_C3          // C3..5 are SPI-pins
#define sdi   PIN_C4
#define sdo   PIN_C5
#define tx   PIN_C6           //
#define trisA_val 0b11110010
#define portA_val 0b00001001  // no reload and asic_cs low, adc_cs high
#define trisC_val 0b10010011
#define portC_val 0b01000000  // tx high, tx_disable low

#use delay(clock=9830400)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use fast_io(A)
#use fast_io(C)

// end of a&b-specific definitions =====================================

typedef int8 *byteptr;


The program produces (or better should produce) a 3-line output for each run. The listing below shows the output (with comments) captured from the program.

Code:
Captured output from T1_Mal.c                    Comment
================================================ +++++++++++++++++++++++++++++++++++++++++++++++++++
T1_Mal V5 cnt:13                                 + downloaded, then run
lp:005e/0071 sz: 13 sle:0b last:0070 packet:005e +
lp:0063/0071 sz: 0e sle:06 last:0070 packet:0063 + lp=63, but 5e..70 is booked already!!
T1_Mal V5 cnt:14                                 + 2nd run
lp:005e/0071 sz: 13 sle:0b last:0070 packet:005e + lp=5e reproduces as expected
lp:0000/000e sz: 0e sle:06                       +  lp of zero is clearly nonsense
T1_Mal V5 cnt:15                                 + 3rd run
lp:005e/0071 sz: 13 sle:0b last:0070 packet:005e + lp=5e ok
lp:00fe/000c sz: 0e sle:06                       + why fe and not 63 as during 1st run?
T1_Mal V5 cnt:16                                 + 4th run
lp:005e/0071 sz: 13 sle:0b last:0070 packet:005ý + program looses track
T1_Mal V5 cnt:17                                 + 5th run
lp:005e/0071 sz: 13 sle:0b last:0070 packet:005e + 5e ok
lp:0064/0072 sz: 0e sle:06 last:0071 packet:0064 + 64 is in [5e..71) and hence wrong_

Strange behaviour - isn't it Question
Morcilla



Joined: 08 Apr 2008
Posts: 2

View user's profile Send private message

Re: malloc on 16F76
PostPosted: Tue Apr 08, 2008 9:57 am     Reply with quote

Roebi wrote:
I have a problem with malloc. My program is for the 16F76 and compiled with PCW 3.242 and then downloaded to the target with ICD-U40 (under control of the ICD Control Program V2.48) I also run and stop the program using the ICD-Control Program.

[Note: The debugger of the PCW does not work with the ICD-U40 - although the ICD is connected to my board strictly according to the rules - but this is a different story.]

Back to malloc. My program initializes everthing, calls malloc twice and then enters an eternal loop. Sometimes the program works, but mostly not.

I then added RS232-output to see the pointers I get from malloc and surprise: The pointers are not the same for each run - although the program just comes out of reset. More: In many cases malloc returns zero. That's wrong with malloc?????



Remember: Malloc function is for request memory, but if you have it.
Malloc return 0 if you don't have enough memory.

Try to delete some variables or if you have previously used malloc and don't need any more this memory, use free() function to free it.


Good luck
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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